The Jakarta Project The mighty Tomcat - Meow!

Tomcat SSL Configuration

Authors:

Henri Gomez <hgomez@slib.fr>
Christopher Cain   <ccain@apache.org>


Table of Contents


Introduction to SSL

SSL, or Secure Sockets Layer, is a technology which allows web browsers and web servers to communicate over a secured connection. This means that the data being sent is encrypted by one side, transmitted, then decrypted by the other side prior to any processing. This is a two-way process, meaning that both the server and the browser encrypt all traffic before sending out data.

Another important aspect of the SSL protocol is Authentication. This means that during your initial attempt to communicate with a web server over a secure connection, that server will present your web browser with a set of credentials, in the form of a Certificate, as proof that the site is who and what it claims to be. In certain cases, the server may also request a certificate from your web browser, asking for proof that you are who you claim to be. This is known as Client Authentication, although in practice it is used primarily for business-to-business (B2B) transactions rather than with typical site users. Most SSL-enabled web servers do not request Client Authentication.


Tomcat and SSL

It is important to note that configuring Tomcat to take advantage of secure sockets is usually only necessary when running it as a standalone web server. When running Tomcat primarily as a Servlet/JSP container behind another web server, such as Apache or Microsoft IIS, it is usually necessary to configure the primary web server to handle the SSL connections from users. Typically, this server will negotiate all SSL-related functionality, then pass on any requests destined for the Tomcat container only after decrypting those requests. Likewise, Tomcat will return cleartext responses, which will then be encrypted by the primary server before being returned to the user's browser. In this environment, Tomcat knows that communications between the primary web server and the client are taking place over a secure connection (because your application needs to be able to ask about this), but it does not participate in the encryption or decryption itself.

Information on configuring Apache for SSL can be found at either the Apache-SSL pages, or the apache-mod_ssl project. For information on configuring Tomcat to communicate with an SSL-enabled Apache server, see the Tomcat with Apache and mod_jk section.

Note: SSL with Tomcat standalone requires JDK 1.2 or greater.


Certificates

In order to implement SSL, a web server must have an associated certificate for each external interface (IP address) that accepts secure connections. The theory behind certificates is that a server should provide some kind of reasonable assurance that its owner is who you think it is, particularly before receiving any sensitive information. While a broader explanation of certificates is beyond the scope of this document, think of a certificate as a digital "driver's license" for an Internet address. It states what company a site is associated with, along with some basic contact information about the site's owner and/or administrator.

This "driver's license" is cryptographically signed by its owner, and is therefore extremely difficult for anyone else to forge. For sites involved in e-commerce, or any other business transaction in which authentication of identity is important, a certificate is typically purchased from a well-known Certificate Authority (CA) such as VeriSign or Thawte. Such certificates can be electronically verified --- in effect, the CA will vouch for the authenticity of the certificates that it grants, so you can, ostensibly, trust that a given certificate is valid if you trust the CA who granted it.

In many cases, however, authentication is not really a concern. An administrator may simply want to ensure that the data being transmitted and received by the server is private and cannot be snooped by anyone who may be eavesdropping on the connection. Fortunately, Java provides a relatively simple command-line tool, called keytool, which can easily create a "self-signed" certificate. Self-signed certificates are simply user-generated certificates which have not been officially registered with any well-known CA and are therefore not really guaranteed to be authentic at all. The owner of the certificate is essentially vouching for himself/herself. Again, this may or may not even be important, depending on your needs.


Building Tomcat with SSL support

If you want to build Tomcat with support for SSL, be careful of your classpath. I usually clear the CLASSPATH environment variable in order to avoid possible conflicts in jars. A common case of conflict is for XML parsers (xerces & jaxp). Tomcat required a recent XML parser, such as Apache Group's Xerces or Sun's JAXP.

At build time (via Ant), Tomcat will check for some libs and will then included more or less options. This is the case with SSL support. If you have the JSSE jars in your CLASSPATH, Tomcat will be built with SSL (SSLSocketFactory). Tomcat will use the JSSE jars (jcert.jar, jsse.jar, jnet.jar). This software cannot be included in Tomcat, due in large part to certain legal restrictions on the distribution of cryptographic software. You'll have to go to the JSSE home page and download from there the domestic (US/Canada) or global archive. You should then make these jars available to Tomcat during the build process by following the relevant build instructions for your version of Tomcat (see the build instructions in your top-level Tomcat directory for details).


Tomcat with Apache and mod_jk

If you use Apache with SSL (apache-ssl or apache-mod_ssl), the Apache connector mod_jk will be able to forward Tomcat SSL information if the JkExtractSSL directive is present in your httpd.conf.

