Setting up an Apache Web Server as a proxy in front of EJBCA

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.

Share