Setup Tomcat SSL certificates with Let's Encrypt automation

Intermediate 25 min May 28, 2026 109 views
Ubuntu 24.04 Debian 12 AlmaLinux 9 Rocky Linux 9

Configure Apache Tomcat 11 with automated SSL certificate management using Let's Encrypt and Certbot. Set up HTTPS connector, Java keystore integration, and automatic certificate renewal for production environments.

Prerequisites

  • Domain name pointing to your server
  • Ports 80 and 443 accessible
  • Sudo access
  • At least 2GB RAM

What this solves

This tutorial configures Apache Tomcat 11 with automated SSL certificates from Let's Encrypt using Certbot. You'll set up HTTPS connectivity with Java keystore integration and automatic certificate renewal. This approach provides production-ready SSL termination directly in Tomcat without requiring a reverse proxy.

Prerequisites

You need a domain name pointing to your server and ports 80 and 443 open in your firewall. Ensure you have sudo access and at least 2GB RAM available for Tomcat operations.

Step-by-step installation

Update system packages

Start by updating your package manager to ensure you get the latest security updates and dependencies.

sudo apt update && sudo apt upgrade -y
sudo dnf update -y

Install Java 17 and required packages

Tomcat 11 requires Java 17 or higher. Install OpenJDK 17 along with wget and other required tools for certificate management.

sudo apt install -y openjdk-17-jdk wget curl unzip
sudo dnf install -y java-17-openjdk-devel wget curl unzip

Create Tomcat user

Create a dedicated system user for running Tomcat services. This follows security best practices by avoiding root execution.

sudo useradd -m -U -d /opt/tomcat -s /bin/false tomcat

Download and install Apache Tomcat 11

Download the latest stable Tomcat 11 release and extract it to the system directory.

cd /tmp
wget https://archive.apache.org/dist/tomcat/tomcat-11/v11.0.0/bin/apache-tomcat-11.0.0.tar.gz
sudo tar xf apache-tomcat-11.0.0.tar.gz -C /opt/tomcat --strip-components=1
sudo chown -R tomcat:tomcat /opt/tomcat
sudo chmod +x /opt/tomcat/bin/*.sh

Install Certbot for Let's Encrypt

Install Certbot to handle SSL certificate generation and renewal from Let's Encrypt authority.

sudo apt install -y certbot
sudo dnf install -y certbot

Create systemd service file

Configure Tomcat as a systemd service for automatic startup and service management.

[Unit]
Description=Apache Tomcat Web Application Container
After=network.target

[Service]
Type=forking

Environment=JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64
Environment=CATALINA_PID=/opt/tomcat/temp/tomcat.pid
Environment=CATALINA_HOME=/opt/tomcat
Environment=CATALINA_BASE=/opt/tomcat
Environment='CATALINA_OPTS=-Xms512M -Xmx1024M -server -XX:+UseParallelGC'
Environment='JAVA_OPTS=-Djava.awt.headless=true -Djava.security.egd=file:/dev/./urandom'

ExecStart=/opt/tomcat/bin/startup.sh
ExecStop=/opt/tomcat/bin/shutdown.sh

User=tomcat
Group=tomcat
UMask=0007
RestartSec=10
Restart=always

[Install]
WantedBy=multi-user.target

Start and enable Tomcat

Reload systemd configuration and start Tomcat to verify the basic installation works before adding SSL.

sudo systemctl daemon-reload
sudo systemctl enable --now tomcat
sudo systemctl status tomcat

Generate initial SSL certificate

Use Certbot standalone mode to generate the initial SSL certificate. Replace example.com with your actual domain name.

Important: Stop Tomcat temporarily while Certbot uses port 80 for domain validation.
sudo systemctl stop tomcat
sudo certbot certonly --standalone -d example.com
sudo systemctl start tomcat

Create keystore conversion script

Create a script to convert Let's Encrypt PEM certificates into Java keystore format that Tomcat requires.

#!/bin/bash

Configuration

DOMAIN="example.com" KEYSTORE_PATH="/opt/tomcat/conf/keystore.p12" KEYSTORE_PASSWORD="changeit" CERT_PATH="/etc/letsencrypt/live/${DOMAIN}"

Remove existing keystore

rm -f "$KEYSTORE_PATH"

Convert certificates to PKCS12 format

openssl pkcs12 -export \ -in "${CERT_PATH}/fullchain.pem" \ -inkey "${CERT_PATH}/privkey.pem" \ -out "$KEYSTORE_PATH" \ -name tomcat \ -password "pass:${KEYSTORE_PASSWORD}"

Set proper ownership and permissions

chown tomcat:tomcat "$KEYSTORE_PATH" chmod 600 "$KEYSTORE_PATH" echo "Certificate conversion completed"

Restart Tomcat to load new certificates

systemctl restart tomcat

Make conversion script executable

Set proper permissions on the certificate conversion script for automated execution.

sudo chmod +x /opt/tomcat/bin/convert-certificates.sh
sudo chown root:root /opt/tomcat/bin/convert-certificates.sh

Run initial certificate conversion

Execute the conversion script to create the initial Java keystore from Let's Encrypt certificates.

sudo /opt/tomcat/bin/convert-certificates.sh

Configure Tomcat SSL connector

Edit the Tomcat server configuration to add HTTPS connector with the SSL keystore. This enables SSL termination directly in Tomcat.



  
  
  
  
  

  
    
    
               
    
    

    
      
        
      
    
  

Configure automatic certificate renewal

Create a systemd timer and service for automatic certificate renewal. This ensures SSL certificates stay valid without manual intervention.

[Unit]
Description=Certbot Renewal

[Service]
Type=oneshot
ExecStart=/usr/bin/certbot renew --quiet --deploy-hook "/opt/tomcat/bin/convert-certificates.sh"
User=root

Create renewal timer

Configure the systemd timer to run certificate renewal checks twice daily. Let's Encrypt recommends frequent checks with automatic renewal.

[Unit]
Description=Run certbot twice daily
Requires=certbot-renewal.service

[Timer]
OnCalendar=--* 00,12:00:00
RandomizedDelaySec=3600
Persistent=true

[Install]
WantedBy=timers.target

Enable automatic renewal

Enable and start the systemd timer for automatic certificate renewal monitoring.

sudo systemctl daemon-reload
sudo systemctl enable --now certbot-renewal.timer
sudo systemctl status certbot-renewal.timer

Configure firewall rules

Open the required ports for HTTP and HTTPS traffic. Port 8080 and 8443 are Tomcat's default ports.

sudo ufw allow 8080/tcp
sudo ufw allow 8443/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo firewall-cmd --permanent --add-port=8080/tcp
sudo firewall-cmd --permanent --add-port=8443/tcp
sudo firewall-cmd --permanent --add-port=80/tcp
sudo firewall-cmd --permanent --add-port=443/tcp
sudo firewall-cmd --reload

Restart Tomcat with SSL configuration

Restart Tomcat to load the new SSL connector configuration and verify HTTPS is working.

sudo systemctl restart tomcat
sudo systemctl status tomcat

Configure production security hardening

Update SSL protocols and ciphers

Configure strong SSL protocols and cipher suites for enhanced security. This configuration disables weak protocols and ciphers.


Configure HTTP to HTTPS redirect

Add security constraints to redirect all HTTP traffic to HTTPS automatically. This ensures encrypted connections for all users.



  
    Protected Context
    /*
  
  
    CONFIDENTIAL
  

Configure security headers

Add HTTP security headers to protect against common web vulnerabilities. Create a custom valve for header injection.






  httpHeaderSecurity
  org.apache.catalina.filters.HttpHeaderSecurityFilter
  
    hstsMaxAgeSeconds
    31536000
  
  
    hstsIncludeSubdomains
    true
  

Verify your setup

Test that Tomcat is running with proper SSL configuration and automatic renewal is working.

# Check Tomcat service status
sudo systemctl status tomcat

Test HTTP connection (should redirect to HTTPS)

curl -I http://example.com:8080

Test HTTPS connection

curl -I https://example.com:8443

Verify SSL certificate details

openssl s_client -connect example.com:8443 -servername example.com

Check certificate renewal timer

sudo systemctl status certbot-renewal.timer

Test certificate renewal (dry run)

sudo certbot renew --dry-run

Check keystore contents

keytool -list -v -keystore /opt/tomcat/conf/keystore.p12 -storetype PKCS12
Note: The SSL certificate verification should show a valid certificate chain with your domain name and Let's Encrypt as the issuer.

Common issues

SymptomCauseFix
Certificate generation failsPort 80 blocked or domain not pointing to serverCheck DNS records and firewall settings for port 80
Tomcat won't start with SSLIncorrect keystore password or pathVerify keystore path and password in server.xml match conversion script
Browser shows certificate errorKeystore not generated or corruptedRun sudo /opt/tomcat/bin/convert-certificates.sh and restart Tomcat
HTTP doesn't redirect to HTTPSMissing security constraints in web.xmlAdd transport-guarantee CONFIDENTIAL setting to web.xml
Certificate renewal failsTomcat blocking port 80 during renewalModify renewal script to stop Tomcat temporarily or use webroot method
HTTPS connection refusedFirewall blocking port 8443Open port 8443 in firewall configuration

Monitor SSL certificate status

Set up monitoring to track certificate expiration and renewal status. This helps prevent unexpected certificate expiration issues.

#!/bin/bash

DOMAIN="example.com"
PORT="8443"
WARN_DAYS=30

Get certificate expiration date

EXP_DATE=$(echo | openssl s_client -connect ${DOMAIN}:${PORT} -servername ${DOMAIN} 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f2) EXP_EPOCH=$(date -d "$EXP_DATE" +%s) CURRENT_EPOCH=$(date +%s) DAYS_LEFT=$(( (EXP_EPOCH - CURRENT_EPOCH) / 86400 )) echo "Certificate for ${DOMAIN} expires in ${DAYS_LEFT} days" if [ $DAYS_LEFT -lt $WARN_DAYS ]; then echo "WARNING: Certificate expires soon!" exit 1 fi echo "Certificate is valid"

For comprehensive SSL and application monitoring, consider implementing automated monitoring solutions like those discussed in Tomcat JMX monitoring with Grafana.

Next steps

Running this in production?

Want this handled for you? Setting up SSL automation once is straightforward. Keeping certificates renewed, monitoring expiration across environments, and handling renewal failures is the harder operational work. See how we run infrastructure like this for European teams.

Automated install script

Run this to automate the entire setup

Need help?

Don't want to manage this yourself?

We handle managed cloud infrastructure for businesses that depend on uptime. From initial setup to ongoing operations.