You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Rainer Jung <ra...@kippdata.de> on 2016/04/13 12:40:12 UTC

Allow SSLProxy* config in context?

I stumbled into a situation where a reverse proxy had two different 
backends behind the same VHost of the proxy. Both backends demand client 
certs as becomes more and more common for services today. Unfortunately 
the CA which issues the client certs in both cases is the same CA, but 
the demanded client cert is individual to the backend services.

As far as I can see, this is currently not configurable. The 
SSLProxyMachineCertificateFile and SSLProxyMachineCertificatePath only 
work on the VHost level and the client cert detection algo in 
ssl_callback_proxy_cert() chooses the first client cert it can find 
which was issued b the right CA. No way to distinguish further.

To me it looks like the "right" way of handling SSLProxy* config would 
be per <Proxy>. Did anyone else already encounter a similar problem? Any 
thoughts or experiments on how to solve this for the future?

Regards,

Rainer

Re: Allow SSLProxy* config in context?

Posted by Stefan Eissing <st...@greenbytes.de>.
> Am 13.04.2016 um 12:55 schrieb Yann Ylavic <yl...@gmail.com>:
> 
> On Wed, Apr 13, 2016 at 12:40 PM, Rainer Jung <ra...@kippdata.de> wrote:
>> 
>> To me it looks like the "right" way of handling SSLProxy* config would be
>> per <Proxy>.
> 
> ++1

+1

> 
>> Did anyone else already encounter a similar problem? Any
>> thoughts or experiments on how to solve this for the future?
> 
> Not sure how to handle this since <Proxy> is in mod_proxy whereas
> SSLProxy* are in mod_ssl.
> <Proxy> is a dir_config still, not sure how we could make it
> available/shared in/with mod_ssl...

For the user it makes more sense to have Proxy settings inside <Proxy>. I always found the SSLProxy* confusing, although I can of course understand how implementation drove this...

-Stefan

Re: Allow SSLProxy* config in context?

Posted by Yann Ylavic <yl...@gmail.com>.
On Wed, Apr 13, 2016 at 12:40 PM, Rainer Jung <ra...@kippdata.de> wrote:
>
> To me it looks like the "right" way of handling SSLProxy* config would be
> per <Proxy>.

++1

> Did anyone else already encounter a similar problem? Any
> thoughts or experiments on how to solve this for the future?

Not sure how to handle this since <Proxy> is in mod_proxy whereas
SSLProxy* are in mod_ssl.
<Proxy> is a dir_config still, not sure how we could make it
available/shared in/with mod_ssl...

Regards,
Yann.

Re: Allow SSLProxy* config in context?

Posted by Rainer Jung <ra...@kippdata.de>.
Am 15.04.2016 um 13:30 schrieb Yann Ylavic:
> On Thu, Apr 14, 2016 at 9:57 AM, Yann Ylavic <yl...@gmail.com> wrote:
>>
>> IIUC, the <Proxy> block is a per_dir context already, which can/could
>> accept any directive provided their ap_check_cmd_context() allows it
>> (we may need to declare a new PROXY_CONF).
>>
>> So how about making per_dir SSLProxy* directives, restricted to server
>> and <proxy> context?
>> This would let the loading (and validation) work like currently,
>> mod_ssl could still do its standalone post_config stuff (server AND
>> per_dir wise).
>>
>> At runtime, proxy_walk() would still do the merging (there may be same
>> SSLProxy* in both <VirtualHost> and <Proxy> which need merging, but
>> that would be a single one since we restrict those directives to
>> server and <proxy> context).
>>
>> Finally, if ssl_proxy_enable[_ex]() is given r->per_dir_config, it
>> could initialize the backend connection with the right context.
>
> I think I'm closed to implement this fully, not finished yet, but
> mostly not tested at all...
>
> This would have the advantage to avoid any naming convention between
> mod_ssl and mod_proxy (DN or proxy name, ...) for the admin.
> Simply put the SSLProxy* directives in <Proxy> and it works (the httpd
> way), merging parent directives when current value is uninitialized,
> creating an SSL_CTX per dir (server, vhost and/or <proxy>) for proxy
> connections to use the appropriate one.
>
> Of course all this can vanish at (self) testing time, I may have
> missed/misunderstood something which makes the whole nonsense...
> In the meantime, maybe it can avoid someone starts working on "the
> other way", unless obviously it is a better way than this one to start
> with (in which case let me know too ;).
> BTW, if I can't finish this afternoon (UTC+2), it won't be before the
> end of the week-end or next week, so any implementation is very
> welcome anyway, the more proposals, the better :)

Very cool Yann!

Rainer

Re: Allow SSLProxy* config in context?

