Oh No – it’s SSL!

You always fear what you don’t understand. That’s why SSL is so scary: because no-one understands it. I often think that’s the secret of its success – it’s so scary, no-one goes near it, therefore it remains a mystery, therefore it remains secure.

And yet everybody uses it, most of us really need it, and auditors insist on it. So let’s face our fears, confront them head-on, and look at how we configure SSL in a JBoss environment!

Architecture and Morality

You may need to configure SSL at different levels of your architecture, depending on the requirements of your customers, your application, or even your industry – those of you who work in financial services may be subject to PCI-compliance, in which case you’ll probably need to put SSL everywhere. That’s for another blog.

For the rest of us, it mostly depends on whether your end users are connecting directly to JBoss or not. If they are, you can configure SSL directly on the JBoss web connector. This is well-documented, and indeed forms part of the official Red Hat JBoss admin training, so I won’t spend time discussing it here.

What isn’t so well documented, but is actually the most likely scenario for most enterprises, is configuring SSL on a pre-existing Apache server acting as a Load Balancer in front of a JBoss cluster. In this scenario, you’ll probably want SSL to terminate at the Apache tier, and to have unencrypted HTTP (or more likely AJP) communications between Apache and JBoss web. This is a popular setup, and is preferable to the ‘SSL everywhere’ approach, for a number of reasons:

  • the configuration overhead (and associated management of certificates etc.) is less, as it’s limited to the Apache tier only;
  • if your Apache server is in a DMZ, and your JBoss cluster is in a secure internal network, you don’t really lose anything from a security perspective by terminating SSL at the Apache tier;
  • SSL affects performance, so confining SSL to the Apache tier (which is usually the quickest bit of the whole setup) reduces the performance impact overall.

The above scenario is the one we’ll concentrate on here.

Organisation

The configuration for SSL terminating at Apache, quite obviously, resides purely within Apache. You will need to have the mod_ssl module installed in your Apache server. If you’ve used the JBoss Enterprise Web Server (EWS) distribution from Red Hat, you’ll already have this module installed (along with a pre-configured mod_cluster module for load balancing).

Probably the best way to illustrate the configuration is to take a scenario: let’s suppose you have 2 applications in your cluster, and you’ve acquired a certificate for each one:

  • you have a certificate for the domain name “rickyroma.tier2.com”. You want to use this for the “rickyroma-webapp” application context;
  • you have a certificate for the domain name “mitchandmurray.co.uk”. You want to use this for the “mitchandmurray-webapp” application context.

The above scenario is illustrated here:

apache

Dazzle Ships

The configuration itself uses the following directives within the httpd.conf file:

  • VirtualHost directives assign the right IP address to the right server name (important when the browser verifies the server certificate);
  • ProxyPass directives re-direct to the appropriate application context;
  • SSL directives point the Apache server to your certificate files.

We’ll look at each of these directives in detail:

VirtualHost

The VirtualHost directive is the basic building block that creates “virtual” servers in Apache. It maps an IP address to a virtual server name, and acts as a container for all the settings associated with that virtual server, such as forwarding to a particular application, and the SSL certificate configuration for that server. In our example, we want 2 VirtualHosts, each one mapping an IP address to the server name we’re using in our URL, as follows:

virtual

If you don’t have multiple IP addresses assigned to your Apache server, you can achieve a similar result using name-based virtual hosting. However, your Apache build must support Server Name Indication (SNI) for this to work, as described here.

ProxyPass

Just like a regular ProxyPass directive, we’re forwarding a request to a particular application context. However in this case it’s a load-balanced application context, so we will need to know the name of the load balancer we’re using. The Balancer Name is configured in the modcluster configuration file (usually found in conf.d/modcluster.conf). If you haven’t specified a Balancer Name in this file, the default name ‘mycluster’ will be used (tip: you can see the name of your balancer on the modcluster-manager page).

You also need to include the name of the sticky session cookie, which in JBoss’s case is JSESSIONID, and the nofailover parameter should be set according to whether or not your applications are replicating sessions and can therefore support session-level failover:

  • Set it to Off if your JBoss servers are properly clustered and your applications are distributable;
  • Set it to On if you’re either not using JBoss clustering or your applications aren’t distributable.

Finally, you also need a corresponding ProxyPassReverse directive, to allow Apache to re-write the headers on the http response before they get to the browser.  This is what the full ProxyPass configuration looks like in the context of our VirtualHosts:

proxypass

SSL

There are 4 SSL directives, all of which are pretty self-explanatory:

  • SSLEngine On as you might expect, turns SSL on for this virtual server;
  • SSLCertificateFile points the virtual server to the full path of your server certificate file;
  • SSLCertificateKeyFile points the virtual server to the full path of your private key file. See below if you don’t have one of these;
  • SSLCertificateChainFile points the virtual server to the full path of your “all-in-one” or “chain” file. Again, see below for instructions on how to construct one of these.

I’d typically put all the above cert files in their own subdirectory – one for each application or virtual host. Here’s an example of these directives in action:

ssl

Once you have enabled SSL, you’ll also want to do a couple of other things:

  • you’ll want to make sure that the virtual servers listen on port 443 instead of port 80;
  • you may additionally want to include a redirect from port 80, in the event that someone tries to reach your applications over http instead of https.

Here’s our example with the full configuration, including the above options:

full-config

Obviously, this assumes you’ve DNS-registered both domain names with the IP address of the Apache server. As a tip, for testing purposes, you can stick a couple of entries in the hosts file of whatever machine you’re testing on, just to fake DNS. Make sure you get rid of them once the actual domain names are properly registered!

Junk Culture

Now, if you are in the edge case scenario where you’re migrating from a JBoss-based SSL configuration, to an Apache-based one, you’ll need a few extras.

Before you configure Apache with the above Virtual Host and SSL directives, you’ll need to ensure that your SSL certificates are in the right format for Apache. Why is this? Because if you’ve been configuring SSL for JBoss, you’ve probably done everything inside a Java keystore, and that won’t work in Apache.

Apache requires certificates in their original PEM format, and also requires the original private key file that you used to generate certificate requests. Sadly, with a Java keystore, this private key is implicit, and is not actually accessible by you. Luckily, there are tools out there that you can use to export a private key from a keystore, and to convert the exported key into a format that Apache can use. I found a good one here:

http://anandsekar.github.io/exporting-the-private-key-from-a-jks-keystore/

Once you have the exported private key file, you can use it in your CertificateKeyFile directive in httpd.conf.

Now, if you’re really unlucky, your security provider will have sent you a number of intermediate certificate files, as opposed to a single, consolidated certificate chain file. If that’s the case, you’re going to have to make the chain (also referred to as a “bundle”) file manually. It really is as dumb as it sounds! You have to open each intermediate cert file and copy/paste the contents into one big file. This file is then used as the entry for your CertificateChainFile directive in httpd.conf.

Pay attention to the order in which you paste in the intermediate certs, as this is significant. Your security provider should give you instructions on this: have a look at the following example from Comodo: https://support.comodo.com/index.php?/Default/Knowledgebase/Article/View/637/37/certificate-installation-apache–mod_ssl.

Crush

This post is really a combination of useful articles and documentation I’ve stumbled across over the last couple of years, with some hands-on experience of doing this on client sites. Hopefully by consolidating it all into this post, you’ll have what you need to be able to configure basic SSL on an Apache server acting as a load balancer for a JBoss cluster. I also hope it’s taken away some of the fear and trepidation associated with SSL, or at least I haven’t made it worse! Good luck…