OMFG! From the why-the-hell-did-this-take-so-long department, I bring you an exciting announcement: you may never, ever have to pay for a trusted SSL certificate for your website again! E-ver! I’d like to introduce you to Let’s Encrypt. From their website:
Let’s Encrypt is a free, automated, and open certificate authority (CA), run for the public’s benefit. Let’s Encrypt is a service provided by the Internet Security Research Group (ISRG).
Before I walk you through the process of installing a free trusted SSL certificate signed by a top-level CA on your DigitalOcean droplet, let me explain why this is such a HUGE deal.
The Secure WEb is Coming
Slowly but surely, the entire internet is moving to only use SSL (HTTPS). Some examples:
- Since mid-2014 at Google
- In April 2015 Mozilla (the Firefox people) announced they are deprecating (i.e. planning to no longer support) non-secure HTTP
- Major publications, e.g. Wired, Mashable, NY Times, are writing about how individuals and businesses should be switching over to HTTPS in light of major security breaches, and scandals like the NSA’s massive surveillance program
It is clear that if you haven’t started to do this already, you should definitely begin moving all of your online content onto a server that only uses HTTPS.
Obstacles to the Secure Web
In the past, there have been two main obstacles to using HTTPS:
- It was complex to install
- It was expensive
Do a search for “how do you install an SSL certificate” and you get a dizzying list of confusing, hard-to-follow tutorials. There are a great number of variables involved in the process, such as what kind of server you’re on, who your web host is, what company originated the certificate, what kind of certificate it is, etc. While it’s certainly gotten easier in the last few years as many companies have found ways to automate the process, figuring out how and where to buy a certificate, knowing how much to pay, and what you get for that money is still extremely challenging.
At the high end, you can pay Symantec (formerly VeriSign) up to $1,500 per year for their “most secure” EV SSL certificate!!! At the low end, you can get certs for as cheap as $9/year at places like NameCheap. They confuse the process by adding warranties of varying amounts, but it all hides the fact that your site visitors really aren’t that much safer with a $1,500 cert than they are with a $9 cert. That’s not to mention the cost many web hosts charge you for obtaining a static IP address. If you don’t know what you’re doing, it is easy to get taken for hundreds of dollars a year for something that is increasingly a necessity. All of this because a small number of companies have a monopoly on the business of generating SSL certificates…until now.
Enter Let’s Encrypt!
Although I couldn’t find any information on its founding in 2013, an IRS tax-exempt 501(c)(3) organization incorporated as a public benefit corporation (a b-corp) called the Internet Security Research Group (ISRG) announced Let’s Encrypt in 2014. Their goals are simple:
- Make it easy to install an SSL certificate
- Make it free for anybody who wants one
Let’s Encrypt started a limited beta test back in September. You had to fill out a form and get approved to join. If accepted, they would send you an email with instructions on how to download their client software and install your software. It’s been a little bit buggy over the past several months, but they are on target to launch their public beta just 3 days from now on December 3rd! Starting then, anyone should be able to fill out the form on their website and get whitelisted to download your new, free certs instantaneously. Okay, so enough background, let’s do it!
Installing Your SSL Certificate
To start out, here are the specs of my server (here’s my tutorial on how to set up a server like this):
- Ubuntu 14.04 LTS running on a droplet at DigitalOcean
- PHP 7 FPM
- Nginx
ufw
andfail2ban
firewalls
Step 1: Log In and Download the letsencrypt
Command Line Client
After logging in, I just performed the following from my home directory (~
):
$ git clone https://github.com/letsencrypt/letsencrypt
$ cd letsencrypt
$ ./letsencrypt-auto –server https://acme-v01.api.letsencrypt.org/directory –help
If you do this, you’ll run their letsencrypt-auto
script and get some basic help information on how to use their tool. As of the time of this writing, this is still new software, so it doesn’t work exactly like they advertise on their website, but if you’re an early adopter like me, and understand how cool this is, you won’t mind that it’s a little bumpy out of the gate.
Step 2: Open Up Port 443/tcp on your Firewall and Reboot
If you followed my tutorial to set up your server, you may not have opened up port 443 (the HTTPS
port) at that time if you didn’t already have a certificate ready to install. To open up the ports, I ran the following commands:
$ sudo ufw allow 443/tcp
$ sudo ufw enable
$ sudo reboot
[/bash]I’m not sure you actually have to reboot here, but I was having trouble getting port 443 to show up as open. To debug this, from a terminal window on my local machine I used a program called nmap
(on a Mac you can install this with brew install nmap
) and ran the command:
After I rebooted, it seemed to start working fine.
Step 3: Stop Firewalls and nginx and Reconfigure Your Default Site
Although letsencrypt
will eventually come with a plugin for nginx
that will automatically install your certs for you with the server running, at present that plugin is “very buggy” so they don’t even have it installed by default. Instead, I used the standalone
method, which I’ll explain in the next step. First, however, stop nginx
and then open up the config file for your site where you want to install your SSL cert:
$ sudo ufw disable
$ sudo service fail2ban stop
$ sudo service nginx stop
$ sudo nano /etc/nginx/sites-available/default
[/bash]Once the config file is opened, modify it so it looks like this:
[bash]server {
listen 80 default_server;
server_name mysite.com www.mysite.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
server_name mysite.com www.mysite.com;
ssl_certificate /etc/letsencrypt/live/mysite.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mysite.com/privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers AES256+EECDH:AES256+EDH:!aNULL;
root /var/www/mysite.com/public;
index index.php index.html index.htm;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
try_files $uri /index.php =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
So note a couple of things:
- I’ve broken what was one
server
block up into twoserver
blocks. - In the first one on line 4 I added
return 301 https://$server_name$request_uri;
which will redirect ALL website traffic toHTTPS
, regardless of whether or not people actually typed inhttps://...
in the address bar when they came there. - The paths to the certificate files (lines 11 and 12) may be different on your server, but I’ll show you how to figure out what they are.
- You should use your actual domain name wherever I have mysite.com.
- I’m setting this up to provide SSL for both
mysite.com
andwww.mysite.com
. It’s important to understand that SSL certs are tied to very specific domain names and you have to get this right or it won’t work.
Save your changes and exit.
Step 4: Install Your SSL Certificate
Okay, now type the following at the terminal:
[bash gutter=”false”]$ cd ~/letsencrypt
$ ./letsencrypt-auto certonly -a standalone –webroot-path /var/www/mysite.com \
-d mysite.com -d www.mysite.com –server https://acme-v01.api.letsencrypt.org/directory \
–agree-dev-preview
[/bash]Cross your fingers. This didn’t work for me the first few times which led me down a bunch of rabbit holes trying to debug the problem. Essentially what I decided is that either their service is still buggy, or I just happened to be trying to install my certificate when they had a lot of people hitting their servers, or maybe both. I had to put in that last command maybe 10 times or more before it worked. I also tried some of the other variations on that command that got sent in the email (NOT the apache
one, though) and it finally happened:
IMPORTANT NOTES:
– Congratulations! Your certificate and chain have been saved at
/etc/letsencrypt/live/mysite.com/fullchain.pem. Your cert
will expire on 2016-02-29. To obtain a new version of the
certificate in the future, simply run Let’s Encrypt again.
I can’t tell you how happy I was to see that message!!! Take note here that the message tells you where on your hard drive the certificates got stored. Make sure that path is the same one you set in your config file above. If it isn’t the same, then you need to modify it.
Step 5: Restart Your Firewalls and Nginx
Okay, at this point the final thing to do is just get your web server up and running again:
[bash gutter=”false”]$ sudo service nginx start
$ sudo ufw enable
$ sudo service fail2ban start
[/bash]And now head over to your website and your browser and with any luck, you’ll see the lock in the address bar!
Closing Thoughts
Okay, now none of us have any excuse not to be securing ALL of our websites. We’re entering a new era. Don’t believe the myths about how SSL will slow your site down. In some cases it actually speeds them up! The call has been made: Let’s Encrypt!
Cannot get this to work – for days…. 🙁
some how it seems 443 is just not accepting settings? I know not.
Sorry you’re having trouble! This post is pretty old at this point. If you’re still trying to get this working, I suggest checking out certbot: https://certbot.eff.org