Huseyn Gasimov
Huseyn Gasimov
Creator of this blog.
Jul 16, 2018 3 min read

Enable HTTPS for free on your website running on Tomcat

thumbnail for this post

Recently, the SSL certificate for my website salsafloors.com was going to expire. Instead of paying and renewing the certificate, I decided to change to Let’s Encrypt SSL certificate, which is for free. But the process was not so easy, that’s why I decided to write a blog post about it. I hope it will help some people in the future save some time.

1 Install Let’s Encrypt certificate

I actually installed Let’s Encrypt certificate for WordPress on Apache before and it was not so painful, because Apache is officially supported by Certbot – the tool for installing Let’s Encrypt certificates. But Tomcat is not supported and this makes the installation a bit complicated.

1.1 Prerequisites:

  • Tomcat 8.5 or higher. Certbot creates pem certificates for you and Tomcat 8.5 supports pem certificates out-of-box. For previous versions, you will need to create a java keystore file and import the created pem files into the keystore file.
  • Java 8 or higher. Make sure that tomcat uses Java 8 or higher. Java 7 didn’t work for me, because it lacked some ciphers, which were necessary to make the generated Let’s Encrypt certificate work.

Ok, let’s get started.

1.2 Download the Certbot tool

First, I downloaded the Certbot tool:

$ wget https://dl.eff.org/certbot-auto
$ chmod a+x certbot-auto

1.3 Fetch SSL certificates

Then I fetched the SSL certificates for my website. Certbot needs a web server for that. Here you have 2 choices:

  1. using –standalone parameter, which will spin a temporary built-in web server. But, if you already have a running web server, you need to shut it down first.
  2. using –webroot parameter and showing the webroot of you running web server. This way certbot can use your web server to do its job.

I chose to use the –webroot parameter, because I was doing it in the production and shutting down the production server was not an option.

$ sudo /path/to/certbot-auto certonly --webroot -w /path/to/apache-tomcat-8.5/webapps/ROOT -d example.com

This will create the following certificates:

  • Certificate: /etc/letsencrypt/live/YOUR_WEBSITE_HERE/cert.pem
  • Chain: /etc/letsencrypt/live/YOUR_WEBSITE_HERE/chain.pem
  • Full Chain: /etc/letsencrypt/live/YOUR_WEBSITE_HERE/fullchain.pem
  • Private Key: /etc/letsencrypt/live/YOUR_WEBSITE_HERE/privkey.pem

1.4 Edit server.xml

Now it’s time to let tomcat know, where the newly generated certificates are. Hence I edited the HTTPS connector in the server.xml like this:

<Connector port="443" protocol="org.apache.coyote.http11.Http11NioProtocol"
               maxThreads="150" SSLEnabled="true" >
    <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
    <SSLHostConfig>
        <Certificate certificateKeyFile="/etc/letsencrypt/live/YOUR_WEBSITE_HERE/privkey.pem"
                        certificateFile="/etc/letsencrypt/live/YOUR_WEBSITE_HERE/cert.pem"
                        certificateChainFile="/etc/letsencrypt/live/YOUR_WEBSITE_HERE/chain.pem"
                        type="RSA" />
    </SSLHostConfig>
</Connector>

Note that I used Http11NioProtocol instead of the default Http11AprProtocol, because Http11AprProtocol didn’t work out-of the box and I needed to install more packages to make it work. You can find a short explanation about the difference between these protocols here.

Then I restarted the tomcat server.

2 Auto-renew certificates

Let’s Encrypt certificates are usually valid for 90 days, hence you need to renew them periodically. You can test automatic renewal for your certificates by running this command:

$ sudo ./path/to/certbot-auto renew --dry-run

If that appears to be working correctly, you can run it periodically by adding the following line to crontab:

0 0,12 * * * python -c 'import random; import time; time.sleep(random.random() * 3600)' && ./path/to/certbot-auto renew

Note that certbot recommends to run it twice a day. It won’t do anything until your certificates are due for renewal or revoked, but running it regularly would give your site a chance of staying online in case a Let’s Encrypt-initiated revocation happened for some reason.

3 Acknowledgements

I would like to thanks all the people behind Let’s Encrypt initiative. Moreover, the following resources helped me a lot in installing the certificates: