January 23, 2017

Let's Encrypt with Amazon Linux

For the past couple of years, I have used StartSSL to obtain free SSL certificates for 13cubed.com and other side projects. As many are aware, StartSSL's parent StartCom was acquired by Chinese CA WoSign. Apple, Google, the Mozilla Foundation, and others have revoked certificates issued by WoSign and StartCom due to several incidents involving improper issuance and back-dating of certificates to avoid the SHA-1 sunset.

I decided to give Let's Encrypt a try, but I wanted to manually handle the editing of the Apache SSL/TLS configuration (I don't trust a script to properly do this without making a mess of things). Surprisingly, as of the time of this post, Let's Encrypt does not provide configuration information for Amazon Linux. Using the information here, I was able to cobble together a short list of steps to get everything up and running:

1. Download the newest version of the Certbot Auto script:

cd /home/ec2-user
wget https://dl.eff.org/certbot-auto

2. Change permissions to make the script executable:

chmod 755 certbot-auto

The script checks for the presence of /etc/issue, and looks for the string "Amazon Linux" therein. On my instance, this file was not present. If the script doesn't find the file, you will receive the following error:
Sorry, I don't know how to bootstrap Certbot on your operating system!
You will need to bootstrap, configure virtualenv, and run pip install manually. Please see https://letsencrypt.readthedocs.org/en/latest/contributing.html#prerequisitesfor more info.
3. If "/etc/issue" is not present on your instance, create the file, adding the string "Amazon Linux" therein:

sudo echo "Amazon Linux" > /etc/issue

4. Run the script with the following parameters, replacing "13cubed.com" and "www.13cubed.com" with your domain. Note the "certonly" parameter, which instructs the script to NOT modify any configuration files. You can add as many "-d" flags as necessary, but wildcards are not supported:

sudo ./certbot-auto --debug -v --server https://acme-v01.api.letsencrypt.org/directory certonly -d www.13cubed.com -d 13cubed.com

You will likely be prompted to install several packages. In my example, I installed the following:

mpfr-3.1.1-4.14.amzn1.x86_64
libmpc-1.0.1-3.3.amzn1.x86_64
cpp48-4.8.3-9.111.amzn1.x86_64
libsepol-devel-2.1.7-3.12.amzn1.x86_64
libselinux-devel-2.1.10-3.22.amzn1.x86_64
libverto-devel-0.2.5-4.9.amzn1.x86_64
kernel-headers-4.4.41-36.55.amzn1.x86_64
glibc-headers-2.17-106.168.amzn1.x86_64
glibc-devel-2.17-106.168.amzn1.x86_64
libcom_err-devel-1.42.12-4.40.amzn1.x86_64
zlib-devel-1.2.8-7.18.amzn1.x86_64
keyutils-libs-devel-1.5.8-3.12.amzn1.x86_64
krb5-devel-1.13.2-12.40.amzn1.x86_64
libgomp-4.8.3-9.111.amzn1.x86_64
gcc48-4.8.3-9.111.amzn1.x86_64
gcc-4.8.3-3.20.amzn1.noarch
1:openssl-devel-1.0.1k-15.96.amzn1.x86_64
libffi-devel-3.0.13-16.5.amzn1.x86_64
system-rpm-config-9.0.3-42.28.amzn1.noarch
python27-tools-2.7.12-2.120.amzn1.x86_64
augeas-libs-1.0.0-5.7.amzn1.x86_64

The script will then ask how the CA should verify ownership of the domain for which you wish to obtain the certificate. I chose the second option, which involved placing a temporary file within the web root (normally /var/www/html on a default installation).

Once the script has finished, it will have generated the following symlinks within /etc/letsencrypt/live/[DOMAIN NAME]/:

Example:

cert.pem -> ../../archive/www.13cubed.com/cert1.pem
chain.pem -> ../../archive/www.13cubed.com/chain1.pem
fullchain.pem -> ../../archive/www.13cubed.com/fullchain1.pem
privkey.pem -> ../../archive/www.13cubed.com/privkey1.pem

5. Assuming you are using Apache, edit /etc/httpd/conf.d/ssl.conf as follows, changing "www.13cubed.com" to the name of the domain for which you obtained the certificate:

vi /etc/httpd/conf.d/ssl.conf

SSLCertificateFile /etc/letsencrypt/live/www.13cubed.com/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/www.13cubed.com/privkey.pem SSLCertificateChainFile /etc/letsencrypt/live/www.13cubed.com/chain.pem

6. Restart Apache and verify the certificate installation was successful:

service httpd restart

7. Let's Encrypt certificates expire every 90 days, so you'll need to create a cron job under "root" to periodically check the status. As suggested in the article I referenced above, I would recommend twice per day. The following cron job checks at 1AM and 1PM:

sudo crontab -e

# MIN HOUR DAYOFMONTH MONTH DAYOFWEEK COMMAND
0 1,13 * * *    /home/ec2-user/certbot-auto renew

Fin!

1 comment: