Marco's Blog

All content personal opinions or work.
en eo

SSL Certificates with Let's Encrypt

2016-10-21 6 min read Howto marco

You probably noticed a microscopic difference when accessing the site: suddenly, when you type in mrgazz.com, you get redirected to the secure site, <>. Why, and how?

First the why: Google announced it was going to prioritize search results according to the security of the site. That makes a lot of sense: “secure” sites have a modicum of respectability and require extra work compared to plain HTTP sites. You have to set up a secure server, which means you have to do more than simply point a DNS name to an IP address.

If you think it’s unfair that HTTP sites get downvoted, it’s an argument that makes sense. At the very least, sites that have been running on HTTP for years should not be suddenly penalized because someone else abuses HTTP. But Google does what Google wants, and frankly the number of search hits this site gets is not a hot priority.

Setting up SSL on a web server is not tragic. In essence, you need a server certificate, you install it according to the instructions of the server, and you set up a separate web server instance that responds to secure requests. It’s a bit of a pain, especially if you only have a single web site to transition, but it’s not a huge stumbling block.

First, getting the certificate. What’s that? It’s a document (file) that certifies that you are who you say you are. When you connect to www.mrgazz.com using SSL, the web server presents this certificate (the public version of it) to your client (the browser), and the browser verifies it. Technically, the browser has a list of trusted authorities that are allowed to certify my certificate, and if one of those authorities says I am good, then your browser agrees.

Which also means that you have to get an authority to certify you. For the longest time, this meant you had to fill out a form and pay money for a certificate to be issued. Certificates would last a year or so, then you’d have to go and renew. This was a double pain point: on one side, a whole year is a lot of time and lots of mischief can happen during that period. Ideally, certificates should last shorter. On the other hand, if you forgot to buy your new certificate, all browsers that connected to your site would suddenly sound alarm bells and tell the user that your site was fishy. They would also generally make it really hard to connect.

Let’s Encrypt is a new project that has a completely different approach. Instead of making the web site owner fill out a form and make a payment, Let’s encrypt matches who you are and who you say you are by running software on the web server. You install the Let’s Encrypt client on the machine that runs the web server, then the software tries to connect to itself using the DNS name. If it succeeds, then it knows you are who you say you are. It then issues a certificate.

The most amazing thing about Let’s Encrypt is not the approach, no matter how amazing it is and how wonderful it is not to have to pay $10 a year. What’s really special is how easy it is to set up on the standard web servers on the Internet. If you run a latest-version Debian or Ubuntu, installing Let’s Encrypt is as simple as:

sudo apt-get install python-letsencrypt-<webserver>

[Note: until recently you had to download an archive and install manually, which I really, really, really didn’t like, because I had no idea what that package would so. Having a package file from the default repository makes me feel much better!]

Running the software for the first time is also completely braindead:

sudo letsencrypt --<webserver>

In my case (as in many), the webserver is apache:

sudo letsencrypt --apache

But letsencrypt comes in a variety of styles for the most common web servers on the Internet.

From the command prompt, you get into an interactive series of dialogs where you essentially confirm which ones of your available sites you want to convert to SSL, and whether you want to allow access to both HTTP and HTTPS or only to HTTPS.

Magically, letsencrypt will write new site rules to make your new SSL connection available. I tried it both with sites that had no SSL configuration at all, as well as this site, which ran a mix of secure and insecure sites, now all converted to secure. letsencrypt figured out how to change the configuration for both types and restarted everything, so that there was the absolute minimum downtime.

This is where I found the absolutely only downside of letsencrypt, and it’s really not its fault. You can access this site, like many web sites on the Internet, under both mrgazz.com and www.mrgazz.com. The former is what geeks call the domain name, while the latter is the server name. If you want to know the difference, you must educate yourself on the Domain Name System and the beauty of A records and CNAMES. That’s beyond the scope of this article.

Suffice to say that letsencrypt refuses to generate certificates for domain names and will issue them only for server names. That means you cannot have https://mrgazz.com, because letsencrypt will not issue a certificate for that server.

You could go about it two ways, just as outlined in the dialog that letsencrypt presents: you could have <> run independently of http://mrgazz.com. That is, users could connect to either independently. In that case, you don’t have to do anything.

If instead you want all traffic to your site to go to the SSL version, you need to do a little extra configuration: in the Apache configuration file, you will see this section:

RewriteEngine on
RewriteCond %{SERVER_NAME} =www.mrgazz.com
RewriteRule ^ [https://%{SERVER_NAME}%{REQUEST_URI}](%{REQUEST_URI}) \[END,QSA,R=permanent\]

What this does is to take the requests sent to the insecure version and redirect them to the secure version. THe problem here is that it does so only for www.mrgazz.com, so you have to add mrgazz.com. Also, the rule redirects to SERVER_NAME, which would redirect to mrgazz.com. You need to change that, so that it always redirects to www.mrgazz.com. In the end, you get this section:

RewriteEngine on
RewriteCond %{SERVER_NAME} =www.mrgazz.com \[OR\]
RewriteCond %{SERVER_NAME} =mrgazz.com
RewriteRule ^ [%{REQUEST_URI}](%{REQUEST_URI}) \[END,QSA,R=permanent\]

Notice the [OR] at the end of the line. Once you reboot the server, everything is just as you wanted.

Extra points:

  • letsencrypt configures your secure web server almost flawlessly. When you check the configuration from a security perspective, you get an A rating for security.
  • letsencrypt security certificates can run multiple web server names from a single web server. You can put as many secure sites as you want on your web server, letsencrypt will configure them all correctly.