Posted by Rainer Jung <ra...@kippdata.de>.
Am 21.04.2016 um 00:35 schrieb Yann Ylavic:
> On Tue, Apr 19, 2016 at 9:36 PM, Yann Ylavic <yl...@gmail.com> wrote:
>>
>> What changed is:
>> 1. SSLProxy* directives are now per directory (restricted to
>> Server/VirtualHost and <Proxy>), so all the internal struct members
>> have been move from SSLSrvConfigRec to SSLDirConfigRec;
>> 2. The merge happens from main server to VirtualHosts (if any) to
>> <Proxy> sections (if any), as usual;
>> 3. The proxies SSL_CTX are still created once at startup, in the
>> post_config hook, by retrieving all the dc->proxy and initializing
>> them (the one associated with the server_rec and the ones of the
>> <Proxy> sections, with the help of a new mod_proxy optional function:
>> ap_proxy_get_sections_configs());
>> 4. At runtime, the new ssl_proxy_{enable,disable}_ex() optional
>> functions are used by mod_proxy to indicate the per dir (proxy
>> worker's) configuration to mod_ssl.
>
> I did even more testing with this new (attached) patch and it works for me.
>
>>
>> Feedbacks and more testing welcome :)
>
> Let me known if it's suitable for trunk...

It'll take me a few days, likely over the weekend. Thanks a bunch already.

Rainer

Re: Allow SSLProxy* config in context?

Posted by Stefan Eissing <st...@greenbytes.de>.
Woah, quite a patch! Tested on OS X 15.4 and all framework/trunk
and mod_h2/trunk tests pass.

Tried to move SSLProxyEngine into the <Proxy> configs. Worked like
a charm, both when needed and when not. When it was missing I
properly got an internal server error and log:

AH01961: SSL Proxy requested for test.example.org:443 but not enabled [Hint: SSLProxyEngine]

So, a go ahead from me. Nice work.

-Stefan

PS. IANAMSE (I am not a mod_ssl expert), but I get the feeling that 
the addition of a mod_ssl_proxy which can keep its own config record
*might* be worth considering at some point in time. 

> Am 21.04.2016 um 20:51 schrieb Yann Ylavic <yl...@gmail.com>:
> 
> On Thu, Apr 21, 2016 at 9:31 AM, Stefan Eissing
> <st...@greenbytes.de> wrote:
>> Not in today, but will have a look tomorrow.
> 
> On Thu, Apr 21, 2016 at 10:53 AM, Rainer Jung <ra...@kippdata.de> wrote:
>> It'll take me a few days, likely over the weekend. Thanks a bunch already.
> 
> Thanks Stefan and Rainer.
> 
> Here is a v3 which passes the tests framework, the previous ones
> didn't because of issues in "ssl_proxy_{enable,disable}_ex()", now
> fixed and also renamed/unified into a single "ssl_engine_set(c,
> per_dir_config, server/proxy, on/off)" function.
> 
> I'll add more framework tests (per <Proxy>) once/if committed.
> 
> Regards,
> Yann.
> <SSLProxy-v3.patch>


Re: Allow SSLProxy* config in context?

Posted by Yann Ylavic <yl...@gmail.com>.
On Thu, Apr 21, 2016 at 9:31 AM, Stefan Eissing
<st...@greenbytes.de> wrote:
> Not in today, but will have a look tomorrow.

On Thu, Apr 21, 2016 at 10:53 AM, Rainer Jung <ra...@kippdata.de> wrote:
> It'll take me a few days, likely over the weekend. Thanks a bunch already.

Thanks Stefan and Rainer.

Here is a v3 which passes the tests framework, the previous ones
didn't because of issues in "ssl_proxy_{enable,disable}_ex()", now
fixed and also renamed/unified into a single "ssl_engine_set(c,
per_dir_config, server/proxy, on/off)" function.

I'll add more framework tests (per <Proxy>) once/if committed.

Regards,
Yann.

Re: Allow SSLProxy* config in context?

Posted by Stefan Eissing <st...@greenbytes.de>.
Not in today, but will have a look tomorrow. 

> Am 21.04.2016 um 00:35 schrieb Yann Ylavic <yl...@gmail.com>:
> 
>> On Tue, Apr 19, 2016 at 9:36 PM, Yann Ylavic <yl...@gmail.com> wrote:
>> 
>> What changed is:
>> 1. SSLProxy* directives are now per directory (restricted to
>> Server/VirtualHost and <Proxy>), so all the internal struct members
>> have been move from SSLSrvConfigRec to SSLDirConfigRec;
>> 2. The merge happens from main server to VirtualHosts (if any) to
>> <Proxy> sections (if any), as usual;
>> 3. The proxies SSL_CTX are still created once at startup, in the
>> post_config hook, by retrieving all the dc->proxy and initializing
>> them (the one associated with the server_rec and the ones of the
>> <Proxy> sections, with the help of a new mod_proxy optional function:
>> ap_proxy_get_sections_configs());
>> 4. At runtime, the new ssl_proxy_{enable,disable}_ex() optional
>> functions are used by mod_proxy to indicate the per dir (proxy
>> worker's) configuration to mod_ssl.
> 
> I did even more testing with this new (attached) patch and it works for me.
> 
>> 
>> Feedbacks and more testing welcome :)
> 
> Let me known if it's suitable for trunk...
> <SSLProxy-v2.patch>

Re: Allow SSLProxy* config in context?

Posted by Yann Ylavic <yl...@gmail.com>.
On Tue, Apr 19, 2016 at 9:36 PM, Yann Ylavic <yl...@gmail.com> wrote:
>
> What changed is:
> 1. SSLProxy* directives are now per directory (restricted to
> Server/VirtualHost and <Proxy>), so all the internal struct members
> have been move from SSLSrvConfigRec to SSLDirConfigRec;
> 2. The merge happens from main server to VirtualHosts (if any) to
> <Proxy> sections (if any), as usual;
> 3. The proxies SSL_CTX are still created once at startup, in the
> post_config hook, by retrieving all the dc->proxy and initializing
> them (the one associated with the server_rec and the ones of the
> <Proxy> sections, with the help of a new mod_proxy optional function:
> ap_proxy_get_sections_configs());
> 4. At runtime, the new ssl_proxy_{enable,disable}_ex() optional
> functions are used by mod_proxy to indicate the per dir (proxy
> worker's) configuration to mod_ssl.

I did even more testing with this new (attached) patch and it works for me.

>
> Feedbacks and more testing welcome :)

Let me known if it's suitable for trunk...

Re: Allow SSLProxy* config in context?

Posted by Yann Ylavic <yl...@gmail.com>.
On Fri, Apr 15, 2016 at 1:30 PM, Yann Ylavic <yl...@gmail.com> wrote:
> On Thu, Apr 14, 2016 at 9:57 AM, Yann Ylavic <yl...@gmail.com> wrote:
>>
>> IIUC, the <Proxy> block is a per_dir context already, which can/could
>> accept any directive provided their ap_check_cmd_context() allows it
>> (we may need to declare a new PROXY_CONF).
>>
>> So how about making per_dir SSLProxy* directives, restricted to server
>> and <proxy> context?
>> This would let the loading (and validation) work like currently,
>> mod_ssl could still do its standalone post_config stuff (server AND
>> per_dir wise).
>>
>> At runtime, proxy_walk() would still do the merging (there may be same
>> SSLProxy* in both <VirtualHost> and <Proxy> which need merging, but
>> that would be a single one since we restrict those directives to
>> server and <proxy> context).
>>
>> Finally, if ssl_proxy_enable[_ex]() is given r->per_dir_config, it
>> could initialize the backend connection with the right context.
>
> I think I'm closed to implement this fully, not finished yet, but
> mostly not tested at all...

The attached patch seems to work correctly with my tests, not very
commented (still).

What changed is:
1. SSLProxy* directives are now per directory (restricted to
Server/VirtualHost and <Proxy>), so all the internal struct members
have been move from SSLSrvConfigRec to SSLDirConfigRec;
2. The merge happens from main server to VirtualHosts (if any) to
<Proxy> sections (if any), as usual;
3. The proxies SSL_CTX are still created once at startup, in the
post_config hook, by retrieving all the dc->proxy and initializing
them (the one associated with the server_rec and the ones of the
<Proxy> sections, with the help of a new mod_proxy optional function:
ap_proxy_get_sections_configs());
4. At runtime, the new ssl_proxy_{enable,disable}_ex() optional
functions are used by mod_proxy to indicate the per dir (proxy
worker's) configuration to mod_ssl.

Feedbacks and more testing welcome :)

Re: Allow SSLProxy* config in context?

Posted by Yann Ylavic <yl...@gmail.com>.
On Thu, Apr 14, 2016 at 9:57 AM, Yann Ylavic <yl...@gmail.com> wrote:
>
> IIUC, the <Proxy> block is a per_dir context already, which can/could
> accept any directive provided their ap_check_cmd_context() allows it
> (we may need to declare a new PROXY_CONF).
>
> So how about making per_dir SSLProxy* directives, restricted to server
> and <proxy> context?
> This would let the loading (and validation) work like currently,
> mod_ssl could still do its standalone post_config stuff (server AND
> per_dir wise).
>
> At runtime, proxy_walk() would still do the merging (there may be same
> SSLProxy* in both <VirtualHost> and <Proxy> which need merging, but
> that would be a single one since we restrict those directives to
> server and <proxy> context).
>
> Finally, if ssl_proxy_enable[_ex]() is given r->per_dir_config, it
> could initialize the backend connection with the right context.

