Enable HTTPS for free on your website running on Tomcat
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.
- 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:
- 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.
- 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.
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: