[Bug 63925] New: Wrong "cert does not match for name"

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

[Bug 63925] New: Wrong "cert does not match for name"

Bugzilla from bugzilla@apache.org
https://bz.apache.org/bugzilla/show_bug.cgi?id=63925

            Bug ID: 63925
           Summary: Wrong "cert does not match for name"
           Product: Apache httpd-2
           Version: 2.4.6
          Hardware: All
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P2
         Component: mod_ssl
          Assignee: [hidden email]
          Reporter: [hidden email]
  Target Milestone: ---

Created attachment 36884
  --> https://bz.apache.org/bugzilla/attachment.cgi?id=36884&action=edit
error log file

Setup:
Client --https(443)-- Apache on server1 --https(8443)-- Backend web-server
The attached log file is from "server1".

Vhost config on server1:
<IfModule mod_ssl.c>
<VirtualHost *:443>
        DocumentRoot "/var/www/html/wrong/"
        ServerName server1.tld1
        SSLCertificateFile /etc/letsencrypt/live/server1.tld1/cert.pem
        SSLCertificateKeyFile /etc/letsencrypt/live/server1.tld1/privkey.pem
        Include /etc/letsencrypt/options-ssl-apache.conf
        SSLCertificateChainFile /etc/letsencrypt/live/server1.tld1/chain.pem

        LogLevel debug
        SSLProxyEngine On
        ProxyPreserveHost On
        ProxyPass / https://server2.tld2:8443/
        ProxyPassReverse / https://server2.tld2:8443/
</VirtualHost>
</IfModule>

mod_ssl is using the http header field "Host:" to check the certificate on a
remote server. Using "ProxyPreserveHost On" in mod_proxy when also using
mod_ssl to communicate with a backend server is unfortunate because
certificates cannot be validated:

[Thu Nov 14 09:14:08.348553 2019] [ssl:debug] [pid 15010] ssl_util_ssl.c(495):
AH02412: [server1.tld1:443] Cert does not match for name 'server1.tld1'
[subject: CN=server2.tld2 / issuer: CN=Let's Encrypt Authority X3,O=Let's
Encrypt,C=US / serial: 123456789 / notbefore: Nov  2 22:22:22 2019 GMT /
notafter: Feb  2 22:22:22 2020 GMT]

This then throws the follwing in error to the client visiting the web site:
Proxy Error
The proxy server could not handle the request GET /.
Reason: Error during SSL Handshake with remote server

I suggest that this bug is being fixed by adding a configuration variable to
mod_ssl so that mod_ssl is using what's in "ProxyPass*" to check that a cert
provided from the backend server is valid or not.

Workaround is to use an other http header, ie "Via:", to tell the backend
server what website to show.

I have attached log file and config file from server1.

To understand the attached log file and config file. Here's it's parameters:
11.11.11.11 = my client
server1.tld1 = apache server (the one that this log is from) this is the
frontend server and is handeling requests from internet (the reverse proxy)
22.22.22.22 and server2.tld2 = the backend server which as several virtual
hosts and hence needs "Host:" to be set correctly
abcdefghi = let's encrypt cert serial (no actual need to keep this hidden, but
i did it anyway)
123456789 = https certificat on my remote server (server2.tld2)

--
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

[Bug 63925] Wrong "cert does not match for name"

Bugzilla from bugzilla@apache.org
https://bz.apache.org/bugzilla/show_bug.cgi?id=63925

Idar Lund <[hidden email]> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |[hidden email]

--
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

[Bug 63925] Wrong "cert does not match for name"

Bugzilla from bugzilla@apache.org
In reply to this post by Bugzilla from bugzilla@apache.org
https://bz.apache.org/bugzilla/show_bug.cgi?id=63925

