Running HTTPS on Nginx with Let's Encrypt
After reading the title you'll by now most likely have noticed that my blog runs HTTPS. This is short summary of what it actually took to do this and a few thoughts on HTTPS.
To start with, if you are thinking that not all sites needs to run HTTPS, for example blogs like this or in general sites that don't handle any sensitive data, then you are missing out and you need to read up on what HTTPS is and what it can do for you. By default you are vulnerable to MitM attacks and chances are if you have i.e. ever used WiFi on an airplane you were a victim of this probably without even thinking about it. Ever seen a top banner on pages you were browsing, displaying your flight information or similar? That wouldn't be possible with HTTPS. If you don't think this is serious then read the following article Tunisia plants country-wide keystroke logger on Facebook. A HTTP page posting to HTTPS is not secure as you should have understood by now after reading the facebook article.
There are quite a few perceived barriers to HTTPS and myths. Please don't be one of those people with excuses because there are none and you'll know once you have read the following.
- HTTP vs HTTPS
- Is TLS fast yet?
- High Performance Browser Network
- What every developer must know about HTTPS
So that was a few thoughts on HTTPS and even though it's shallow it's simply due to the fact that the above links explains everything and more, in greater detail.
Now, you might think that running HTTPS on this silly blog was expensive and that it took some time to set up but bottomline is that it was free and took me about an hour.
Let's Encrypt is a free, automated, and open Certificate Authority brought to you by the non-profit Internet Security Research Group (ISRG).
Anyways, most of my time was spent actually upgrading from Ubuntu 14 LTS to 16 LTS. Once that was done I had to iron out a few issues such as my ghost service not working. I had to add a systemd service configuration as follows:
[Unit] Description=ghost After=network.target [Service] Type=simple # Edit WorkingDirectory, User and Group as needed WorkingDirectory=/path/to/Ghost User=http Group=http ExecStart=/usr/bin/npm start --production ExecStop=/usr/bin/npm stop --production Restart=always SyslogIdentifier=Ghost [Install] WantedBy=multi-user.target
Once that was working again I proceeded to get Let's Encrypt.
sudo apt-get update sudo apt-get install letsencrypt
For Let's Encrypt to do its validation it needs access to a folder named
default would be replaced with your actual site. Once you have updated your nginx configuration you simply verify your changes and if all is well you restart the server.
sudo nginx -t sudo systemctl restart nginx
Then I proceeded to obtain the certificate as follows
sudo letsencrypt certonly -a webroot --webroot-path=/var/www/html -d example.com -d www.example.com
and once that was done and the validation succeeded I had certificates.
However, after this I proceeded to generate a strong Diffie-Hellman group to increase the security and configured the nginx configuration to use TLS. There is however one little catch to Let's Encrypt and that is that the certificates expires every 90 days. This however, is not a problem because if you read PR text earlier you might have noticed it said automated. A simple cron job renews the certificates every 60 days. Whoop whoop!
That's it really :-)
This is not meant to be a step by step guide, those you'll find everywhere using your favorite search engine. However I hope you at least got the impression that if I had not had to update Ubuntu, this would probably have been done in 30 minutes or less. There really isn't an excuse for not going HTTPS and even for larger sites I'm sure it's possible to allocate resources to get it done if it's simply prioritized and if it's not you most likely don't fully understand the benefits and risks of not having TLS.
Last but not least I want to share two other great links, one is badssl which you can use for testing purposes and another is ssllabs for analyzing your implementation of HTTPS.