Skip to main content

[Humbledown highlights] Generating Tomcat Keystore from Key, Cert, and CA Bundle

Originally published by myself on humbledown.org at Sun Jun 12 06:05:32 NZST 2011
and since recovered to this location. It has not been tested since its original publication.

I had to configure a new Tomcat installation yesterday with for SSL. The server also has an Apache (httpd) installation, and the SSL certificate was generated using the OpenSSL command (umask 077; cd /etc/pki/tls/private; openssl req -nodes -newkey rsa:2048 -keyout servername.key -out servername.csr. This generates the private key and a certificate signing request, which gets sent to the Certificate Authority (CA). The response from the CA includes a servername.crt and servername.ca-bundle, which contains a list of PEM-encoded x509 certificates, that are used in establishing the chain of trust from your certificate to a root certificate.

That process works completely fine fine for the httpd server, but Tomcat expects its key to be generated using the keytool command, and the resulting certificate and CA bundle to be imported using keytool. Tomcat (or rather, the Java Security libraries) also default to using the Java Key Store (JKS) format. This is annoying, because it means the keystore will not include the private key (which you generated using openssl req ....

Although you can still combine them together into a JKS keystore, it does require that you compile and use a small Java utility from the agentbob website. However, I prefer not to use third-party utilities to maintain a JKS keystore when the Tomcat and OpenSSL can maintain a PKCS#12 formatted keystore.

Here is a script that will take a PEM-encoded SSL private key foo.key, certificate foo.crt and CA chain foo.ca-bundle files [NOTE BIG ASSUMPTION -- this is a site-local convention], and combine them into a PKCS#12-formatted keystore that can be used with Tomcat. It expects, though doesn't require, that the (private) key is under /etc/pki/tls/private/, and the crt and ca-bundle files are under /etc/pki/tls/certs/

File: generate-tomcat-keystore-pkcs12

#!/bin/bash

# Why a regex? Globs are painful to expand
#
newest_file_in_dir_matching_regex()
{
    local dir="$1"
    local regex="$2"

    echo "$dir/$(ls -t "$dir" | egrep "$regex" | head -1)"
}

read_with_default()
{
    local prompt="$1"
    local default="$2"

    local response=""
    read -e -p "$prompt [$default]: " response

    if [ -z "$response" ]; then
        response="$default"
    fi

    echo "$response"
}

friendly_name='tomcat'

keystore_filename=$(read_with_default 'New keystore filename' \
        '/etc/tomcat5/tomcat.keystore.pkcs12')

key_filename=$(read_with_default 'Private key filename' \
        $(newest_file_in_dir_matching_regex /etc/pki/tls/private '\.key$'))

cert_filename=$(read_with_default 'Certificate filename' \
        $(newest_file_in_dir_matching_regex /etc/pki/tls/certs '\.crt$'))

cabundle_filename=$(read_with_default 'CA Bundle filename' \
        $(newest_file_in_dir_matching_regex /etc/pki/tls/certs '\.ca-bundle$'))

cat "$key_filename" "$cert_filename" "$cabundle_filename" | \
openssl pkcs12 -export -nodes \
        -name      "$friendly_name" \
        -out       "$keystore_filename"

echo "Now you can configure Tomcat with the following connector:"
echo ""
echo "    "
echo "    "

Don't forget to mark it executable, and to backup any old keystore before running this.

Comments

Popular posts from this blog

ORA-12170: TNS:Connect timeout — resolved

If you're dealing with Oracle clients, you may be familiar with the error message
ERROR ORA-12170: TNS:Connect timed out occurred I was recently asked to investigate such a problem where an application server was having trouble talking to a database server. This issue was blocking progress on a number of projects in our development environment, and our developers' agile post-it note progress note board had a red post-it saying 'Waiting for Cameron', so I thought I should promote it to the front of my rather long list of things I needed to do... it probably also helped that the problem domain was rather interesting to me, and so it ended being a late-night productivity session where I wasn't interrupted and my experimentation wouldn't disrupt others. I think my colleagues are still getting used to seeing email from me at the wee hours of the morning.

This can masquerade as a number of other error strings as well. Here's what you might see in the sqlnet.log f…

Getting MySQL server to run with SSL

I needed to get an old version of MySQL server running with SSL. Thankfully, that support has been there for a long time, although on my previous try I found it rather frustrating and gave it over for some other job that needed doing.

If securing client connections to a database server is a non-negotiable requirement, I would suggest that MySQL is perhaps a poor-fit and other options, such as PostgreSQL -- according to common web-consensus and my interactions with developers would suggest -- should be first considered. While MySQL can do SSL connections, it does so in a rather poor way that leaves much to be desired.

UPDATED 2014-04-28 for MySQL 5.0 (on ancient Debian Etch).

Here is the fast guide to getting SSL on MySQL server. I'm doing this on a Debian 7 ("Wheezy") server. To complete things, I'll test connectivity from a 5.1 client as well as a reasonably up-to-date MySQL Workbench 5.2 CE, plus a Python 2.6 client; just to see what sort of pain awaits.

UPDATE: 2014-0…

From DNS Packet Capture to analysis in Kibana

UPDATE June 2015: Forget this post, just head for the Beats component for ElasticSearch. Beats is based on PacketBeat (the same people). That said, I haven't used it yet.

If you're trying to get analytics on DNS traffic on a busy or potentially overloaded DNS server, then you really don't want to enable query logging. You'd be better off getting data from a traffic capture. If you're capturing this on the DNS server, ensure the capture file doesn't flood the disk or degrade performance overmuch (here I'm capturing it on a separate partition, and running it at a reduced priority).

# nice tcpdump -p -nn -i eth0 -s0 -w /spare/dns.pcap port domain

Great, so now you've got a lot of packets (set's say at least a million, which is a reasonably short capture). Despite being short, that is still a massive pain to work with in Wireshark, and Wireshark is not the best tool for faceting the message stream so you can can look for patterns (eg. to find relationshi…