Re: friends of mod_proxy

2022-10-10 Thread Ruediger Pluem



On 10/10/22 6:35 PM, Eric Covener wrote:
> On Mon, Oct 10, 2022 at 11:55 AM Yann Ylavic  wrote:
>>
>> On Fri, Oct 7, 2022 at 9:14 PM Ruediger Pluem  wrote:
>>>
>>> On 10/7/22 7:11 PM, Stefan Eissing via dev wrote:


> Am 07.10.2022 um 18:45 schrieb Yann Ylavic :
>

 Thanks, Yann, for the detailed explanation on how this works and that the 
 default does the right thing.
>>>
>>> +1. I missed the default of not reusing the connection in these cases but 
>>> having the possibility to override it like the user did.
>>> But shouldn't we default to not reusing the connection in case of a $ 
>>> inside the port as well?
>>
>> We default to disabling connection reuse for any $ substitution
>> already, the compat issue is for an explicit enablereuse=on which used
>> to "work" because it was ignored..
>>
>> How about a patch like the attached one now, which disables connection
>> reuse definitively (regardless of enablereuse) if there is a $
>> substitution in the hostname or port part of the URL?
>> The patch uses the existing "is_address_reusable" flag (set to false
>> initially in this case), and since it's not configurable by the user
>> we are safe from a connection reuse point of vue in any case.
> 
> +1 in concept
> 

Looks sensible. +1.

Regards

RĂ¼diger


Re: friends of mod_proxy

2022-10-10 Thread Eric Covener
On Mon, Oct 10, 2022 at 11:55 AM Yann Ylavic  wrote:
>
> On Fri, Oct 7, 2022 at 9:14 PM Ruediger Pluem  wrote:
> >
> > On 10/7/22 7:11 PM, Stefan Eissing via dev wrote:
> > >
> > >
> > >> Am 07.10.2022 um 18:45 schrieb Yann Ylavic :
> > >>
> > >
> > > Thanks, Yann, for the detailed explanation on how this works and that the 
> > > default does the right thing.
> >
> > +1. I missed the default of not reusing the connection in these cases but 
> > having the possibility to override it like the user did.
> > But shouldn't we default to not reusing the connection in case of a $ 
> > inside the port as well?
>
> We default to disabling connection reuse for any $ substitution
> already, the compat issue is for an explicit enablereuse=on which used
> to "work" because it was ignored..
>
> How about a patch like the attached one now, which disables connection
> reuse definitively (regardless of enablereuse) if there is a $
> substitution in the hostname or port part of the URL?
> The patch uses the existing "is_address_reusable" flag (set to false
> initially in this case), and since it's not configurable by the user
> we are safe from a connection reuse point of vue in any case.

+1 in concept


Re: friends of mod_proxy

2022-10-10 Thread Yann Ylavic
On Fri, Oct 7, 2022 at 9:14 PM Ruediger Pluem  wrote:
>
> On 10/7/22 7:11 PM, Stefan Eissing via dev wrote:
> >
> >
> >> Am 07.10.2022 um 18:45 schrieb Yann Ylavic :
> >>
> >
> > Thanks, Yann, for the detailed explanation on how this works and that the 
> > default does the right thing.
>
> +1. I missed the default of not reusing the connection in these cases but 
> having the possibility to override it like the user did.
> But shouldn't we default to not reusing the connection in case of a $ inside 
> the port as well?

We default to disabling connection reuse for any $ substitution
already, the compat issue is for an explicit enablereuse=on which used
to "work" because it was ignored..

How about a patch like the attached one now, which disables connection
reuse definitively (regardless of enablereuse) if there is a $
substitution in the hostname or port part of the URL?
The patch uses the existing "is_address_reusable" flag (set to false
initially in this case), and since it's not configurable by the user
we are safe from a connection reuse point of vue in any case.

>
> >
> > My guess is that such configurations are pretty rare, as their security is 
> > not good in general. The only thing that comes to mind is logging a warning 
> > for such cases.
>
> +1

