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:
Preparing a keystore with the server certificate, server key, and optionally the CA certificate.
Configuring a HTTPS connector for Jetty (the web application container)
Deploying and starting the HTTPS connector for Jetty
The following sections cover these steps in detail.
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:
Use a self-signed certificate for testing
Use a certificate signed by an internal certificate authority
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 | |
---|---|
The procedures described here use the keytool tool included with the JDK. |
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:
Indicates that we're generating a new key
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.
The key algorithm, which may be DSA or RSA. RSA is preferred.
The number of days the key should be valid for
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:
A password for the keystore (a new password for a new keystore, or the existing password for an existing keystore)
Your first and last name. Important: you should actually enter the host name for the server here.
Your organizational unit, such as a department within your company
Your company
A city
A country code
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”.
This case has three steps:
Create a new key and keystore using a procedure just like in the previous section.
Generate a certificate signing request (CSR) and have the certificate authority generate a signed certificate for you.
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:
Indicates that we're generating a CSR
The alias of the private key, which should be the same as what you specified in the first command when you created the key
The output file to write the CSR to
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:
Indicates that you're importing a certificate
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.
The file containing the CA certificate.
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.
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:
Indicates that you're importing a certificate
The file containing the CA response (a signed copy of your server certificate)
The name of the private key in the 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.
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:
Indicates that you're importing a certificate
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.
The file containing the CA certificate.
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.
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.
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 | |
---|---|
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:
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).
The path to the keystore configured in Section 9.6.1, “Keystore Configuration”. This should be relative to the Geronimo installation directory.
An optional attribute specifying the keystore type. For the procedure above to work, this should be left out or set to JKS.
The password for the keystore itself, if any.
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.
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.
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.
The lower bound on the thread pool used to service connections coming in to this connector.
The upper bound on the thread pool used to service connections coming in to this connector.
A reference to the master web container. This should normally appear exactly as shown in the example.
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.
HTTPS Connector GBeans are generally deployed as server-wide services.
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