9.6. Configuring SSL/HTTPS

This section discusses configuring Geronimo to support HTTPS access to web applications. (Currently secure access to EJBs is not supported.) There are three parts to configuring SSL:

  1. Preparing a keystore with the server certificate, server key, and optionally the CA certificate.

  2. Configuring a HTTPS connector for Jetty (the web application container)

  3. Deploying and starting the HTTPS connector for Jetty

The following sections cover these steps in detail.

9.6.1. Keystore Configuration

In order to enable HTTPS, Geronimo requires a keystore. There are two restrictions on the keystore:

  • It should contain only one private key, with a matching certificate

  • If client certs are enabled, and you choose not to trust the standard set of certificate authorities, all CA certificates in the keystore will be trusted

Generally, this means that the keystore should contain only Geronimo server information.

There are three possible approaches to server certificates:

  1. Use a self-signed certificate for testing

  2. Use a certificate signed by an internal certificate authority

  3. Use a certificate signed by a public certificate authority

The last two cases are identical so far as the keystore is concerned, so the following sections will cover preparing a self-signed test certificate, preparing a certificate signed by a certificate authority, and importing CA certificates.

[Note]Note

The procedures described here use the keytool tool included with the JDK.

9.6.1.1. Preparing a Keystore with a Self-Signed Test Certificate

This is the easiest case, as you can do everything in one step:

  • Create a new keystore

  • Create a private key in the keystore

  • Create a self-signed certificate in the keystore that matches the private key

The command looks like this:

keytool -genkey -alias geronimokey -keyalg RSA -validity 365 \
        -keystore ssl-keystore

The arguments are:

-genkey

Indicates that we're generating a new key

-alias

The name to store the new key under. This is not terribly important as Geronimo will pick the only private key out of the keystore, but you'll need to use this if you want to inspect or alter the key using keytool.

-keyalg

The key algorithm, which may be DSA or RSA. RSA is preferred.

-validity

The number of days the key should be valid for

-keystore

The file name to save the keystore to (or the name of an existing keystore, to update an existing one)

When you run this command, you'll be prompted for:

  1. A password for the keystore (a new password for a new keystore, or the existing password for an existing keystore)

  2. Your first and last name. Important: you should actually enter the host name for the server here.

  3. Your organizational unit, such as a department within your company

  4. Your company

  5. A city

  6. A country code

  7. A password for the private key, which may be the same as or different than the password for the keystore.

When the command finishes, they keystore has been created with the private key and self-signed certificate. If you're not planning to use client certs, or if the standard certificate authorities are sufficient, you can skip ahead to Section 9.6.2, “HTTPS Connector Configuration”.

9.6.1.2. Preparing a Keystore with a Certificate Signed by a Certificate Authority

This case has three steps:

  1. Create a new key and keystore using a procedure just like in the previous section.

  2. Generate a certificate signing request (CSR) and have the certificate authority generate a signed certificate for you.

  3. Import the certificate authority's response into the keystore.

To generate a key, use the same command described in the previous section:

keytool -genkey -alias geronimokey -keyalg RSA -validity 365 \
        -keystore ssl-keystore

In this case, the alias is important as we'll need it for the next two steps.

To generate a CSR, use a command like this:

keytool -certreq -alias geronimokey -file geronimo.csr \
        -keystore ssl-keystore

The arguments are:

-certreq

Indicates that we're generating a CSR

-alias

The alias of the private key, which should be the same as what you specified in the first command when you created the key

-file

The output file to write the CSR to

-keystore

The keystore file, which should be the same as what you specified in the first command.

When you run this command, you'll be prompted for the keystore password, and the private key password. The tool will then write the CSR to the specified file.

You should send the CSR to the certificate authority, and they should sign it and return a new certificate for the Geronimo server key. That process is outside of the scope of this book.

When you receive the CA response, make sure it is in PEM format (plain text, not binary) and copy it to the same location as the keystore.

If the CA is not one of the standard certificate authorities present in the common JDK CA cert file, you'll also need a copy of the CA certificate. Import that CA cert into the keystore with a command like this:

keytool -import -trustcacerts -file ca-cert.pem -alias MyCA \
        -keystore ssl-keystore

The arguments here are:

-import

Indicates that you're importing a certificate

-trustcacerts

Indicates that the certificate should be imported as a trusted CA cert. The CA cert must be trusted in order to successfully import a certificate signed by that CA.

-file

The file containing the CA certificate.

-alias

The name to store this CA under in the keystore. You can choose this freely, so long as it does not conflict with the private key alias.

-keystore

The keystore file, which should be the same as you've been using all along

You'll be prompted for the keystore password, and for whether you really want to trust the certificate you're importing.

Then use a command like this to import the certificate signed by the CA into the keystore:

keytool -import -file geronimo.pem -alias geronimokey \
        -keystore teststore

The arguments here are:

-import

Indicates that you're importing a certificate

-file

The file containing the CA response (a signed copy of your server certificate)

-alias

The name of the private key in the keystore.

-keystore

The keystore file, which should be the same as you've been using all along

You'll be prompted for the keystore password and the private key password.

Once this command completes, the keystore should contain a private key, a server certificate signed by a CA, and if it is not a standard CA, a copy of the certificate identifying the CA.

9.6.1.3. Loading CA Certificates into the Keystore

If any additional certificate authorities should be trusted, particularly trusted to sign client certs for clients connecting to the server, you should import their CA certificates using a command like this:

keytool -import -trustcacerts -file ca-cert.pem -alias SomeCA \
        -keystore ssl-keystore

The arguments here are:

-import

Indicates that you're importing a certificate

-trustcacerts

Indicates that the certificate should be imported as a trusted CA cert. The CA cert must be trusted in order to successfully import a certificate signed by that CA.