Forwarded SSL Information is:
 
HTTPS Apache Redirect to Tomcat from an SSL Area
SSL_SESSION_ID SSL session ID
SSL_CIPHER SSL CIPHER used
SSL_CLIENT_CERT SSL Certificate of client

Since apache-ssl and apache-mod_ssl use different environment variables, you can adapt SSL variables via the following JK vars:

Here is an example of some directives to include in httpd.conf for use with mod_ssl:

# Should mod_jk send SSL information to Tomcat (default is On)
JkExtractSSL On
# What is the indicator for SSL (default is HTTPS)
JkHTTPSIndicator HTTPS
# What is the indicator for SSL session (default is SSL_SESSION_ID)
JkSESSIONIndicator SSL_SESSION_ID
# What is the indicator for client SSL cipher suit (default is SSL_CIPHER)
JkCIPHERIndicator SSL_CIPHER
# What is the indicator for the client SSL certificated (default is SSL_CLIENT_CERT)
JkCERTSIndicator SSL_CLIENT_CERT

When using mod_jk with Apache & mod_ssl, it is essential to specify "SSLOptions +StdEnvVars +ExportCertData" in the httpd.conf file.
Otherwise, mod_ssl will not produce the neccessary environment variables for mod_jk. (Tilo Christ <tilo.christ@med.siemens.de>).

Warning, even though mod_jk supports both ajp12 (an old version from ApacheJServ) and ajp13, only ajp13 can forward SSL information to Tomcat.


SSL via Apache

mod_jk supports the VirtualHost directive of Apache. This is especially useful when using Apache mod_ssl with Tomcat.
The following configuration will easily secure your webapps via Apache SSL support (be careful when setting these jk variables outside VirtualHost directives):

JkWorkersFile /etc/httpd/conf/workers.properties
JkLogFile /var/log/httpd/mod_jk.log
JkLogLevel warn

The jk redirect stuff can be set in virtual hosts: 

<VirtualHost _default_:443>
SSLEngine on
SSLCipherSuite ALL:!ADH:!EXP56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL

# other SSL stuff

Alias /alesia "/var/tomcat/webapps/alesia" 
<Directory "/var/tomcat/webapps/alesia">

Options Indexes FollowSymLinks 
</Directory>

