7

I am trying to set up part of a Virtualhost in apache to require client authentication. The VirtualHost in question also acts as a reverse proxy for the actual web server. Here's what I have done:

  • Created ca.crt, ca.csr, and ca.key on the server I am using as the CA.
  • Modified the config of the VirtualHost to look like this:

...

ProxyPass / http://xxx.xxx.xxx.xxx:80/
ProxyPassReverse / http://xxx.xxx.xxx.xxx:80/
ProxyPassReverseCookiePath / /

SSLEngine On
SSLCertificateFile "/private/etc/apache2/server.crt"
SSLCertificateKeyFile "/private/etc/apache2/server.key"
SSLCertificateChainFile "/private/etc/apache2/ca_bundle.crt"
SSLCACertificateFile "/private/etc/apache2/self_ca.crt"
SSLVerifyClient none
SSLOptions StrictRequire   
SSLProtocol all -SSLv2
SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL

<Location /clientauth>
    # These options force the client to authenticate with a client certificate.
    SSLVerifyClient require
    SSLVerifyDepth 1
</Location>
  • Created a test client certificate using my custom CA.
  • Installed the client certificate in to the login keychain on Mac OS X Lion, and manually into Firefox.

But I am unable to browse to the /clientauth path.

  • Firefox says "SSL peer was unable to negotiate an acceptable set of security parameters."
  • Opera says "Secure connection: fatal error (40) from server."
  • Chrome and Safari say "HTTP 403 Forbidden".
  • cURL (using the .p12 file) for some reason cannot find the key...
  • cURL (using the .crt and .key files) does the handshake, sends the request and then says "Empty reply from server".
  • The apache error logs keep repeating the line Re-negotiation handshake failed: Not accepted by client!?

Is this a conflict between using client authentication and being a reverse proxy? Or have I done something else wrong?

5

The underlying problem here is the renegotiation refusal. This stems from activity over the last year or two to fix a TLS vulnerability, and there were various interim fixes of refusing to renegotiate until a new TLS extension was implemented. So one thing you need to do is ensure your SSL (OpenSSL) and possibly therefore your Apache HTTPD as well is/are as up to date as possible.

  • Turns out the server had OpenSSL 0.9.8l, the version in which they disabled renegotiation altogether. Updating should fix this, thanks. – DanielGibbs Jul 27 '12 at 22:56
  • @DanielGibbs, did upgrading OpenSSL fix your issue? To what version did you upgrade? – Kevin Meredith May 21 '13 at 16:19
  • Hi Kevin, I did end up fixing this issue by upgrading both Apache and OpenSSL to (I think) the latest versions as of when this question was asked. I'll have a look when I get to work and I'll get back to you. – DanielGibbs May 21 '13 at 20:03
  • Apache is version 2.4.2 and OpenSSL is 0.9.8r (Feb 2011, not that recent afterall). – DanielGibbs May 21 '13 at 21:14
5

The HTTP client only sends the HTTP request once the SSL session has been negotiated, which means that the server only knows the URL requested by the client once SSL has been setup. Since you are changing the value of SSLVerifyClient based on the URL, Apache cannot request the client certificate when the SSL session is first negotiated, and instead has to force a renegotiation of the session once it knows the URL. It seems that the problem lies with this renegotiation, and so I suggest that you test it without this by setting SSLVerifyClient require in the VirtualHost block and removing it from the Location block.

  • Ah, that makes sense. Then how would I configure it so that only a path actually requires the client to have a valid certificate? – DanielGibbs Jul 26 '12 at 1:02
  • @DanielGibbs The way you've done it is perfectly correct but it relies on the renegotiation being agreed to by the client: see my answer. – user207421 Jul 26 '12 at 7:18
  • I am running into exactly the same problem as described in the Question and I tried to implement your Solution. I put the Directives SSLVerifyClient require and SSLVerifyDepth 1 into the VirtualHost Block. Now I can open the SSL Connection but the Client Certificate is not recognized and the Location is actually unprotected. Anyone can open it as well. – Bodo Hugo Barwich Jun 28 '18 at 14:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.