-file

The file containing the CA certificate.

-alias

The name to store this CA under in the keystore. You can choose this freely, so long as it does not conflict with any other entries in the keystore.

-keystore

The keystore file, which should be the same as you've been using all along

For each CA cert you import, you'll be prompted for the keystore password, and for whether you really want to trust the certificate you're importing.

9.6.2. HTTPS Connector Configuration

Now that the keystore is configured, you need to configure the server to listen for incoming HTTPS requests and use the key and certificate in the keystore.

In Geronimo, you need to explicitly configure the pathways used by browsers attempting to connect to the web container. In the case of Jetty, the default web container, these pathways are knows as connectors. The standard configuration includes a Jetty connector supporting HTTP on port 8080, as well as a HTTPS connector on port 8443. This section discusses configuring a custom connector supporting HTTPS, on a different port.

[Note]Note

Milestone 5 allows you to add, remove, and edit connectors (including HTTPS settings) through the web console, which is much easier than using the deployment plans described in this section. The console also supports both Tomcat and Jetty with the same interface.

Each Jetty connector is a GBean, so the process of configuring a Jetty connector involves configuring a GBean. The standard GBean deployment information for a Jetty HTTPS connector looks like this:

Example 9.10. Jetty HTTPS Connector Configuration

<gbean name="MyJettySSLConnector"
      class="org.apache.geronimo.jetty.connector.HTTPSConnector">
  <attribute name="port">8443</attribute>
  <attribute name="keystoreFileName">
    var/security/keystore
  </attribute>
  <attribute name="keystoreType">JKS</attribute>
  <attribute name="keystorePassword">secret</attribute>
  <attribute name="keyPassword">secret</attribute>
  <attribute name="clientAuthRequired">false</attribute>
  <attribute name="secureProtocol">TLS</attribute>
  <attribute name="maxThreads">50</attribute>
  <attribute name="minThreads">10</attribute>
  <reference name="JettyContainer">
    <module>geronimo/jetty/1.0/car</module>
    <name>JettyWebContainer</name>
  </reference>
  <reference name="ServerInfo">
    <module>geronimo/j2ee-system/1.0/car</module>
    <name>ServerInfo</name>
  </reference>
</gbean>

The GBean name should be adjusted to be unique, and the class should always appear exactly as above.

The configuration attributes and references for the HTTPS connector are:

port

The port that the HTTPS connector should listen on. The standard HTTPS port is 443, but in order for Geronimo to bind to port 443, it must be run with administrative privileges (which means as root, on a UNIX OS).

keystoreFileName

The path to the keystore configured in Section 9.6.1, “Keystore Configuration”. This should be relative to the Geronimo installation directory.

keystoreType

An optional attribute specifying the keystore type. For the procedure above to work, this should be left out or set to JKS.

keystorePassword

The password for the keystore itself, if any.

keyPassword

The password for the private key within the keystore, if any. Note that for maximum compatibility with Tomcat, the keyPassword and keystorePassword should be the same.

clientAuthRequired

If set to true, the clients must have a valid client certificate in order to connect. If set to false, any client can connect. The connection will still be secure in either case; it's only a question of whether the server can trust the clients.

secureProtocol

The variety of the SSL protocol to use. Normally this should be omitted or set to TLS, though certain JDKs (mainly from IBM) require a value of SSL to work correctly.

minThreads

The lower bound on the thread pool used to service connections coming in to this connector.

maxThreads

The upper bound on the thread pool used to service connections coming in to this connector.

JettyContainer

A reference to the master web container. This should normally appear exactly as shown in the example.

ServerInfo

A reference to the basic server information repository, used to locate files on the file system. This should normally appear exactly as shown in the example.

9.6.3. HTTPS Connector Deployment

HTTPS Connector GBeans are generally deployed as server-wide services.

[Note]Note

Technically, the GBean could be deployed with an application or module. However, it is not possible to configure a connector that only allows access to a single application or web module. Therefore an application-scoped deployment doesn't usually make sense -- while that application was running HTTPS access would be open for all web applications running in Geronimo, and when that application was stopped then HTTPS access would be disabled for all web applications.

The deployment plan for an HTTPS connector typically looks like this:

Example 9.11. Jetty HTTPS Connector Deployment Plan

ssl-plan.xml

<configuration
    xmlns="http://geronimo.apache.org/xml/ns/deployment"
    configId="SSL"
    parentId="geronimo/jetty/1.0/car">
  <!-- HTTPS Connector GBean goes here -->
</configuration>

The parentId for the HTTPS Connector should always be geronimo/jetty/1.0/car, since that is the configuration that deploys the main Jetty container. To complete this deployment plan, you should insert the gbean configuration information from Section 9.6.2, “HTTPS Connector Configuration” into the configuration element here.

Once the deployment plan has been saved, you can deploy it with a command like this:

java -jar bin/deployer.jar deploy ssl-plan.xml

That will install the configuration into the server and start it (assuming the server is running). Jetty will immediately begin listening for HTTPS connections on the designated port.

For testing purposes, you may also want to start the console (if it's not already running):

java -jar bin/deployer.jar start \
              geronimo/webconsole-jetty/1.0/car

Then you can visit the console in your browser using a URL like https://localhost:8443/console/

When you try this, you may run into a few issues:

  • If port 8443 doesn't work, you should use whichever port you configured in the HTTPS connector configuration

  • If you have not added the certificate authority that signed the server certificate to your browser, or if it's a self-signed test certificate, you may get a prompt that the signer is not trusted, asking you whether to accept the certificate for this session or permanently.

  • If you generated the certificate for a host name other than localhost, your browser may prompt you with a note that you're trying to connect to localhost but the certificate is for a different host name