How to setup SSL on AWS with Tomcat Container
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
- 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 certificatechain.pem
: The Let's Encrypt chain certificatefullchain.pem
: cert.pem and chain.pem combinedprivkey.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.