How to setup SSL on AWS with Tomcat Container

Weidian Huang
4 min readJul 19, 2020

If you wanted to enable SSL for your website, it is the best time to do it - "Let's Encrypt" provides SSL certificates for free. This article describes how to setup SSL using certificate issued by "Let's Encrypt" for the Amazon EC2 instance with Tomcat container.

Step 0: Prerequisites

This is our basic set up.

EC2 AMI: Amazon Linux AMI

JAVA: JAVA1.7

TOMCAT: Tomcat7

Before we start, we’ll also need:

  • A user with sudo privileges. If you’ve been following the tutorials, you have this.
  • Your domain registrar login information.
  • Your domain pointed to the Amazon AWS Elastic IP with an A record. Letsencrypt validates the domain ownership via the A record, so make sure that the IP address is set up properly in your domain registrar.
  • You’ll need to stop the server for a few minutes to allow letsencrypt to run a web server on port 80. Make any necessary precautions.
  • There is a second, ‘webroot’ option that we can tap into for automatic renewals, so once the initial setup process is done we won’t have to shut down the server again.

Step 1: Installing the Let’s Encrypt Installation Scripts

  1. Update PIP if you already have it installed:
pip install --upgrade pip

2. Update Virtual Environment:

$ pip install --upgrade virtualenv

3. Create new virtual environment:

$ virtualenv -p /usr/bin/python27 venv27

4. If you don’t have Git installed on your machine, install it:

$ sudo yum install git

5. Clone "Let's Encrypt" repo and go to the letsencrypt folder:

$ git clone https://github.com/letsencrypt/letsencrypt && cd letsencrypt/

6. If you have Nginx server or Httpd server running, stop it:

$ sudo service nginx stop

7. Run standalone plugin to issue the certificate. Please note, that running standalone plugin requires port 80 to be free (that is why Nginx and Httpd were stopped in the previous step) since this plugin will run the temporary server on it:

$ ./letsencrypt-auto certonly --debug --standalone -d <domain-name>

8. After last step you’ll find 4 files in the /etc/letsencrypt/live/<domain-name>:

  • cert.pem: Your domain's certificate
  • chain.pem: The Let's Encrypt chain certificate
  • fullchain.pem: cert.pem and chain.pem combined
  • privkey.pem: Your certificate's private key

Step 2: Server configuration

There are 3 different methods to enable ssl connection to Tomcat.

1. Use another web server, like Nginx, to proxy request to Tomcat.

2. Use Tomcat BIO/NIO connector.

3. Use Tomcat APR connector.

This article we will going to intruduce the first methods only, for the third method, please refer to this article: https://blog.eveoh.nl/2014/02/tls-ssl-ciphers-pfs-tomcat/

Using Nginx

Install Nginx:

$ sudo yum install nginx

Start Nginx serice.

$sudo service nginx start

Disable the default nginx configuration.

$ cd /etc/nginx/conf.d/$ sudo mv default.conf default.conf~

Create a new nginx configuration file.

$ sudo nano tomcat-proxy.conf

Add the following snippet.

server {
listen 80;
listen 443 ssl;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/<domain-name>/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/<domain-name>/privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';

location / {
proxy_pass http://127.0.0.1:8080/;
}
}

Save and exit. Then test your new configuration.

$ sudo nginx -t

If there are no problems, tell nginx to reload your new configuration.

$ sudo nginx -s reload

Using Tomcat BIO/NIO connector

1. Create keystore for Tomcat

Tomcat use JKS, we need to 2 steps to bundle our fullchain.pem and privkey.pem inside a JKS.

$ openssl pkcs12 -export -in fullchain.pem -inkey privkey.pem -out fullchain_and_key.p12 -name tomcat

You will be asked to provide a password (called yourPKCS12pass in the following). Do not forget it. You will need it for our second step.

Now that we have our PKCS12 keystore, we can use Java’s keytool to generate a JKS from our PKCS12 file like so:

$ keytool -importkeystore -deststorepass yourJKSpass -destkeypass yourKeyPass -destkeystore MyDSKeyStore.jks -srckeystore fullchain_and_key.p12 -srcstoretype PKCS12 -srcstorepass yourPKCS12pass -alias tomcat

This will give you a file called MyDSKeyStore.jks. Now you are ready to configure Tomcat for HTTPS.

2. Configure Tomcat for HTTPS

Now that we have the required JKS, we configure Tomcat’s SSL Connector to use the generated JKS the way it is documented here and here. For this we need to edit Tomcat’s server.xml file found in $CATALINA_BASE/conf/. For DiskStations users this should look something like this:

/volume1/@appstore/Tomcat7/src/conf/

Open that file and find the block starting with <Connector port="8443" protocol="org.apache.coyote.http11.Http11Protocol". Uncomment that block and add your details to the connector. The result should look something like this.

<Connector port=”8443" protocol=”HTTP/1.1" SSLEnabled=”true” maxThreads=”150" scheme=”https” secure=”true” clientAuth=”false” sslProtocol=”TLS” keystoreFile=”conf/MyDSKeyStore.jks” keystorePass=”yourKeyPass” ciphers=”TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_RC4_128_SHA,TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA256, TLS_RSA_WITH_AES_256_CBC_SHA,SSL_RSA_WITH_RC4_128_SHA” />

3. Debug the connection

You can use openssl or a browser to test the connection

>openssl s_client -connect www.talengineer.com:8443 -tls1

If you met the following output from by using openssl

Loading ‘screen’ into random state — doneCONNECTED(00000194)18632:error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure:./ssl/s3_pkt.c:1053:SSL alert number 4018632:error:1409E0E5:SSL routines:SSL3_WRITE_BYTES:ssl handshake failure:./ssl/s3_pkt.c:530:

And the following message from browser.

ERR_SSL_VERSION_OR_CIPHER_MISMATCHHIDDEN DETAILSUnsupported protocolThe client and server don’t support a common SSL protocol version or cipher suite.

It obviously your Tomcat setting is still not correct, ensure that the “ciphers” property is set in the Connector.

--

--

Weidian Huang

Android developer likes to dig deeper into the issues