Setting up an Apache Web Server as a Proxy

This section covers 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.

To support OCSP GET requests through the proxy in recent version of Apache (2.4), you may need to activate mod_lbmethod_byrequests. You may also need to use the nocanon directory to ProxyPass in order to correctly-forward encoded slash characters (/).

To set up an Apache Web Server as a Proxy in front of EJBCA, 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 the 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. Note that the SSL-certificate should be issued by the same CA that issued the Tomcat SSL certificate (ManagementCA in the default configuration). To generate the SSL-certificate for Apache using the EJBCA CLI, run the following:

$ cd $EJBCA_HOME
 $ bin/ejbca.sh ra addendentity apache-ssl foo123 
"CN=ca-server.company.local,O=EJBCA Sample,C=SE" "" ManagementCA "" 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, according to the follwoing.

Note that this configuration with SSLVerifyClient inside a Location directive is not safe with the discovered vulnerability in SSL/TLS discovered in 2009-11-15 (CVE-2009-3555). You should run updated versions of Apache and Java, or 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).

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

It is recommended to use a firewall as an extra layer of security (e.g. drop malformed packages and prevent future services from being exploited).

URL Configuration

The following sample configuration allows rendering nice URLs for OCSP, to for example point your OCSP service locator to http://ocsp.company.com/ instead of http://ocsp.company.com:8080/ejbca/publicweb/status/ocsp (some information omitted 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> 

This also applies for CRL distribution points.