Information

  • To store a Let's Encrypt certificate in Tomcat, the certificate must be imported in the Tomcat Keystore.

Procedure

Manually

Procedure

  • 1. Stop Tomcat service
  • 2. Generate/update Let's Encrypt certificate via certbot certonly --standalone -d [hostname].
    • To do so, the server must be accessible via internet and the ports 80 and 443 must not be occupied.
  • 3. Switch to the directory of the newly created certificate files (Standard: /etc/letsencrypt/live/[hostname])
  • 4. Create a temporary keystore file with the following command: openssl pkcs12 -export -in "fullchain.pem" -inkey "privkey.pem" -out "/tmp/keystorefile" -name tomcat -CAfile "chain.pem" -caname root -passout pass:changeit
  • 5. Delete the old Tomcat keystore (Standard: /var/lib/tomcat/cert/[hostname].pkcs12).
  • 6. Switch to the directory of the newly created keystore files.
  • 7. Import them to the Tomcat keystore using the following commands: keytool -importkeystore -deststorepass changeit -destkeypass changeit -destkeystore "/var/lib/tomcat/cert/[hostname].pkcs12" -srckeystore "/tmp/keystorefile" -srcstoretype PKCS12 -srcstorepass changeit -alias tomcat

The /usr/share/tomcat/conf/server.xml configuration file must possibly be adapted in order for it to refer to the correct keystore file:

<Connector port="443" protocol="org.apache.coyote.http11.Http11NioProtocol"
                  maxThreads="150" SSLEnabled="true"
                  scheme="https" secure="true"
                  SSLProtocol="TLSv1.2"
                  keystoreFile="/var/lib/tomcat/cert/[hostname].pkcs12" keystorePass="changeit"
                  clientAuth="false"
                  />
CODE
  • 8. Delete temporary keystore file
  • 9. Start Tomcat service

Automatically

A bash script for this may, e.g., look as follows:

#!/usr/bin/env bash

set -o nounset

# Verzeichnis der Let's Encrypt Zertifikate
DIR=/path/to/cert-files
# Verzeichnis zum Zwischenspeichern der Keystore-File
TEMPDIR=/tmp
# Verzeichnis des Tomcat Keystores
KEY=/path/to/tomcat-keystore
# Log File
LOG=renew.log
# Zusätzliches Log File mit der Ausgabe vom certbot
TEMP_LOG=temp_renew.log

{
    echo "----------------------------------$(date)----------------------------------"
    
    echo "Stopping Tomcat.."
    systemctl stop tomcat.service
    
    echo "Renewing Certificates.."
    certbot certonly -n --standalone -d [hostname] |& tee "${TEMP_LOG}"
    
    if grep -q Congratulations "${TEMP_LOG}"; then
    
        echo "Changing Directory to ${DIR}"
        pushd "${DIR}" > /dev/null
            echo "Creating new Keystore.."
            openssl pkcs12 -export -in "fullchain.pem" -inkey "privkey.pem" -out "${TEMPDIR}/keystorefile" -name tomcat -CAfile "chain.pem" -caname root -passout pass:changeit
        popd > /dev/null
        
        if [ -f "${KEY}" ]; then
            echo "Keystore ${KEY} already exists. Deleting.."
            rm "${KEY}"
        fi
        
        echo "Changing Directory to ${TEMPDIR}"
        pushd "${TEMPDIR}" > /dev/null
            echo "Importing new Keystore into Tomcat.."
            keytool -importkeystore -deststorepass changeit -destkeypass changeit -destkeystore "${KEY}" -srckeystore "${TEMPDIR}/keystorefile" -srcstoretype PKCS12 -srcstorepass changeit -alias tomcat
        popd > /dev/null
        
        echo "Cleanup.."
        rm "${TEMPDIR}/keystorefile"
        
    fi
    
    echo "Starting Tomcat.."
    systemctl start tomcat.service
    
    echo "----------------------------------$(date)----------------------------------"
    
} |& tee -a "${LOG}"
BASH