Done in the patch too, along with some docs update regarding this use case.


Regards;
Yann.
Index: modules/proxy/proxy_util.c
===
--- modules/proxy/proxy_util.c	(revision 1903576)
+++ modules/proxy/proxy_util.c	(working copy)
@@ -1851,6 +1851,7 @@ PROXY_DECLARE(char *) ap_proxy_define_worker_ex(ap
 proxy_worker_shared *wshared;
 const char *ptr = NULL, *sockpath = NULL, *pdollars = NULL;
 apr_port_t port_of_scheme;
+int disable_reuse = 0;
 apr_uri_t uri;
 
 /*
@@ -1879,6 +1880,12 @@ PROXY_DECLARE(char *) ap_proxy_define_worker_ex(ap
  * to fail (e.g. "ProxyPassMatch ^/(a|b)(/.*)? http://host:port$2;).
  * So we trim all the $n from the :port and prepend them in uri.path
  * afterward for apr_uri_unparse() to restore the original URL below.
+ * If a dollar substitution is found in the hostname[:port] part of
+ * the URL, reusing address and connections in the same worker is not
+ * possible (the current implementation of active connections cache
+ * handles/assumes a single origin server:port per worker only), so
+ * we set disable_reuse here during parsing to take that into account
+ * in the worker settings below.
  */
 #define IS_REF(x) (x[0] == '$' && apr_isdigit(x[1]))
 const char *pos = ap_strstr_c(ptr, "://");
@@ -1885,6 +1892,9 @@ PROXY_DECLARE(char *) ap_proxy_define_worker_ex(ap
 if (pos) {
 pos += 3;
 while (*pos && *pos != ':' && *pos != '/') {
+if (*pos == '$') {
+disable_reuse = 1;
+}
 pos++;
 }
 if (*pos == ':') {
@@ -1904,6 +1914,7 @@ PROXY_DECLARE(char *) ap_proxy_define_worker_ex(ap
 vec[1].iov_base = (void *)path;
 vec[1].iov_len = strlen(path);
 ptr = apr_pstrcatv(p, vec, 2, NULL);
+disable_reuse = 1;
 }
 }
 }
@@ -1999,7 +2010,7 @@ PROXY_DECLARE(char *) ap_proxy_define_worker_ex(ap
 wshared->port = (uri.port) ? uri.port : port_of_scheme;
 wshared->flush_packets = flush_off;
 wshared->flush_wait = PROXY_FLUSH_WAIT;
-wshared->is_address_reusable = 1;
+wshared->is_address_reusable = !disable_reuse;
 wshared->lbfactor = 100;
 wshared->passes = 1;
 wshared->fails = 1;
@@ -2008,7 +2019,31 @@ PROXY_DECLARE(char *) ap_proxy_define_worker_ex(ap
 wshared->hash.def = ap_proxy_hashfunc(wshared->name_ex, PROXY_HASHFUNC_DEFAULT);
 wshared->hash.fnv = ap_proxy_hashfunc(wshared->name_ex, PROXY_HASHFUNC_FNV);
 wshared->was_malloced = (mask & AP_PROXY_WORKER_IS_MALLOCED) != 0;
-wshared->is_name_matchable = 0;
+if (mask & AP_PROXY_WORKER_IS_MATCH) {
+wshared->is_name_matchable = 1;
+
+/* Before AP_PROXY_WORKER_IS_MATCH (< 2.4.47), a regex worker with
+ * dollar substitution was never matched against any actual URL, thus
+ * the requests fell through the generic worker. Now if a ProyPassMatch
+ * matches, a worker (and its parameters) is always used to determine
+ * the properties of the connection with the origin server. So for
+ * instance the same "timeout=" will be enforced for all the requests
+ * matched by the same ProyPassMatch worker, which is an improvement
+ * compared to the global/vhost [Proxy]Timeout applied by the generic
+ * worker. Likewise, address and connection reuse is the default for
+ * a ProyPassMatch worker with no dollar substitution, just like a
+ * "normal" worker.