Let’s Encrypt is a new Certificate Authority that is automated and free to use. This makes it possible to obtain domain validated (DV) certificates for your domain names as no cost!
I registered for the closed beta, and got a few of my domain names authorised. This meant that I could now obtain certificates for them. The process was fairly simple. I chose to use the webroot authentication method, which means that the Let’s Encrypt client should be able to place files under my webroot to prove that I control the domain.
Since my webroot is /var/www I created the /var/www/acme/.well-known/acme-challenge folders for the webroot plugin to use. My web server is Nginx so I placed the following code in the server blocks for the domains I want to obtain certificates for and reloaded the Nginx configuration.
location ~ ^/\.well-known/acme-challenge {
root /var/www/acme;
default_type application/jose+json;
}
Now it was time to install and run the Let’s Encrypt client to obtain the certificates. When prompted I used /var/www/acme as the webroot path.
git clone https://github.com/letsencrypt/letsencrypt
cd letsencrypt
./letsencrypt-auto --agree-dev-preview --server https://acme-v01.api.letsencrypt.org/directory certonly
So far so good. I now had my certificates under /etc/letsencrypt/live and could configure Nginx to use them. Great! For those who are curious this is my SSL configuration for Nginx:
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA";
ssl_ecdh_curve secp384r1;
ssl_dhparam /etc/ssl/dhparams.pem;
add_header Strict-Transport-Security max-age=31536000;
The certificates are valid for 90 days, so they need to be renewed fairly often. I wanted to automate this process, so I wrote the following script. Basically it checks all certificates under /etc/letsencrypt/live and if one is about to expire in less than 4 weeks it is automatically renewed. I named this script certrenew.
#!/bin/bash
if [ ! -d /etc/letsencrypt/live ]; then
exit 1
fi
function issueCert {
/root/.local/share/letsencrypt/bin/letsencrypt certonly --renew-by-default --agree-dev-preview --server https://acme-v01.api.letsencrypt.org/directory --authenticator webroot --webroot-path /var/www/acme $1
}
exitcode=1
while IFS= read -r -d '' cert; do
if ! openssl x509 -noout -checkend $((4*7*86400)) -in "${cert}"; then
subject="$(openssl x509 -noout -subject -in "${cert}" | grep -o -E 'CN=[^ ,]+' | tr -d 'CN=')"
subjectaltnames="$(openssl x509 -noout -text -in "${cert}" | sed -n '/X509v3 Subject Alternative Name/{n;p}' | sed 's/\s//g' | tr -d 'DNS:' | sed 's/,/ /g')"
domains="-d ${subject}"
for name in ${subjectaltnames}; do
if [ "${name}" != "${subject}" ]; then
domains="${domains} -d ${name}"
fi
done
issueCert "${domains}"
exitcode=0
fi
done < <(find /etc/letsencrypt/live -name cert.pem -print0)
exit ${exitcode}
The script can be downloaded here.
To automate everything I run the following script via cron every day. It calls the certrenew script and if certificates are renewed it reloads the Nginx configuration after the renewal process. This will produce output so you will get an e-mail from the cron daemon when certificates are renewed. If you don't what that then just send the output of certrenew to /dev/null.
#!/bin/bash
if /usr/local/bin/certrenew; then
/usr/sbin/nginx -t && systemctl reload nginx
fi
exit 0
That's it. Fully automated renewal of Let's Encrypt certificates 🙂
Seneste kommentarer