I think I'm closed to implement this fully, not finished yet, but
mostly not tested at all...

This would have the advantage to avoid any naming convention between
mod_ssl and mod_proxy (DN or proxy name, ...) for the admin.
Simply put the SSLProxy* directives in <Proxy> and it works (the httpd
way), merging parent directives when current value is uninitialized,
creating an SSL_CTX per dir (server, vhost and/or <proxy>) for proxy
connections to use the appropriate one.

Of course all this can vanish at (self) testing time, I may have
missed/misunderstood something which makes the whole nonsense...
In the meantime, maybe it can avoid someone starts working on "the
other way", unless obviously it is a better way than this one to start
with (in which case let me know too ;).
BTW, if I can't finish this afternoon (UTC+2), it won't be before the
end of the week-end or next week, so any implementation is very
welcome anyway, the more proposals, the better :)

Regards,
Yann.

Re: Allow SSLProxy* config in context?

Posted by Yann Ylavic <yl...@gmail.com>.
On Wed, Apr 13, 2016 at 7:49 PM, Rainer Jung <ra...@kippdata.de> wrote:
> Am 13.04.2016 um 17:04 schrieb Graham Leggett:
>>
>> The catch is that mod_ssl forces us to declare SSL certs and keys server
>> wide, not per directory, loaded and parsed at startup. We however want to
>> specify certs per directory.
>
> Per directory or better in some new way per proxy backend (or proxy worker,
> proxy balancer).

IIUC, the <Proxy> block is a per_dir context already, which can/could
accept any directive provided their ap_check_cmd_context() allows it
(we may need to declare a new PROXY_CONF).

So how about making per_dir SSLProxy* directives, restricted to server
and <proxy> context?
This would let the loading (and validation) work like currently,
mod_ssl could still do its standalone post_config stuff (server AND
per_dir wise).

At runtime, proxy_walk() would still do the merging (there may be same
SSLProxy* in both <VirtualHost> and <Proxy> which need merging, but
that would be a single one since we restrict those directives to
server and <proxy> context).

Finally, if ssl_proxy_enable[_ex]() is given r->per_dir_config, it
could initialize the backend connection with the right context.

Wouldn't that work without so many changes?

Re: Allow SSLProxy* config in context?

Posted by Rainer Jung <ra...@kippdata.de>.
Am 15.04.2016 um 03:20 schrieb Daniel Ruggeri:
>
> On 4/14/2016 3:08 AM, Rainer Jung wrote:
>> Your idea to allow selecting a client cert based on CN or DN sounds
>> attractive to me as well. But since it wouldn't help with other per
>> backend settings (like different Verify settings) we might even think
>> about combining both. As long as your only problem would be client
>> certs, you can select via CN or DN and keep the config vhost global,
>> but once you need more adjustments per backend, you would start to
>> configure SSLProxy* inside <Proxy ...>.
>>
>> WDYT?
>
> Yep! Agreed - I was focusing on the use case presented, but didn't think
> about other cases such as different SSLProxyVerify settings and friends
> such as this. I'd cast a vote for the more comprehensive solution you
> and Graham shared that makes each option available in a directory
> context. Adding yet another directive would satisfy this one use case,
> but the bigger picture would serve users better and be less confusing.
>
> Food for thought - I haven't dug into these...
> * Not sure if it would be a handy target of opportunity or PITA... Since
> ProxyPass is currently server/vhost/dir configurable, should we think to
> include this capability as arguments to ProxyPass/BalancerMember, too?
> * Maybe I missed it, but I don't think the proposed ideas truly provide
> per-backend configuration. Rather, they provide configuration for all
> backends in a dir context if you land on a balancer containing many
> targets. Is that OK, or should we be thinking about ways to make it even
> more granular? (the use cases that come to mind are rather contrived, so
> I may be overthinking it)
> * Would each of these per-dir configs post-merge result in a distinct
> SSL_CTX that needs to be created in mod_ssl? If so, does that require
> significant refactoring in mod_ssl or does the proxy module manage these?

I think there are two notions of dir config versus server config.

First: in which contexts are directives allowed by the general checks 
Apache does. Here <Proxy> is ACCESS_CONF (global server or vhost, but 
not inside Directory, Location, Files), but ProxyPass is RSRC_CONF or 
ACCESS_CONF (everything except htaccess).

Second: how do we handle the values and do we force additional 
structural requirements on the config. Do we add the values to a server 
config structure or to a directory config structure.

In our case I would much prefer to keep the config in a server config 
structure so that it could still be used for init purposes during server 
startup and not only later during request processing. No directory tree 
walking etc., only server config merging during startup and handling in 
the post_config hook, similar to today.

