Modern Website over HTTP 2 and SSL with Nginx and Let's EncryptPublished on
Triangles. Generated through trianglify
The free and open certificate authority, Let’s Encrypt has been out in public beta for the last few months and v0.3.0 of their client was recently released, so I decided to give it a try on one of my side projects: eu4stats.com.
Additionally, Nginx, the web server behind eu4stats.com, received an update in September that supports HTTP2 requests. While HTTP2 does hold the promise of increased performance, eu4stats.com most likely won’t see the benefit because most the assets are pulled from CDNs like jsDelivr, but it will be a good future proofing excersise.
Step 0: Testing Along the Way
We’ll be testing our server externally through the use of
cURL. We’ll see the upgrade, the switch to https, and http 2 represented in the response. The following command will let us see.
cURL, as packaged, is unable to query using HTTP 2, so you’ll have to build it from source by first building nghttp2 and then building cURL by configuring with the
--with-nghttp2 flag and path. After everything is built, you’ll see the previous command returning HTTP 2 headers.
Step 1: Updating Nginx
We need a recent version of Nginx, but default package managers are likely to carry only outdated versions, so hop over to the official linux distrubtion page. The stable package doesn’t include the HTTP2 module (
--with-http_v2_module), so use the mainline version.
Below we add the Nginx key to
apt, add their repo, and update.
We can test the Nginx server and HTTP version with
apt-cache showpkg nginx. Newer versions of Nginx should appear. Let’s install the most recent one.
If the previous snippet does not work, it’s because the nginx maintainer for ubuntu somewhat emulates the apache server configuration, so you may have to go a few more steps.
The latest and greatest Nginx is installed, but because you can’t enable HTTP 2.0 unencrypted (if you can, you shouldn’t because browsers may reject it) we have to get our certificate. Next step!
Step 2: Let’s Encrypt: Retrieving Certificates
Getting and setting up Let’s Encrypt on a machine is somewhat of a controversial topic. As a system administrator, you are putting a lot of trust into this program because:
- Requires root privileges. You’re giving Let’s Encrypt the power to do anything on your machine, including mess it up
- Heavy installation. Installs various dependencies including GCC, which is the not what I want to be installing on what should be a slim server with limited disk space.
- Is a black box. You execute a command and all your certificates including your key are generated. If you’re not careful, it’ll rewrite your Apache configuration as well!
Naturally I tried looking for alternatives that alleviated all mentioned problems:
- gethttpsforfree.com: As a website, doesn’t require installation of anything but also doesn’t support auto-renewel.
- Let’s Encrypt - No Sudo: Had more problems than I could shake a stick at with odd crypto errors.
- simp_le: is another heavy install
After several hours I gave up and went back to the Let’s Encrypt docs and found this golden nugget:
Unless you have a very specific requirements, we kindly ask you to use the letsencrypt-auto method. It’s the fastest, the most thoroughly tested and the most reliable way of getting our software and the free SSL certificates!
They really should have focused on making the client as small and self contained as possible and then build upon that foundation. Not spend time prioritizing an ncurses GUI or auto-magically updating your site’s configuration. All the while, closing sane requests to open up the black box as “too difficult”. Ok, rant done. It’s beta software and getting better every day.
Once you pull down
letsencrypt-auto here are the commands to run to get handed the cert from already running site:
You’ll see your Let’s Encrypt certificate along with the chain, full cert, and private key.
Step 3: Installing Certificates
SSL configuration of a server is probably less intuitive than probably one thinks. To help us, Mozilla created an SSL configuration generator and I would recommend starting with the intermediate Nginx configuration. Since we’ll want http 2 and Let’s Encrypt auto renewal, modify the pull request to add http2 and include the following snippets:
Step 4: Auto Renewal
The Let’s Encrypt official client will have a
renew command in 0.4.0 , so I won’t spend too much time on this because this section will be outdated shortly. In the meantime, I recommend using the