--- Comment #1 from Yann Ylavic <[hidden email]> ---
(In reply to Idar Lund from comment #0)
> <VirtualHost *:443>
> ServerName server1.tld1
[snip]
> SSLProxyEngine On
> ProxyPreserveHost On
> ProxyPass / https://server2.tld2:8443/
> ProxyPassReverse / https://server2.tld2:8443/
> </VirtualHost>
>
> mod_ssl is using the http header field "Host:" to check the certificate on a
> remote server.

mod_ssl is indeed using the "Host:" which is sent to the backend server to
validate that the certificate given by that backend corresponds. This is the
right think to do.

What happens in your case is that with "ProxyPreserveHost on" this "Host:" is
"server1" (the one from the client/browser), so it fails to match the returned
"server2" certificate. But why use ProxyPreserveHost in the first place if the
backend really is "server2"?

I'd suggest to leave ProxyPreserveHost alone (i.e. default "off"), so that the
"Host:" header is taken from the ProxyPass, or set "SSLProxyCheckPeerName off"
if you don't want to verify the backend's CN (it can't match in your case).

--
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

[Bug 63925] Wrong "cert does not match for name"

Bugzilla from bugzilla@apache.org
In reply to this post by Bugzilla from bugzilla@apache.org
https://bz.apache.org/bugzilla/show_bug.cgi?id=63925

--- Comment #2 from Idar Lund <[hidden email]> ---
(In reply to Yann Ylavic from comment #1)
> mod_ssl is indeed using the "Host:" which is sent to the backend server to
> validate that the certificate given by that backend corresponds. This is the
> right think to do.
>
> I'd suggest to leave ProxyPreserveHost alone (i.e. default "off"), so that
> the "Host:" header is taken from the ProxyPass, or set
> "SSLProxyCheckPeerName off" if you don't want to verify the backend's CN (it
> can't match in your case).

I totally agree that this should be default behaviour, but in this case the
backend server is serving several sites and needs a way to determine what site
(or vhost for that matter) to serve the query. The standardized way to do that
is to use the "Host:" HTTP header field.

If I turn "ProxyPreserveHost" off, then the backend server has no idea on what
site it's supposed to serve. This is why I also mentioned the workaround with
the "Via:" HTTP header setting.

Also; disabling the CN checking is not an option as this opens up for man in
the middle attacks.

This is also why I'm suggesting that it should be configurable what mod_ssl is
using to check the name.

--
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

[Bug 63925] Wrong "cert does not match for name"

Bugzilla from bugzilla@apache.org
In reply to this post by Bugzilla from bugzilla@apache.org
https://bz.apache.org/bugzilla/show_bug.cgi?id=63925

--- Comment #3 from Yann Ylavic <[hidden email]> ---
(In reply to Idar Lund from comment #2)
> If I turn "ProxyPreserveHost" off, then the backend server has no idea on
> what site it's supposed to serve.

Why that? If ProxyPreserveHost is off then the "Host;" header will be the one
of the ProxyPass, which is what you seem to want.

--
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

[Bug 63925] Wrong "cert does not match for name"

Bugzilla from bugzilla@apache.org
In reply to this post by Bugzilla from bugzilla@apache.org
https://bz.apache.org/bugzilla/show_bug.cgi?id=63925

--- Comment #4 from Idar Lund <[hidden email]> ---
(In reply to Yann Ylavic from comment #3)
> (In reply to Idar Lund from comment #2)
> > If I turn "ProxyPreserveHost" off, then the backend server has no idea on
> > what site it's supposed to serve.
>
> Why that? If ProxyPreserveHost is off then the "Host;" header will be the
> one of the ProxyPass, which is what you seem to want.

Because the backend server needs to know what site the _client_ was asking for.
The http header to server1 is correct, but then when this is forwarded to
server2 the host variable in the header has to be intact. If not, server2 has
noe idea on what site (vhost) it's supposed to serve.

--
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

[Bug 63925] Wrong "cert does not match for name"

Bugzilla from bugzilla@apache.org
In reply to this post by Bugzilla from bugzilla@apache.org
https://bz.apache.org/bugzilla/show_bug.cgi?id=63925

--- Comment #5 from Yann Ylavic <[hidden email]> ---
So I suppose your backend has a configuration like this:

<VirtualHost *:8443>
        ServerName server1
        SSLCertificateFile /path/to/server2.pem
        ...
</VirtualHost>

and thus its certificate's CN ("server2") does not match its ServerName
("server1")?

My point is that if you want the proxy to validate the backend's CN, ServerName
and SSLCertificateFile need to be consistent on the backend (usually with
ProxyPreserveHost the same certificate is used on the proxy and the backend).
Otherwise, the proxy cannot accept that the returned certificate does not match
the Host header _it_ requested.

--
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

[Bug 63925] Wrong "cert does not match for name"

Bugzilla from bugzilla@apache.org
In reply to this post by Bugzilla from bugzilla@apache.org
https://bz.apache.org/bugzilla/show_bug.cgi?id=63925

--- Comment #6 from Idar Lund <[hidden email]> ---
(In reply to Yann Ylavic from comment #5)

> So I suppose your backend has a configuration like this:
>
> <VirtualHost *:8443>
> ServerName server1
> SSLCertificateFile /path/to/server2.pem
> ...
> </VirtualHost>
>
> and thus its certificate's CN ("server2") does not match its ServerName
> ("server1")?

Something similar, yes.


> My point is that if you want the proxy to validate the backend's CN,
> ServerName and SSLCertificateFile need to be consistent on the backend
> (usually with ProxyPreserveHost the same certificate is used on the proxy
> and the backend).
> Otherwise, the proxy cannot accept that the returned certificate does not
> match the Host header _it_ requested.

We do share the same point - mod_ssl needs to know what name it should check
against and today this is done with the "Host:" header variable. But I disagree
that I should have the same certificate on both servers. Then I'd use the
"ProxyVia On" directive instead and filter on "Via:" on server2.

The best way to fix this is to make it configurable. So that mod_ssl either can
take a CN variable name to check against, or a directive to tell mod_ssl to use
whatever is in ProxyPass/ProxyPassReverse.

--
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]