That is one of the reasons, I would prefer to only allow SSLProxy* in 
<Proxy> but not allowing ssl key=value tokens in ProxyPass. The 
implementation would become much harder, but also the semantics very 
unclear. As soon as there is more than one ProxyPass to the same backend 
the question would be, whether the ssl setting is really meant to apply 
only for the specific left hand side of the ProxyPass (incoming URI). I 
find it featurewise sufficient to support setting per backend and not 
support settings per backend and incoming URI.

What we might be able to do, is handling (and documenting) any ssl 
setting in ProxyPass as being used per server per backend, not per 
location. We would not put the setting to a dir config but instead to a 
server config (I think that works but we'd need to test).

I personally don't like very much the long key=value lists behind a 
ProxyPass so I would be already satisfied with a <Proxy> solution.

BalancerMember: if a setting were in a <Proxy> for a balancer we would 
it apply to any member. Do we think we need the possibility to have 
different ssl settings for the members of the same balancer? I'd hope we 
can start without that feature, but I might overlook some use case here.

I'd put the ssl settings in a hash of SSL_CTX structs per server. The 
key to the hash would be the worker URL (name).

Your idea of making the client cert choosable via CN and/or DN is an 
excellent addition, because this is probably the most important use 
case, where an SSL setting could depend on the URI of the target and 
where doing a directory walk is cheap and doesn't mean major 
refactoring, because we don't have to create SSL contexts but instead 
just use a string token to select the correct certficate.

Regards,

Rainer

Re: Allow SSLProxy* config in context?

Posted by Daniel Ruggeri <DR...@primary.net>.
On 4/14/2016 3:08 AM, Rainer Jung wrote:
> Your idea to allow selecting a client cert based on CN or DN sounds
> attractive to me as well. But since it wouldn't help with other per
> backend settings (like different Verify settings) we might even think
> about combining both. As long as your only problem would be client
> certs, you can select via CN or DN and keep the config vhost global,
> but once you need more adjustments per backend, you would start to
> configure SSLProxy* inside <Proxy ...>.
>
> WDYT? 

Yep! Agreed - I was focusing on the use case presented, but didn't think
about other cases such as different SSLProxyVerify settings and friends
such as this. I'd cast a vote for the more comprehensive solution you
and Graham shared that makes each option available in a directory
context. Adding yet another directive would satisfy this one use case,
but the bigger picture would serve users better and be less confusing.

Food for thought - I haven't dug into these...
* Not sure if it would be a handy target of opportunity or PITA... Since
ProxyPass is currently server/vhost/dir configurable, should we think to
include this capability as arguments to ProxyPass/BalancerMember, too?
* Maybe I missed it, but I don't think the proposed ideas truly provide
per-backend configuration. Rather, they provide configuration for all
backends in a dir context if you land on a balancer containing many
targets. Is that OK, or should we be thinking about ways to make it even
more granular? (the use cases that come to mind are rather contrived, so
I may be overthinking it)
* Would each of these per-dir configs post-merge result in a distinct
SSL_CTX that needs to be created in mod_ssl? If so, does that require
significant refactoring in mod_ssl or does the proxy module manage these?

-- 
Daniel Ruggeri


Re: Allow SSLProxy* config in context?

Posted by Rainer Jung <ra...@kippdata.de>.
Am 14.04.2016 um 02:57 schrieb Daniel Ruggeri:
>
> On 4/13/2016 2:22 PM, Rainer Jung wrote:
>>
>> We could pass the worker name from mod_proxy to mod_ssl via a
>> connection note, similar to currently already passing the SNI name via
>> the connection note proxy-request-hostname.
>
> +1 on the connection note idea, but see below about having to inform the
> callback function about too much information
>
> On 4/13/2016 10:04 AM, Graham Leggett wrote:
>> What I had in mind was a syntax where the certs were named, for example:
>>
>> SSLProxyCertificate foo /path/to/foo.cert
>>
>> Followed somewhere else by:
>>
>> <Proxy …>
>>    SSLProxyEnable foo
>> </Proxy>
>
> On one hand, this is an attractive idea because we have already
> conditioned users/administrators to think about naming things via config
> as you can do with authn providers and aliases.
>
> On another hand, there are two gotchas I see. Giving something a name in
> the configuration does not necessarily mean anything to the file or
> certificate store because they aren't married in the same way that authn
> providers and their aliases are. That is, if a different team/individual
> manages the certificate store than the server configuration, the two
> would have to keep in sync with additions or removals. This can be a
> PITA if you have a short certificate lifecycle and have to renew often.
> PLUS, there are cases where there may be many certificates in the file.
> Combine that with the previous point and you could have a nightmare.
>
> Perhaps in addition to or instead of aliases via config, something more
> "dynamic" could be used where a DN, CN or some other attribute about the
> cert that was parsed during startup becomes the representation?
>
> <vhost...>
>     ...
>    #As today
>     SSLProxyMachineCertificateFile /path/to/file
>     <Proxy ...>
>        #Plus new stuff
>        SSLProxyMachineCertificateCN myIdentity
>        #or
>        SSLProxyMachineCertificateDN /C=US/ST=Missouri/L=St.
> Louis/O=BitNebula/CN=DanielRuggeri.bitnebula.com
>     </Proxy>
> </vhost>
>
> This could be a really clean solution because the proxy can just pass
> this name or DN to the ssl module in a note and the ssl module could
> make the selection of certs from that data.
>
> Stashing this (completely untested and thrown together) code around line
> 1778 in modules/ssl/ssl_engine_kernel.c could be all that's needed in
> mod_ssl....
>      char *preferred_name;
> ......
>      if (preferred_name) {
>          for (i = 0; i < sk_X509_INFO_num(certs); i++) {
>              X509_NAME *name;
>              info = sk_X509_INFO_value(certs, i);
>              name = X509_get_subject_name(inf->x509);
>
>              for(j = 0; j < X509_NAME_entry_count(name); j++) {
>                  const char *this_name = //something
>                  if (strcmp(preferred_name, this_name) == 0) {
>                      modssl_proxy_info_log(c, info, APLOGNO(02279)
>                                            "found acceptable cert");
>
>                      modssl_set_cert_info(info, x509, pkey);
>                      return TRUE;
>                  }
>              }
>          }
>          ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(000000)
>              SSLPROXY_CERT_CB_LOG_FMT
>              "server configuration requested certificate name %s"
>              "but it was not found in the certificate store",
> preferred_name);
>      }
>
>
>
> I haven't cracked open the proxy code to see what it would take to
> collapse this down to a per proxy/worker/etc, but it doesn't seem like
> terrible endeavor.

