2

I need to set up a forward proxy with 2-way SSL verification. I got pretty far using Apache 2.4.10 on Debian, but it fails because the certificate CN is compared to the wrong name. I've searched and read every page that remotely mentions something similar, but I can't find the solution.

Setup:

  • tomcat server running on http://localhost:8080 with namebased virtual hosts
  • when triggered each of the vhosts sends a request to https://externalserver.com:443/uri
  • the SSL connection should provide the certificate belonging to the vhost and verify the certificate of the externalserver

I've set up a virtual host in Apache 2.4.10 for each tomcat vhost, with the following configuration:

<Virtualhost *:80>
  ServerName domain1.example.com

   SSLProxyEngine On
   ProxyVia On

   SSLProxyMachineCertificateFile /proxysetup/certs/domain1.example.certandkey.pem

   # server certificate verification

   SSLProxyCACertificatePath /proxysetup/ca
   SSLProxyCARevocationCheck leaf
   SSLProxyCARevocationPath /proxysetup/crl
   SSLProxyVerify require
   SSLProxyVerifyDepth 4
   SSLProxyCheckPeerName off
   SSLProxyCheckPeerCN on
   SSLProxyCheckPeerExpire on

  ProxyPass /external https://externalserver.com/ 
  ProxyPassReverse /external https://externalserver.com/

    <Proxy "*">
        Order deny,allow
        Allow from all
    </Proxy>

   LogLevel Debug

   ErrorLog  /proxysetup/logs/domain1.example-error-80.log
   CustomLog /proxysetup/logs/domain1.example-access-80.log combined

</VirtualHost>

When I start a request (http://domain1.example.com/external/someuri) I see the SSL handshake taking place but fails with the following error

SSL Proxy: Peer certificate CN mismatch: Certificate CN: EXTERNALSERVER.COM Requested hostname: domain1.example.com

The connection is then closed.

When adding ProxyPerserveHost off the handshake stops even before this check is performed.

What needs to be done to get the certificate successfully verified?

UPDATE

I managed to get this working by changing the configuration to:

<Virtualhost *:80>
  ServerName domain1.example.com

   SSLProxyEngine On

   SSLProxyMachineCertificateFile /proxysetup/certs/domain1.example.certandkey.pem

   # server certificate verification

   SSLProxyCACertificatePath /proxysetup/ca
   SSLProxyCARevocationCheck leaf
   SSLProxyCARevocationPath /proxysetup/crl
   SSLProxyVerify require
   SSLProxyVerifyDepth 4
   SSLProxyCheckPeerName off
   SSLProxyCheckPeerCN off
   SSLProxyCheckPeerExpire on

  ProxyPass /external/ https://externalserver.com/ 
  ProxyPassReverse /external/ https://externalserver.com/

  ProxyPass / http://localhost:8080/
  ProxyPassReverse / http://localhost:8080/

    <Proxy "*">
        Require all granted
    </Proxy>

  <Proxy "*/external/">
  # only allow local requests 
  # and only if the server certificate contains the correct FQDN

  Require all denied
  Require local
  SSLRequire %{SSL_SERVER_S_DN_CN} in {"externalserver.com"}
  </Proxy>

   LogLevel Debug

   ErrorLog  /proxysetup/logs/domain1.example-error-80.log
   CustomLog /proxysetup/logs/domain1.example-access-80.log combined

</VirtualHost>

Update 2

There is still something wrong:

  1. When I change
 SSLRequire %{SSL_SERVER_S_DN_CN} in {"externalserver.com"}

to

 SSLRequire %{SSL_SERVER_S_DN_CN} in {"somethingelse.com"}

I still get a connection. Even when adding SSLOptions +StrictRequire

  1. When I set SSLProxyCheckPeerName on

The certificate of the server (externalserver.com) is matched to domain1.example.com. I would expect it to match to 'externalserver.com'

Am I doing something wrong or did I stumble upon a bug?

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Browse other questions tagged or ask your own question.