JkMount /alesia/servlet/* ajp13
JkMount /alesia/*.jsp ajp13 

<Location "/alesia/WEB-INF/">
AllowOverride None
Deny from all
</Location>

</VirtualHost>


SSL Standalone

In order to configure Tomcat standalone for SSL support, you need to create (or import) an SSL certificate. For more information about SSL and certificates, you might find the following resources helpful:

1. Download and Install JSSE

Download the Java Secure Socket Extensions (JSSE) package, version 1.0.2 or later, from http://java.sun.com/products/jsse/ . If you are running JDK 1.4 (currently in beta), these classes have been integrated directly into the JDK, so you can skip this entire step.

After expanding the package, there are two ways to make it available to Tomcat (choose one or the other):
Note: The system classpath is effectively ignored by Tomcat, so including the JSSE jars there will not make them available for use by the Tomcat engine during runtime (although it will not conflict with the two methods described above if they do happen to be in the system classpath). Also, do not copy these jars into any of the internal Tomcat repositories (the $TOMCAT_HOME/lib/* directories, individual webapp directories, etc.). Doing so may cause Tomcat to fail, as these libraries should only be loaded by the system classloader.

2. Prepare the Certificate Keystore

Note: In order to execute the keytool command-line utility, the JSSE jars must be either in the classpath or an installed extension.

A "keystore" is essentially just a repository file for cryptographic objects, such as keys and certificates. Tomcat currently operates only on JKS format keystores. This is Java's standard "Java KeyStore" format, and is the format created by the keytool command-line utility. This tool is included in the JDK.

To create a new keystore from scratch, containing a single self-signed certificate, execute the following from a terminal command line:

%JAVA_HOME%\bin\keytool -genkey -alias tomcat -keyalg RSA (Windows)
$JAVA_HOME/bin/keytool -genkey -alias tomcat -keyalg RSA (Unix)

(The RSA algorithm should be preferred as a secure algorithm, and also to ensure general compatibility with other servers and components such as Netscape and IIS.)

This command will create a new file, in the home directory of the user under which you run it, named ".keystore". To specify a different location or filename, add the -keystore parameter, followed by the complete pathname to your keystore file, to the keytool command shown above. For example:

%JAVA_HOME%\bin\keytool -genkey -alias tomcat -keyalg RSA \ -keystore /path/to/my/keystore (Windows)
$JAVA_HOME/bin/keytool -genkey -alias tomcat -keyalg RSA \ -keystore /path/to/my/keystore (Unix)

After executing the keytool command, you will first be prompted for the keystore password. The default password used by Tomcat is "changeit" (all lower case), although you can specify a custom password if you like. Again, this will need to be reflected in the server.xml configuration file.

[root@www.vercingetorix.org /root]# $JAVA_HOME/bin/keytool -genkey -alias tomcat -keyalg RSA
Enter keystore password:  changeit
What is your first and last name?
  [Unknown]:  www.vercingetorix.org
What is the name of your organizational unit?
  [Unknown]:  Chief
What is the name of your organization?
  [Unknown]:  Gaulois
What is the name of your City or Locality?
  [Unknown]:  Alesia
What is the name of your State or Province?
  [Unknown]:  50
What is the two-letter country code for this unit?
  [Unknown]:  FR
Is <CN=www.vercingetorix.org, OU=Chief, O=Gaulois, L=Alesia, ST=50, C=FR> correct?
  [no]:  yes

Finally, you will be prompted for the key password, which is the password specifically for this Certificate (as opposed to any other Certificates stored in the same keystore file). You MUST use the same password here as was used for the keystore password itself. (Currently, pressing the ENTER at this prompt will automatically do this.)

To import an existing certificate into a JKS keystore:

It is possible to import certificates generated with OpenSSL. Here are the steps needed to generate such certs with OpenSSL : For more information, please read the documentation (in your JDK documentation package) about keytool.

3. Edit the Tomcat configuration file

To configure a secure (SSL) HTTP connector for Tomcat, verify that it is activated in the $TOMCAT_HOME/conf/server.xml file (the standard version of this file, as shipped with Tomcat, contains a simple example which is commented-out by default).

Syntax for Tomcat 3.2 :

<Connector className="org.apache.tomcat.service.PoolTcpConnector">
<Parameter name="handler" value="org.apache.tomcat.service.http.HttpConnectionHandler"/>
<Parameter name="port" value="8443"/>
<Parameter name="socketFactory" value="org.apache.tomcat.net.SSLSocketFactory" />
<Parameter name="keystore" value="/var/tomcat/conf/keystore" />
<Parameter name="keypass" value="mynewpass"/>
<Parameter name="clientAuth" value="false"/>
</Connector>

Syntax for Tomcat 3.3 :

<Http10Connector
  port="8443"
  secure="true"
  keystore="/var/tomcat/conf/keystore"
  keypass="mynewpass"
  clientAuth="false" />

In the above examples, we indicate that the keystore is file located at /var/tomcat/conf/keystore, and the password if "mynewpass". Again, these attributes can be skipped if the Tomcat defaults were used. Also, we specified that we don't want to enforce client authentication.


General Tips on Running SSL

The first time a user attempts to access a secured page on your site, he or she is typically presented with a dialog containing the details of the certificate (such as the company and contact name), and asked if he or she wishes to accept the certificate as valid and continue with the transaction. Some browsers will provide an option for permanently accepting a given certificate as valid, in which case the user will not be bothered with a prompt each time they visit your site. Other browsers do not provide this option. Once approved by the user, a certificate will be considered valid for at least the entire browser session.

Also, while the SSL protocol was designed to be as efficient as securely possible, encryption/decryption is a computationally expensive process from a performance standpoint. It is not strictly necessary to run an entire web application over SSL, and indeed a developer can pick and choose which pages require a secure connection and which do not. For a reasonably busy site, it is customary to only run certain pages under SSL, namely those pages where sensitive information could possibly be exchanged. This would include things like login pages, personal information pages, and shopping cart checkouts, where credit card information could possibly be transmitted. Any page within an application can be requested over a secure socket by simply prefixing the address with https: instead of http:. Any pages which absolutely require a secure connection should check the protocol type associated with the page request and take the appropriate action if the https protocol is not specified.


Troubleshooting SSL Standalone

Here is a list of common problems that you may encounter when setting up Tomcat standalone for SSL, and what to do about them.

If you are still having problems, a good source of information is the TOMCAT-USER mailing list. You can find pointers to archives of previous messages on this list, as well as subscription and unsubscription information, at http://jakarta.apache.org/site/mail.html.



Credits

This document was written by Henri Gomez and Christopher Cain. Thanks to both Tilo Christ <tilo.christ@med.siemens.de> and hgopal@cmcltd.com for additional contributions.


 
Copyright ©1999-2001 The Apache Software Foundation


Legal Stuff They Make Us Say
Contact Information