Yeah that's looks very feasible and would allow the actual use case. I 
was wondering whether more SSLProxy* directives would benefit from a per 
backend config possibility. And as a variation of Graham's suggestion, I 
was thinking about (example)

<Proxy http://mycluster>
     SSLProxyMachineCertificateFile /path/to/file
     ... proxy settings ...
</Proxy>

In the vhost config we would not then have an array or hash of ssl proxy 
ocnfig setting. The key to the hash would be "http://mycluster" in the 
example above. And mod_proxy would forward "http://mycluster" to mod_ssl 
via connection notes to allow mod_ssl to select the right proxy ssl config.

So there would be no additional name "foo", instead we would reuse the 
name of the worker from the surrounding proxy block. The selection of 
the certificate would still happen based on the CA, but it would be 
selected from the right store (the one associated with "http://mycluster").

I see your point about having to administer more ssl files outside of 
the config, ie. client cert files or directories per backend. I would 
hope that those would be manageable by choosing some naming convention 
for the file names.

Your idea to allow selecting a client cert based on CN or DN sounds 
attractive to me as well. But since it wouldn't help with other per 
backend settings (like different Verify settings) we might even think 
about combining both. As long as your only problem would be client 
certs, you can select via CN or DN and keep the config vhost global, but 
once you need more adjustments per backend, you would start to configure 
SSLProxy* inside <Proxy ...>.

WDYT?

Regards,

Rainer

Re: Allow SSLProxy* config in context?

Posted by Daniel Ruggeri <DR...@primary.net>.
On 4/13/2016 2:22 PM, Rainer Jung wrote:
>
> We could pass the worker name from mod_proxy to mod_ssl via a
> connection note, similar to currently already passing the SNI name via
> the connection note proxy-request-hostname.

+1 on the connection note idea, but see below about having to inform the
callback function about too much information

On 4/13/2016 10:04 AM, Graham Leggett wrote:
> What I had in mind was a syntax where the certs were named, for example:
>
> SSLProxyCertificate foo /path/to/foo.cert
>
> Followed somewhere else by:
>
> <Proxy …>
>   SSLProxyEnable foo
> </Proxy>

On one hand, this is an attractive idea because we have already
conditioned users/administrators to think about naming things via config
as you can do with authn providers and aliases.

On another hand, there are two gotchas I see. Giving something a name in
the configuration does not necessarily mean anything to the file or
certificate store because they aren't married in the same way that authn
providers and their aliases are. That is, if a different team/individual
manages the certificate store than the server configuration, the two
would have to keep in sync with additions or removals. This can be a
PITA if you have a short certificate lifecycle and have to renew often.
PLUS, there are cases where there may be many certificates in the file.
Combine that with the previous point and you could have a nightmare.

Perhaps in addition to or instead of aliases via config, something more
"dynamic" could be used where a DN, CN or some other attribute about the
cert that was parsed during startup becomes the representation?

<vhost...>
   ...
  #As today
   SSLProxyMachineCertificateFile /path/to/file
   <Proxy ...>
      #Plus new stuff
      SSLProxyMachineCertificateCN myIdentity
      #or
      SSLProxyMachineCertificateDN /C=US/ST=Missouri/L=St.
Louis/O=BitNebula/CN=DanielRuggeri.bitnebula.com
   </Proxy>
</vhost>

This could be a really clean solution because the proxy can just pass
this name or DN to the ssl module in a note and the ssl module could
make the selection of certs from that data.

Stashing this (completely untested and thrown together) code around line
1778 in modules/ssl/ssl_engine_kernel.c could be all that's needed in
mod_ssl....
    char *preferred_name;
......
    if (preferred_name) {
        for (i = 0; i < sk_X509_INFO_num(certs); i++) {
            X509_NAME *name;
            info = sk_X509_INFO_value(certs, i);
            name = X509_get_subject_name(inf->x509);

            for(j = 0; j < X509_NAME_entry_count(name); j++) {
                const char *this_name = //something
                if (strcmp(preferred_name, this_name) == 0) {
                    modssl_proxy_info_log(c, info, APLOGNO(02279)
                                          "found acceptable cert");

                    modssl_set_cert_info(info, x509, pkey);
                    return TRUE;
                }
            }
        }
        ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(000000)
            SSLPROXY_CERT_CB_LOG_FMT
            "server configuration requested certificate name %s"
            "but it was not found in the certificate store",
preferred_name);
    }



I haven't cracked open the proxy code to see what it would take to
collapse this down to a per proxy/worker/etc, but it doesn't seem like
terrible endeavor.

-- 
Daniel Ruggeri


Re: Allow SSLProxy* config in context?

Posted by Rainer Jung <ra...@kippdata.de>.
Am 13.04.2016 um 19:49 schrieb Rainer Jung:
> Am 13.04.2016 um 17:04 schrieb Graham Leggett:
>> On 13 Apr 2016, at 12:40 PM, Rainer Jung <ra...@kippdata.de> wrote:
>>
>>> I stumbled into a situation where a reverse proxy had two different
>>> backends behind the same VHost of the proxy. Both backends demand
>>> client certs as becomes more and more common for services today.
>>> Unfortunately the CA which issues the client certs in both cases is
>>> the same CA, but the demanded client cert is individual to the
>>> backend services.
>>>
>>> As far as I can see, this is currently not configurable. The
>>> SSLProxyMachineCertificateFile and SSLProxyMachineCertificatePath
>>> only work on the VHost level and the client cert detection algo in
>>> ssl_callback_proxy_cert() chooses the first client cert it can find
>>> which was issued b the right CA. No way to distinguish further.
>>>
>>> To me it looks like the "right" way of handling SSLProxy* config
>>> would be per <Proxy>. Did anyone else already encounter a similar
>>> problem? Any thoughts or experiments on how to solve this for the
>>> future?
>>
>> I looked at this a while back.
>>
>> The catch is that mod_ssl forces us to declare SSL certs and keys
>> server wide, not per directory, loaded and parsed at startup. We
>> however want to specify certs per directory.
>
> Per directory or better in some new way per proxy backend (or proxy
> worker, proxy balancer).
>
>> What I had in mind was a syntax where the certs were named, for example:
>>
>> SSLProxyCertificate foo /path/to/foo.cert
>>
>> Followed somewhere else by:
>>
>> <Proxy …>
>>    SSLProxyEnable foo
>> </Proxy>
>
> I would also like to prevent using per dir config, directory walk etc.
>
> Like (I think) proxy has it's backend config in per server structures
> which are lists of backends with names, the proxy ssl config could be a
> list of traditional ssl configs indexed by name. Name could be like you
> suggest a name given via additional directive attributes, or simply the
> balancer name (URL) given in the opening <Proxy URL> tag of the proxy
> container.
>
> What I haven't yet investigated is, how easy one could pass the worker
> or balancer name from mod_proxy to mod_ssl, so that mod_ssl can choose
> the correct ssl proxy config (without coupling the proxy and ssl details
> too close to each other). Another thing is getting a hand at the URL
> when the SSLProxy* directive is handled inside <Proxy> during directive
> parsing. Maybe similar to how mod_proxy does it.
>
> Yes, that looks like a deeper coupling of mod_ssl and mod_proxy, but the
> whole use case of mod_ssl as an client currently is coupled to the proxy
> setup, so it doesn't look wrong to "fully" support SSLProxy* per <Proxy>.

We could pass the worker name from mod_proxy to mod_ssl via a connection 
note, similar to currently already passing the SNI name via the 
connection note proxy-request-hostname.

> I guess we need to prototype something.

Regards,

Rainer

Re: Allow SSLProxy* config in context?

Posted by Rainer Jung <ra...@kippdata.de>.
Am 13.04.2016 um 17:04 schrieb Graham Leggett:
> On 13 Apr 2016, at 12:40 PM, Rainer Jung <ra...@kippdata.de> wrote:
>
>> I stumbled into a situation where a reverse proxy had two different backends behind the same VHost of the proxy. Both backends demand client certs as becomes more and more common for services today. Unfortunately the CA which issues the client certs in both cases is the same CA, but the demanded client cert is individual to the backend services.
>>
>> As far as I can see, this is currently not configurable. The SSLProxyMachineCertificateFile and SSLProxyMachineCertificatePath only work on the VHost level and the client cert detection algo in ssl_callback_proxy_cert() chooses the first client cert it can find which was issued b the right CA. No way to distinguish further.
>>
>> To me it looks like the "right" way of handling SSLProxy* config would be per <Proxy>. Did anyone else already encounter a similar problem? Any thoughts or experiments on how to solve this for the future?
>
> I looked at this a while back.
>
> The catch is that mod_ssl forces us to declare SSL certs and keys server wide, not per directory, loaded and parsed at startup. We however want to specify certs per directory.

Per directory or better in some new way per proxy backend (or proxy 
worker, proxy balancer).

> What I had in mind was a syntax where the certs were named, for example:
>
> SSLProxyCertificate foo /path/to/foo.cert
>
> Followed somewhere else by:
>
> <Proxy …>
>    SSLProxyEnable foo
> </Proxy>

I would also like to prevent using per dir config, directory walk etc.

Like (I think) proxy has it's backend config in per server structures 
which are lists of backends with names, the proxy ssl config could be a 
list of traditional ssl configs indexed by name. Name could be like you 
suggest a name given via additional directive attributes, or simply the 
balancer name (URL) given in the opening <Proxy URL> tag of the proxy 
container.

What I haven't yet investigated is, how easy one could pass the worker 
or balancer name from mod_proxy to mod_ssl, so that mod_ssl can choose 
the correct ssl proxy config (without coupling the proxy and ssl details 
too close to each other). Another thing is getting a hand at the URL 
when the SSLProxy* directive is handled inside <Proxy> during directive 
parsing. Maybe similar to how mod_proxy does it.

Yes, that looks like a deeper coupling of mod_ssl and mod_proxy, but the 
whole use case of mod_ssl as an client currently is coupled to the proxy 
setup, so it doesn't look wrong to "fully" support SSLProxy* per <Proxy>.

I guess we need to prototype something.

Regards,

Rainer

Re: Allow SSLProxy* config in context?

Posted by Graham Leggett <mi...@sharp.fm>.
On 13 Apr 2016, at 12:40 PM, Rainer Jung <ra...@kippdata.de> wrote:

> I stumbled into a situation where a reverse proxy had two different backends behind the same VHost of the proxy. Both backends demand client certs as becomes more and more common for services today. Unfortunately the CA which issues the client certs in both cases is the same CA, but the demanded client cert is individual to the backend services.
> 
> As far as I can see, this is currently not configurable. The SSLProxyMachineCertificateFile and SSLProxyMachineCertificatePath only work on the VHost level and the client cert detection algo in ssl_callback_proxy_cert() chooses the first client cert it can find which was issued b the right CA. No way to distinguish further.
> 
> To me it looks like the "right" way of handling SSLProxy* config would be per <Proxy>. Did anyone else already encounter a similar problem? Any thoughts or experiments on how to solve this for the future?

I looked at this a while back.

The catch is that mod_ssl forces us to declare SSL certs and keys server wide, not per directory, loaded and parsed at startup. We however want to specify certs per directory.

What I had in mind was a syntax where the certs were named, for example:

SSLProxyCertificate foo /path/to/foo.cert

Followed somewhere else by:

<Proxy …>
  SSLProxyEnable foo
</Proxy>

Regards,
Graham
—


Re: Allow SSLProxy* config in context?

Posted by Christian Folini <ch...@netnea.com>.
Rainer,

There is a commercial apache-based reverse proxy in Switzerland 
(with substantial market share) which is able to use / create
a client certificate _per_ session.

So the client connects to the RP, performs authentication. When
creating the session serverside, the RP creates a client cert and
fills it with information received from the client and binds this
cert to the session. Then it connects to the backend and uses this
dynamic client cert in the handshake.

I realise this is way beyond what Apache is capable of doing. But
when looking into the limitations of SSLProxy..., one might consider
an architecture, that would allow this. Maybe not immediately, but
sometime down the road.

Best,

Christian


-- 
Seek simplicity, and distrust it.
-- Alfred North Whitehead