Setting up an Apache Web Server as a proxy in front of EJBCA Rumi, April 26, 2012 This section will show you how to use an Apache Web Server Proxy in front of EJBCA. The resulting server will Display EJBCA public web at https://ca-server.company.local/ Redirect all HTTP-requests to HTTPS, except for OCSP and CRL. Require a client SSL certificate when accessing https://ca-server.company.local/adminweb/ Be able to loadbalance requests Still answer to requests on https://ca-server.company.local/ejbca/* This example was created on Ubuntu 64-bit Server 7.10 using the Apache Web Server 2.2 package, but should be easy to adapt to any system able to run Apache. Start by installing EJBCA as normal. If you intend to have the CA on the same machine as the proxy you should modify $EJBCA_HOME/conf/web.properties to only listen to localhost httpsserver.bindaddress.pubhttp=127.0.0.1 httpsserver.bindaddress.pubhttps=127.0.0.1 httpsserver.bindaddress.privhttps=127.0.0.1 Install the Apache web server and enable required modules: $sudo su #apt-get install apache2 #cd /etc/apache2/mods-enabled/ #ln -s ../mods-available/proxy.load proxy.load #ln -s ../mods-available/proxy_http.load proxy_http.load #ln -s ../mods-available/proxy_ajp.load proxy_ajp.load #ln -s ../mods-available/proxy_balancer.load proxy_balancer.load #ln -s ../mods-available/rewrite.load rewrite.load #ln -s ../mods-available/ssl.load ssl.load Generate the SSL-certificate for Apache. This should be issued by the same CA that issued the Tomcat SSL certificate (AdminCA1 in the default configuration). This can be done with the EJBCA CLI: $ cd $EJBCA_HOME $ bin/ejbca.sh ra adduser apache-ssl foo123 "CN=ca-server.company.local,O=EJBCA Sample,C=SE" "" AdminCA1 "" 1 PEM SERVER $ bin/ejbca.sh ra setclearpwd apache-ssl foo123 $ bin/ejbca.sh batch $ ls p12/pem/ca-server.company.local* p12/pem/ca-server.company.local-CA.pem p12/pem/ca-server.company.local-Key.pem p12/pem/ca-server.company.local.pem Configure the default virtual host-file /etc/apache2/sites-enabled/000-default Note Note that this configuration with SSLVerifyClient inside a Location directtive is not safe with the newly (2009-11-15) discovered vulnerability in SSL/TLS. You should only use SSLVerifyClient and SSLCipherSuite on whole virtualhosts. You can create the same effect as below by using a separate subdomain for EJBCA administration (i.e. admin.ca.youdomain.com). See for example the Debian advisory. NameVirtualHost *:80 <VirtualHost *:80> DocumentRoot /var/www/ # Proxy requests to EJBCA instances (only one on local machine configured) <Proxy balancer://mycluster-kerb> BalancerMember ajp://localhost:8009/ejbca/ </Proxy> ProxyPass / balancer://mycluster-kerb/ RewriteEngine On # Redirect all but the CRL Distribution Point, OCSP and Helthcheck to HTTPS RewriteCond %{THE_REQUEST} !(/publicweb/webdist/certdist.*cmd=crl|/publicweb/status/) RewriteRule ^(.*)$ https://%{SERVER_NAME}$1 [L,R] # Treat reqeusts to / and /ejbca/ as the same. Required by EJBCA's Admin Web. RewriteCond %{THE_REQUEST} /ejbca/ RewriteRule ^/ejbca/(.*)$ /$1 [PT] # Configure log LogLevel warn ErrorLog /var/log/apache2/error.log CustomLog /var/log/apache2/access.log combined </VirtualHost> NameVirtualHost *:443 <VirtualHost *:443> DocumentRoot /var/www/ RewriteEngine On # Treat reqeusts to / and /ejbca/ as the same. Required by EJBCA's Admin Web. RewriteCond %{THE_REQUEST} /ejbca/ RewriteRule ^/ejbca/(.*)$ /$1 [PT] # Configure secure SSL for this server using SSL certificate generated by EJBCA SSLEngine on SSLCipherSuite HIGH SSLProtocol all -SSLv2 SSLCertificateFile /home/jboss/ejbca/p12/pem/ca-server.company.local.pem SSLCertificateKeyFile /home/jboss/ejbca/p12/pem/ca-server.company.local-Key.pem # Require Client SSL certificate for the Admin GUI <Location /adminweb> SSLVerifyClient require SSLVerifyDepth 1 SSLCACertificateFile /home/jboss/ejbca/p12/pem/ca-server.company.local-CA.pem </Location> # Proxy requests to EJBCA instances (only one on local machine configured) <Proxy balancer://mycluster-kerb> BalancerMember ajp://localhost:8009/ejbca/ </Proxy> ProxyPass / balancer://mycluster-kerb/ # Configure log LogLevel warn ErrorLog /var/log/apache2/error.log CustomLog /var/log/apache2/access.log combined </VirtualHost> Reload the apache configuration and verify that only port 80, 443 and other desired services (e.g. a ssh-daemon) are listening on all or external interfaces $sudo /etc/init.d/apache2 reload $sudo netstat -nap | grep LISTEN | grep -v 127.0.0.1 tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 7612/apache2 tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN 7612/apache2 tcp6 0 0 :::22 :::* LISTEN 3746/sshd Even though this looks secure, it is still a good idea to use a firewall as an extra layer of security (e.g. drop malformed packages and prevent future services from being exploited). *** Nice URLs *** A sample configuration how to fix up nice URLs for OCSP so that you can point your OCSP service locator to http://ocsp.company.com/ instead of http://ocsp.company.com:8080/ejbca/publicweb/status/ocsp (some info left out for brevity). <VirtualHost ocsp.company.com:80> <Proxy *> Order deny,allow Allow from all </Proxy> ProxyPass / http://127.0.0.1:8080/ejbca/publicweb/status/ocsp ProxyPassReverse / http://127.0.0.1:8080/ejbca/publicweb/status/ocsp </VirtualHost> You can easily do the same for CRL distribution points. Setting up an Apache Web Server with mod_jk in front of EJBCA Instead of using a proxy you can use mod_jk which uses a JK connector between apache and tomcat. I think this have some benefits. You can easily combine it with mod_rewrite to have any type of external URLs, for OCSP, CRLs etc, and mapping them to other URLs in EJBCA. This section will show you how to use an Apache with mod_jk in front of EJBCA. The resulting server will Display EJBCA public web at http://demo.primekey.se/ Require a client SSL certificate when accessing https://demo.primekey.se/, which works for the admin-GUI. This example was created on Ubuntu 64-bit Server 8.10 using the Apache Web Server 2.2 package, but should be easy to adapt to any system able to run Apache. # sudo apt-get install apache2 libapache2-mod-jk # vim /etc/libapache2-mod-jk/workers.properties ----- worker.list=jboss # Define a worker using ajp13 worker.jboss.port=8009 worker.jboss.host=127.0.0.1 worker.jboss.type=ajp13 ----- # vim /etc/apache2/sites-available/demo.primekey.se ----- <VirtualHost demo.primekey.se:80> # We must disable default charset or everything will be ISO-8859-1, AddDefaultCharset off ServerAdmin webmaster@primekey.se ServerName demo.primekey.se ServerAlias demo.primekey.se JkLogFile /var/log/apache2/mod_jk.log JkLogLevel debug JkMount /* jboss JkMount / jboss </VirtualHost> <VirtualHost demo.primekey.se:443>> # We must disable default charset or everything will be ISO-8859-1, AddDefaultCharset off ServerAdmin webmaster@primekey.se ServerName demo.primekey.se ServerAlias demo.primekey.se SSLEngine on JkLogFile /var/log/apache2/mod_jk.log JkLogLevel debug JkMount /* jboss JkMount / jboss # JkExtractSSL is On by default # JkExtractSSL On </VirtualHost> ----- # vim /etc/apache2/mods-available/ssl.conf ----- SSLVerifyClient require SSLVerifyDepth 3 SSLCACertificateFile /etc/apache2/ssl/apache-CA.pem SSLCertificateFile /etc/apache2/ssl/apache.pem SSLOptions +StdEnvVars +ExportCertData ----- # vim /etc/apache2/mods-available/jk.load ----- LoadModule jk_module /usr/lib/apache2/modules/mod_jk.so JkWorkersFile /etc/libapache2-mod-jk/workers.properties ----- Now enable ssl.load and ssl.conf in /etc/apache2/mods-enabled. Finally restart apache and go to http://demo.primekey.se/ (or https). Same security considerations as for using proxy applies. If you are using the external OCSP responder then you also got to ensure you got this line in the file apache2.conf: KeepAlive Off If not apache will hang. Also an external OCSP responder it could be good to add these lines to the 'Virtual Host' configuration: RewriteEngine on RewriteRule .* /ejbca/publicweb/status/ocsp [PT] JkMount /ejbca/publicweb/status/ocsp/* ocsp_worker JkMount /ejbca/publicweb/status/ocsp ocsp_worker By doing this you don't have to bother about typing the last part of the URL. Just right server name will do. PKI ApacheApache ProxyEJBCA