Ever since Let’s Encrypt announced free SSL certificates (albeit with a few caveats, more on this below), I’ve wanted to make the change to serving web pages on this blog securely. Last night I finally buckled down and got it done. After a small mishap that involved the accidental removal of my Nginx configuration file (a droplet backup saved me from certain disaster), I generated a cert following the pretty great tutorial from Digital Ocean.
A few notes on the process:
- For people just running a self-hosted WordPress blog, there’s zero WordPress-side configuration you have to do, which kind of surprised me. I thought I was going to have do at least install some kind of WordPress plugin, but it turns out enabling HTTPS is all dependent on your web server software. For Nginx, it’s a few lines in your site’s configuration file, and presto, HTTP over SSL (once you’ve gotten past the hurdle of generating your cert).
One of the first issues I ran into was the certbot not recognising my domain, returning a 403 Forbidden when it attempted to authenticate that I owned the domain in question. At first I thought this was because the DNS changes I made hadn’t propagated yet, but then I realised it was one of my Nginx access rules (the only preventing access to any file or directory starting with a period) that was preventing certbot from accessing my domain. A quick Nginx configuration change fixed that issue – I’m still not sure if it will need to access the well-known directory again when it attempts to renew the certificate, but we’ll know in about 89 days.
Yeah, Let’s Encrypt only issues certs that are valid for 90 days. But it’s not such a big deal, because there’s a handy way to renew your cert that you can even put in cron for true set-and-forget functionality. It’s not the annual or multiple-year certificate that you’d get from a more established CA, but you’re also not paying anything.
Once I had generated the cert, updated my Nginx configuration, and restarted Nginx with the new config, my blog wouldn’t load — the connection would just time out when attempting to load it in a browser, and curl via Terminal told a similar story. I scratched my head at this a little, until I discovered that my server’s firewall was blocking port 443. Oops. Bit of a rookie mistake there, and what made it even more difficult to diagnose was how I had set Nginx to redirect HTTP traffic on port 80 to port 443 — pretty standard practice when enabling HTTPS, but it made troubleshooting the issue more difficult.
Anyway, my blog now scores an A+ on Qualys’ site SSL testing suite, and all I have to do is turn think of some other stuff to write about, so there’s actually something to serve over HTTPS.
Update Dec 30, 2016: After discovering that (some? if not all) posts with images were being served as mixed content, I used this sql update statement on this page to update all my wp-content links in posts to be served over TLS. I also updated my site URL in settings, so hopefully everything should be hunky-dory.
Or… maybe not. I just realised that there’s probably a tonne of pages (mostly from the now-defunct Posterous) that would have been being served over HTTP. Still not sure what I want to do with those Posterous posts, as images as broken on all of them at the moment.