Hello Karspar,
Hi all,

On Wed, Apr 18, 2012 at 10:16:51AM +0200, Kaspar Brand wrote:

> > So implementation-wise this will most likely have two parts of code:
> > 
> > 1. Determining the hostname to put into SNI data depending on
> > ProxyPreserveHost somewhere in the reverse proxy module. 
> > 
> > 2. Putting that value into the SNI data in mod_ssl's ssl_engine_io.c.
> I'm not too familiar with the history/motivation of the
> ProxyPreserveHost directve (which dates to as far as 2002, see r93089),
> but in the context of proxy SSL requests, I think it isn't a
> particularly good idea to support this feature... because essentially,
> it opens up the door to MitM attacks: you're asking mod_proxy_http to,
> say, request URI https://foo.example.org/index.html, but directing it
> via TLS to a host configured with certificate bar.example.org.

I don't think so: I'm not directing the Proxy to connect to a different
host. I just make it send different SNI data to the configured backend
server and accept a different CN in the server's certificate. The MitM
would still have to hijack the server's IP or DNS entry and present a
certificate issued by a trusted CA for that CN, just that it now has to
read bar.example.org instead of foo.example.org. I don't see, how the
attack gets simpler by that.

I am, however, not sure how the change will affect forward proxying (if
at all). I have only thought about reverse proxying where I have
SSLProxyVerify set to require on the reverse proxy and run both servers
with a self-signed CA for just that purpose. All the client-side
presentation is done by the reverse proxy with the official certificates.

> mod_proxy_http's "blindness" for MitM attacks was also the reason for
> introducing SSLProxyCheckPeerCN in r760866/r768504, I assume. In
> addition to dealing with SNI extension / Host header mismatches you
> would also have to accommodate for the case of CN / Host header mismatches.

That's done automatically since the same note is used for CN check and
SNI data. By setting that note to the hostname from the Host header,
all there items are in sync automatically.

I've put together a small patch doing just that (admittedly without much
knowing what I'm doing since its my very first time hacking apache).
I've opened a bug report for it:
https://issues.apache.org/bugzilla/show_bug.cgi?id=53134. Feel free to
have a look at it and tell me what you think. Perhaps it also helps to
make clear, what I mean.

With that patch name based virtual hosts work with SSL through an
httpd-2.4/trunk reverse proxy with a single virtual host and no rewrite
rules whatsoever on both servers.

> To solve your immediate problem in 2.4, what you could try is:

>       ProxyPass / https://127.0.0.1:12443/
>         ProxyPreserveHost On
>         SSLProxyCheckPeerCN off

> This prevents mod_ssl in 2.4 from adding an SNI extension to the proxy
> request (it will skip IP addresses), and will pass the Host reader from
> the original request to the backend. You need to turn off
> SSLProxyCheckPeerCN at the same time (unless your backend cert has
> CN=127.0.0.1) - but in the end, this just reflects what you're asking
> mod_proxy_http to do: connect via TLS to host with cert X and request
> resource from host Y.

I've chosen the second possible workaround: Setting SSLProxyProtocol to
SSLv3. If you look at the code in ssl_engine_io.c you'll see that its
the second condition for disabling SNI towards the backend server. This
way, SSLProxyCheckPeerCN can stay enabled.
-- 
Micha
I hate forms!

Reply via email to