I needed Certificate Authentication on a Bastion host. I was pointed to the article from Zeitoun.net (below) by a friend, but it did not work with Apache 2.2.
Apache took my SSL_* variables and passed them along as HTTP_SSL_* variables. This is ok, but not good enough if I don’t want to change source code.
After hacking it a little I found the following seemed to work:
Bastion:
#LoadModule proxy_module modules/mod_proxy.so #LoadModule headers_module modules/mod_headers.so LoadModule ssl_module modules/mod_ssl.so Listen 443 AddType application/x-x509-ca-cert .crt AddType application/x-pkcs7-crl .crl SSLPassPhraseDialog builtin SSLSessionCache shmcb:/var/cache/mod_ssl/scache(512000) SSLSessionCacheTimeout 300 SSLMutex default SSLRandomSeed startup file:/dev/urandom 256 SSLRandomSeed connect builtin SSLCryptoDevice builtin <VirtualHost _default_:443> Servername bastion # this did not work the way I wanted # SSLProxyEngineSSLProxyMachineCertificateFile /usr/local/etc/proxyUser.crt ErrorLog logs/bastion_error_log TransferLog logs/bastion_access_log LogLevel warn SSLEngine on SSLProtocol all -SSLv2 SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM SSLCertificateFile /etc/pki/tls/certs/localhost.crt SSLCertificateKeyFile /etc/pki/tls/private/localhost.key SSLCACertificatePath /usr/local/etc/auth/ SSLVerifyClient require SSLVerifyDepth 2 SSLOptions +ExportCertData <Proxy *> AddDefaultCharset Off Order deny,allow Allow from all </Proxy> # initialize the special headers to a blank value to avoid http header forgeries RequestHeader set SSL_CLIENT_S_DN "" RequestHeader set SSL_CLIENT_I_DN "" RequestHeader set SSL_SERVER_S_DN_OU "" RequestHeader set SSL_CLIENT_VERIFY "" RequestHeader set SSL_CLIENT_S_DN_CN "" <Location /> # add all the SSL_* you need in the internal web application RequestHeader set SSL_CLIENT_S_DN "%{SSL_CLIENT_S_DN}s" RequestHeader set SSL_CLIENT_I_DN "%{SSL_CLIENT_I_DN}s" RequestHeader set SSL_SERVER_S_DN_OU "%{SSL_SERVER_S_DN_OU}s" RequestHeader set SSL_CLIENT_VERIFY "%{SSL_CLIENT_VERIFY}s" RequestHeader set SSL_CLIENT_S_DN_CN "%{SSL_CLIENT_S_DN_CN}s" ProxyPass https://internal/ ProxyPassReverse https://internal/ </Location> SetEnvIf User-Agent ".*MSIE.*" \ nokeepalive ssl-unclean-shutdown \ downgrade-1.0 force-response-1.0 CustomLog logs/bastion_request_log \ "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b" </VirtualHost>
On the Internal machine
Turn off Client SSL Authentication
# SSLVerifyClient require
and add the following for each SSL variable that you need
SetEnvIfNoCase SSL_CLIENT_S_DN_CN “(.*)” SSL_CLIENT_S_DN_CN=$1
Cool thing is that I can run HTTPS on the backside, just not Client Certificate authentication.
http://www.zeitoun.net/articles/client-certificate-x509-authentication-behind-reverse-proxy/start
http://www.askapache.com/htaccess/setenvif.html
http://httpd.apache.org/docs/2.2/mod/mod_headers.html
http://httpd.apache.org/docs/2.2/mod/mod_proxy.html
http://httpd.apache.org/docs/2.2/mod/mod_ssl.html