May 13, 2016 Tags: meta
As of today, my personal site is finally encrypted, with a Let’s Encrypt certificate:
I was invited to LE’s beta a little over a year ago, but had shied away from HTTPS on the (completely incorrect) assumption that it would require additional maintenance and configuration time. Seeing how my personal site is 99% static and hand-written, I didn’t feel any particular need to complicate my life with another administration task.
I would see articles and posts every few weeks about how amazingly easy it LE was to set up, but chalked them off as a combination of hype and people less lazy than I am (I’ve been told it’s a virtue).
Then, yesterday, I discovered certbot.
Certbot is basically the old letsencrypt
client (actually, it’s exactly the
old client), except renamed and with a new PR campaign (and mascot). The project
page made configuration look dead simple, so I decided to bite the bullet and
try it.
In 5 minutes, I had an HTTPS-secured site with an A+ security report.
Here are the exact steps I took:
1
2
3
4
5
6
7
8
$ wget https://dl.eff.org/certbot-auto
$ chmod +x certbot-auto
$ ./certbot-auto certonly # fill out the interactive dialogs
$ sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048 # generate a strong DH group
$ sudo vim /etc/nginx/sites-enabled/default # update nginx's config
$ sudo mv ./certbot-auto /etc/letsencrypt/ # move for later scheduling
$ sudo crontab -e # schedule certificate updates
$ sudo service nginx reload # load the new ssl configuration
certbot-auto
’s configuration was an absolute breeze - every step was extremely
explicit (and validated!) to prevent user error. The curses
-style interface
used was probably one of the friendlier I’ve ever encountered.
Editing nginx
’s configuration required a bit of research, but DigitalOcean
had my back with a
tutorial
on my exact setup (substituting letsencrypt-auto
for certbot-auto
).
I also went with their advice on generating a stronger (2048 bit) Diffie-Hellman
group, which is the only additional step required for obtaining that
highly-coveted A+ report. Ultimately, the configuration ended up looking like
this (cruft removed):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# http
server {
listen 80;
server_name woodruffw.us www.woodruffw.us;
# redirect all HTTP requests to HTTPS
return 301 https://$host$request_uri;
}
# https
server {
listen 443 ssl;
root /usr/share/nginx/html;
index index.html;
# make available on localhost as well
server_name localhost woodruffw.us www.woodruffw.us;
ssl_certificate /etc/letsencrypt/live/woodruffw.us/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/woodruffw.us/privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_stapling on;
ssl_stapling_verify on;
add_header Strict-Transport-Security max-age=15768000;
location ~ /.well-known {
allow all;
}
}
From there, ensuring that the certificate remains updated is a single line
in the system crontab
:
1
30 2 * * 1 /etc/letsencrypt/certbot-auto renew ; service nginx reload
One sudo service nginx reload
later, and my site was fully encrypted, with
unencrypted sessions seamlessly redirected.
nginx
, and that only
took about 2 minutes.
That won’t be necessary for long,
either.cron
job
will run once a week until the end of time (or I turn off the server, whichever
comes first). I can opt to change my ciphersuites as encryption technologies
evolve, and that’s a 30-second change in nginx
’s configuration.I know I’m a bit late to the party when it comes to LE, but this is great news for the web and for pervasive encryption.
If you haven’t already looked into adding a Let’s Encrypt cert to your (unsecured) site, please do. It’s free (as in beer and freedom), dead simple (I’m really not exaggerating about the 5 minutes), and an easy way to make your part of the web more secure.
- William