A Simple Step-By-Step Guide To Apache Tomcat SSL Configuration
Secure Socket Layer (SSL) is a protocol that provides security for communications between client and server by implementing encrypted data and certificate-based authentication. Technically, the term "SSL" now refers to the Transport Layer ouSecurity (TLS) protocol, which is based on the original SSL specification.
SSL is one of the most common ways of integrating secure communication on the internet, as it is a mature protocol that is well-supported by every major browser and a number of well-respected organizations provide third party SSL authentication services.
If you're using Apache Tomcat, chances are that at least some of the data you're handling is sensitive, and SSL is an easy way to offer your users security. The good news is that Tomcat fully supports the SSL protocol. The bad news is that the configuration process and SSL itself can be a little confusing for first-time users.
Don't worry! To help you get SSL working with your Tomcat servers, we've assembled a simple, comprehensive, step-by-step guide to using SSL with Tomcat. From an overview of how the protocol actually works, to clear, simple configuration instructions, this guide will help you get SSL running on your server in no time.
Tcat eliminates tedious configuration tasks. Create the correct configuration a single time, save it to a server profile, and apply it to other instances (or groups of instances) with a single click. Try Tcat for free today!
Before we start configuring Tomcat to use SSL, it will help to understand why the SSL protocol was created, and how it works. If you already know all this stuff and are just looking to get SSL working with Apache Tomcat, click here to jump to a step-by-step configuration guide.
The SSL protocol aims to provide solutions to two simple security problems:
- How can we securely transmit data between two parties in such a way that only the two parties can read it?
- How can one (or more) of the parties involved prove that they are actually the entity we want to grant the ability to decrypt our encrypted transmission?
SSL's answer to the first question is encryption. Before transmitting any data, the sender encrypts its message, and the receiver must in turn decrypt the message before processing it. The encryption and decryption is accomplished through a method called "public key encryption."
SSL's answer to the second question is also part of the answer to the first question. In order for public key encryption to provide secure communication, one more more of the communicating parties must have some way of proving to the other that they are, in fact, who they claim to be. SSL provides this proof by requiring that one or more of the parties present a digital certificate into the initial negotiation of the connection, prior to the transmission of any encrypted data. This process is called "handshaking."
To ensure that the certificate is a valid proof of identity, SSL contacts a trusted third party server specified in the certificate, called a Certificate Authority (CA). A Certificate Authority is a trusted company that agrees to vouch for the identity of a site, usually for a fee. Generally, the more widely the CA is known as a reputable organization, the more they will charge you per year to verify your site's identity. Examples of well-respected CA's include Verisign and Digicert.
HTTPS vs. HTTP
The most common way that SSL is integrated into Internet communications is through the HTTPS protocol. Calling HTTPS a "protocol" is not entirely accurate, as it is simply a combination of the HTTP and SSL protocols. When we say a message was sent using HTTPS, what we are actually saying is that the message was first encrypted using SSL, transmitted and received using normal HTTP protocol, and then decrypted by the receiver, also with SSL.
So that's SSL in a (very basic) nutshell. To sum up:
- SSL offers security through encryption
- the encryption process is made possible through the use of digital certificates verified by a third party Certificate Authority
- the most common implementation of this process is the HTTPS combination protocol.
Looks good! Now, let's get SSL working with your Tomcat Server.
Configuring Tomcat to use SSL connections can be a bit tricky the first time around, but if you follow this step by step guide, you should it up and running in no time.
When To Use SSL With Tomcat
Before you go through the trouble of getting SSL up and running, it's a probably a good idea to determine if you actually should be using this configuration. The most common reason you'd need to use Tomcat to handle SSL connections would be if you are running Tomcat as a stand-alone web server.
In other words, if you're fronting Tomcat with a web server and using it only as an application server or Tomcat servlet container, in most cases you should let the web server function as a proxy for all SSL requests.
Why? Because all that decryption, encryption, and handshaking isn't free - actually, it's not just "not free," it's quite CPU-intensive, and it significantly slows down the speed of transmission. In other words, if you're already using a web server to serve your static content, you're better off letting it handle all that, freeing up your Tomcat server to focus on its specialty - quickly generating dynamic content, and allowing it to get that data to your web server as quickly as possible, in cleartext.
If, however, your site is small enough that you don't need to mess around with an additional web server, then Tomcat will happily handle your SSL needs. Here's how to get it working.
Configuring Tomcat To Use SSL
Setting up SSL for Tomcat can be pided into two main tasks: creating a functional keystore, and configuring the Tomcat connectors and applications. Let's tackle them one at a time.
Step 1 - Creating the Keystore
The keys Tomcat will use for SSL transactions are stored in a password-protected file called, creatively, the "keystore." The first step to enabling SSL on your server is to create and edit this file. You can create this file in one of two ways - by importing an existing key into the keystore, or by creating an entirely new key.
In the interest of simplicity, this guide will only cover the latter (but you can find instructions for importing keys on Apache's Tomcat Documentation site).
A program called keytool, which is included with your JDK, will do the actual work of creating your new keystore. To create a new keystore using this program, enter the following command at the command-line, substituting syntax appropriate for your OS:
$JAVA_HOME/bin/keytool -genkey -alias [youralias] -keyalg RSA -keystore [/preferred/keystore/path]
Use an [alias] and [path] of your choice.
Next, keytool will ask you to enter the password you want to use for the keystore. Again, choose whatever you like (but don't forget it).
After you choose the keystore password, you will enter the information required for the Certificate, such as your company and your name. Make sure this information is accurate, as you will have to submit this file to the Certificate Authority of your choice to obtain a certificate.
The last thing keytool will ask you to specify is the key password, which is the password specific to this specific certificates. Rather than enter anything at this prompt, just press ENTER.
This will cause keytool to set the key password to a value equivalent to the keystore password. Matching passwords are REQUIRED for Tomcat to access the certificate. If you choose two different passwords, any attempts to access the keystore will result in a crash (so don't do it).
Congratulations - if you followed the directions correctly, you should now have a usable keystore file named [youralias], located in the directory you chose.
Step 2 - Creating the Certificate Signing Request
Now that you've created your keystore, it's time to create a file called the Certificate Signing Request, or CSR, which will be used by the Certificate Authority of your choice to generate the Certificate SSL will present to other parties during the handshake.
You can use the keytool to create this file, as well. To do so, enter the following at the command line:
$JAVA_HOME/bin/keytool -certreq -keyalg RSA -alias [youralias] -file [yourcertificatname].csr -keystore [path/to/your/keystore]
Substitute the values you chose earlier for the [placeholders].
If you follow the instructions correctly, keytool will create a file called yourcertificatename.csr, which you can submit to the CA you've chosen via the process they provide on their website. Using this file, they will generate a custom certificate for your server, which you can download according to the instructions they provide on their website.
Step 3 - Installing Your New Certificate
Getting tired yet? Don't worry - there's light at the end of the tunnel. This is the last thing you'll need to do to create a keystore for Tomcat to use. Well, the last two things. Hang in there!
SSL verifies the authenticity of a site's certificate by using something called a "chain of trust," which basically means that during the handshake, SSL initiates an additional handshake with the Certificate Authority specified in your site's certificate, to verify that you haven't simply made up your own CA.
In order to "anchor" your certificate's chain of trust, you have to download an additional certificate, called a "Root Certificate," from your CA, and then import both this certificate and your site's new certificate into your keystore. Your CA should provide information about obtaining a Root Certificate on their website.
Once you've downloaded both your own Certificate and the Root certificate provided by your CA, import them into your keystore with the following commands, replacing the [placeholders]:
To import the Root Certificate -
keytool -import -alias root -keystore [path/to/your/keystore] -trustcacerts -file [path/to/the/root_certificate]
To import your new Certificate -
keytool -import -alias [youralias] -keystore [path/to/your/keystore] -file [path/to/your_keystore]
Do everything right? Then pat yourself on the back - you are now the proud owner of a functional, certified keystore.
Now that we have a functional keystore populated with valid certificates, it's time to configure Tomcat to use SSL. First, we'll configure Tomcat's SSL connectors, and then we'll specify which webapps we want to use SSL by default.
Step 1 - Configuring Tomcat's SSL Connectors
Tomcat's global Connector options are configured in Tomcat's main configuration file, "$CATALINA_BASE/conf/server.xml", so you should open this file now. The Connectors we are looking for connect on port 8443 by default, so search for this port, until you come across an entry that looks like this:
<!-- Define a SSL HTTP/1.1 Connector on port 8443
This connector uses the JSSE configuration, when using APR, the
connector should be using the OpenSSL style configuration
described in the APR documentation -->
<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true"
You'll notice that the comment enclosing this connector talks about a choice between APR and JSSE configurations. This refers to the implementation of SSL you are intending to use. JSSE, which is Tomcat's default configuration, is supported by default, and included in all JDKs after version 1.4. So if you don't even know what APR is, you only need to uncomment this entry, and add some additional information to allow Tomcat to find your keystore:
<Connector port="8443" maxThreads="150" scheme="https" secure="true" SSLEnabled="true" keystoreFile="path/to/your/keystore" keystorePass="YourKeystorePassword" clientAuth="false" keyAlias="yourAlias" sslProtocol="TLS"/>
If, on the other hand, you know that using the Apache Portable Runtime (APR), also known as Tomcat's "native library," is by far the best practice to follow, especially when using Tomcat as a standalone web server (which you probably are), and have already installed it on your server, then you'll need to alter this entry as follows to allow Tomcat to use APR's OpenSSL implementation in place of JSSE, or trying to use SSL will generate an error:
<Connector port="8443" scheme="https" secure="true" SSLEnabled="true" SSLCertificateFile="/path/to/your/certificate.crt" SSLCertificateKeyFile="/path/to/your/keyfile" SSLPassword="YourKeystorePassword" SSLCertificateChainFile="path/to/your/root/certificate" keyAlias="yourAlias" SSLProtocol="TLSv1"/>
Notice that if you are using APR, the "SSLCertificateFile" and "SSLCertificateKey"-type attributes are used in place of the keystoreFile attribute. For more information on the differences between using APR in place of JSSE, consult Apache's Tomcat APR Documentation.
Restart Tomcat. Once you're up and running again, test your configuration by connecting to a secure page, using a URL such as https://[yourhost]:8443. If you followed the directions correctly, you should be able to view the page over a secure HTTPS connection!
Step 2 - Limiting SSL Usage
Enabling SSL in Tomcat's server.xml file causes all files to be run both as secure and insecure pages, which can cause unnecessary server load. You can choose which applications offer SSL connections on a per-application basis by adding the following <security-constraint> element to the application's WEB-INF/web.xml file:
This configuration allows you to set SSL options for all an application's pages in one place. For example, to disable SSL for all your application's pages, change "CONFIDENTIAL" to "NONE".
In the interest of simplicity, this guide does not cover all of the elements of SSL configuration (although they are covered extensively in Apache's Tomcat SSL Documentation). We will, however, provide you with a short list of other options and important areas of note to consider as you tweak your SSL configuration.
If you have configured connectors for both APR and JSSE, Tomcat will use APR by default if you have installed the native libraries. You can force it to use JSSE by modifying a Connector's "protocol" attribute as follows:
If you want to force APR, you can do so with a similar edit:
Common Errors Caused By Aliases and Passwords
If you encounter any errors with your SSL configuration, make sure that you have correctly entered settings such as keystore passwords and aliases. These values are case sensitive for some of the supported keystore formats.