LetsEncrypt is great, but it doesn’t always work brilliantly with Amazon EC2 instances.

Documented below are the various steps and hurdles I’ve had to overcome to install LetsEncrypt and configure Apache to run a clients site securely over SSL. I’m writing this as much as anything for my own reference as I keep having to remember this every time it comes up! I expect it’ll soon be much easier than this, but for now, this is what you need to do.

Steps:

> sudo yum install python27-devel
> sudo git clone https://github.com/letsencrypt/letsencrypt /opt/letsencrypt
> sudo yum install python-pip
> sudo pip install virtualenv
> sudo ln -s /usr/local/bin/virtualenv /usr/bin/virtualenv
> sudo /opt/letsencrypt/letsencrypt-auto --debug

Allow SSL connections through your AWS security settings.

> sudo vi /etc/letsencrypt/config.ini

Add the following lines to this file:

rsa-key-size = 4096
email = support@yoursite.co.uk

Then run the below to generate your certificate:

> sudo /opt/letsencrypt/letsencrypt-auto --debug --config /etc/letsencrypt/config.ini --agree-tos

This generated my certificate ok. However because of my older version of Apache (and other things I’d done to the httpd.conf and ssl.conf files), Letsencrypt couldn’t automatically install it, which was annoying.

After an hour or so trying different things, I managed to manually install the certificate.

When making changes to your ssl.conf file you can avoid breaking your site by testing the config file first using the command:

> sudo service httpd configtest

Then once you get a ‘Syntax OK’ result do:

> sudo service httpd restart

Some of the configuration changes I made to the ssl.conf file are below, including disabling the RC4 cipher.

SSLCertificateFile /etc/letsencrypt/live/domainname.co.uk/fullchain.pem
SSLCertificateChainFile /etc/letsencrypt/live/domainname.co.uk/chain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/domainname.co.uk/privkey.pem

SSLCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:AES:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA

SSLProxyCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:AES:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA

SSLHonorCipherOrder on

SSLProtocol -SSLv2 -SSLv3 -TLSv1 -TLSv1.1 +TLSv1.2
SSLProxyProtocol -SSLv2 -SSLv3 -TLSv1 -TLSv1.1 +TLSv1.2

Expanding the certificate to cover new subdomains

Another issue we had to consider was installing the certificate on the various subdomains / domains that run via the default virtualhost. Thankfully no further ssl.conf updates are required for this and the new domains can neatly by added to the existing certificate with the following command:

> sudo /opt/letsencrypt/letsencrypt-auto --debug certonly -a standalone --expand --config /etc/letsencrypt/config.ini --agree-tos -d admin.clientsite.co.uk -d clientsite.co.uk -d demo.clientsite.co.uk

The command above requires Apache to be stopped temporarily, so in an effort to streamline the process I created a little PHP script to do it for me.

All that remained then was to setup the cronjob to renew the certificate periodically:

0 5 * * * sudo /opt/letsencrypt/letsencrypt-auto renew --config /etc/letsencrypt/config.ini --agree-tos && sudo apachectl graceful

References:

https://ivopetkov.com/b/let-s-encrypt-on-ec2/
https://github.com/certbot/certbot/issues/2889
http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/SSL-on-an-instance.html