Hi. I'm Mitchell Anicas, a Technical Writer at DigitalOcean. In this screencast, I'll
show you how to secure Nginx with a free SSL certificate from Let's Encrypt.
Let's Encrypt is a new certificate authority that provides an easy way to obtain and install
free TLS/SSL certificates. These certificates can be used with any web server software,
such as Nginx, Apache, or HAProxy, to provide encryption and authentication between your
server and its users.
Here's what you need before getting started
Root or superuser access to an Ubuntu 14.04 Server
If you don't have one, follow this link to create one on DigitalOcean.
Registered Domain, such as example.com, (and the ability to change the nameserver records)
To complete our setup, we will follow these steps.
Point Domain to Server Install Nginx
Install Let's Encrypt Client Obtain a Certificate
Configure Nginx (to use the certificate) Set up certificate auto-renewal
First, we'll point our domain name to our server.
Then, on the server, we'll install Nginx and the Let's Encrypt client. After obtaining
an SSL certificate, we will configure Nginx to use it. Lastly, we'll set up a script that
will automatically renew our SSL certificate before it expires.
If you already have completed the first two steps, and have an Nginx server that is accessible
via a domain name, just skip them.
1. Point Domain to Server
Let's get started.
To point your domain to your server, go to the control panel for your domain's nameservers
so you can make sure you have the proper A records in place. This will allow your users
to access your server by going to your domain name in a web browser. Also, Let's Encrypt
will only issue a certificate to a server that is accessible via a domain name.
I'll show you how to do this using DigitalOcean's DNS. If you're using some other DNS service,
the process should be more or less the same.
If your domain doesn't already exist in the system, create it. I'm using mitchellanicas.com
Then create an A record for the domain name, and another for the www version of the domain.
Both of them point to my server's public IP address.
Once the DNS information propagates, you should be able to access your server via your domain
name.
2. Install Nginx
Now we're ready to install Nginx, the web server software.
First, log in to your Ubuntu server using SSH.
ssh user@example.com Then update your apt-get repository listings
with:
sudo apt-get update Then install Nginx with:
sudo apt-get install nginx Enter Yes at the prompt. Once the installation
is complete, Nginx will be running with the default page. You can verify this by visiting
your domain, over HTTP, in a web browser.
3. Install Let's Encrypt Client
Currently, the best way to install the Let's encrypt client is to simply clone it from
the official GitHub repository. In the future, it will likely be available via a package
manager, such as apt-get.
Install Git
So, let's install Git:
sudo apt-get install git (Note: You may also need to install the bc
package)
Clone Let's Encrypt
Now we can use this git command to clone Let's Encrypt to our server's /opt directory:
sudo git clone https://github.com/letsencrypt/letsencrypt /opt/letsencrypt
4. Obtain a Certificate
Now, with Let's Encrypt installed, we can obtain free SSL certificates.
Let's Encrypt provides a few different mechanisms, or plugins, that it can use to authenticate
that your server should be issued an SSL certificate. The most simple authenticator is the Standalone
plugin, which works by temporarily running a basic web server, on port 80, so that Let's
Encrypt can verify that your domain belongs to your server.
Because the standalone authenticator listens on port 80, the standard port for HTTP traffic,
we need to stop Nginx temporarily with:
sudo service nginx stop Run Let's Encrypt
Now, change to the let's encrypt directory with:
cd /opt/letsencrypt Use the standalone plugin by running this
command:
./letsencrypt-auto certonly --standalone Enter your email address:
manicas@digitalocean.com Then agree to the Let's Encrypt subscriber
agreement.
Then enter your domain names. I want my certificate to work with the www and "non-www' versions
of my domain, so I'll enter both of them here.
mitchellanicas.com www.mitchellanicas.com If everything goes well, you will see output
like this. The output should show you the location of your certificate files and the
expiration date of your certificate. You can verify that all of the relevant files have
been created with this command:
sudo ls /etc/letsencrypt/live We will be using the fullchain.pem and privkey.pem
files with Nginx.
5. Configure Nginx
Now we'll configure Nginx to use the Let's Encrypt certificate, which will enable encrypted
HTTPS traffic. We will also configure plain HTTP connections to be redirected to HTTPS.
I'm going to use the vim editor to edit the default Nginx server block configuration with:
sudo vim /etc/nginx/sites-available/default (Note: If you're not familiar with vim, I
would recommend using the nano editor instead. sudo nano /etc/nginx/sites-available/default)
Find the server block.
Comment out or delete the lines that configure the server to listen on port 80:
Next, in the server block, add: listen 443 ssl;. This configures Nginx to listen on port
443 for SSL connections.
Then, specify your server name like this: server_name mitchellanicas.com www.mitchellanicas.com.
Of course, you will want to use your own domain name here.
Then we have to specify the ssl certificate and private key, like this:
ssl_certificate /etc/letsencrypt/live/mitchellanicas.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/mitchellanicas.com/privkey.pem;
When you're done, it should look like this:
listen 443 ssl;
server_name example.com www.example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
Now we will add a few lines to the server block so that Nginx will only use the most
secure SSL protocols and ciphers:
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on;
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH'; Lastly, outside of the original server block,
we'll create a server block that will listen on port 80 and redirect the traffic to the
HTTPS server block that we just configured:
server { listen 80;
server_name mitchellanicas.com; return 301 https://$host$request_uri;
} Now save and exit the file. If you want to
see the completed example configuration file, check out the link in the annotations.
To put the changes into effect, restart Nginx with:
sudo service nginx restart The Let's Encrypt TLS/SSL certificate is now
in place. At this point, you should test that the TLS/SSL certificate works by visiting
your domain in a web browser. You can verify that the Let's Encrypt certificate is being
used by clicking on the lock icon in the address bar.
6. Set up certificate auto-renewal
Let's Encrypt certificates are valid for only 90 days. To avoid having to remember to manually
renew our certificates every three months, we can automate the renewal process. I'll
show you how to set up certificate auto-renewal now.
We'll be leveraging the Let's Encrypt Webroot authenticator. The Webroot plugin allows us
to use Nginx to serve a special file that the Let's Encrypt CA can read to verify that
your server should be issued a new or renewed certificate.
Open your Nginx configuration again:
sudo vim /etc/nginx/sites-enabled/default Under the SSL server block, add this location
block:
location ~ /.well-known { allow all;
} You will also want look up what your document
root is set to by searching for the root directive, as the path is required to use the Webroot
plugin. If you're using the default configuration file, the root will be /usr/share/nginx/html.
Save and exit.
Create a Let's Encrypt Configuration File
Next, we need to create a Let's Encrypt configuration file. This will allow us to use Let's Encrypt
to request an SSL certificate without user interaction, which is necessary to set up
a fully-automated renewal process.
Copy the example Let's Encrypt configuration file to /usr/local/etc with this command:
sudo cp /opt/letsencrypt/examples/cli.ini /usr/local/etc/le-renew-webroot.ini
Now open the file in an editor:
sudo vim /usr/local/etc/le-renew-webroot.ini Uncomment the email line and fill in your
email address.
email = manicas@digitalocean.com Then uncomment the domains line and enter
your domain names.
domains = mitchellanicas.com, www.mitchellanicas.com Be sure to put these in the same order that
you used when you requested the certificate the first time.
Then uncomment the webroot-path line and update it to match your Nginx document root.
webroot-path = /usr/share/nginx/html My server is using the default root path,
so I don't need to update it.
Your file should look something like this.
Save and exit when you're ready to move on.
Now we can use the configuration file with Let's Encrypt to request a certificate. Assuming
your configuration file is correct, these commands can be used to renew your certificate:
cd /opt/letsencrypt ./letsencrypt-auto certonly -a webroot --renew-by-default
--config /usr/local/etc/le-renew-webroot.ini Create a Renewal Script
To automate the renewal process, we will use a shell script that will verify the certificate
expiration date for the provided domain and request a renewal when the expiration is less
than 30 days away. This script will be scheduled to run once a week as a cronjob. This way,
even if the renewal request fails, there’s a 30-day window to try again every week.
First, download the script to /usr/local/sbin with this curl command:
sudo curl -L -o /usr/local/sbin/le-renew-webroot http://do.co/le-nginx-renew
Feel free to review the contents of the script.
Make it executable with:
sudo chmod +x /usr/local/sbin/le-renew-webroot The le-renew-webroot script takes an argument,
the domain name whose certificate you want to check for renewal. When the renewal is
not yet necessary, it will simply output how many days are left until the given certificate
will expire,,,,..
For example, if you run the script now, you will be able to see how many days are left
before your certificate will expire:
sudo le-renew-webroot Now that our renewal script is in place, all
we need to do is schedule a cron job that will run the script once a week. Open your
server's root crontab with:
sudo crontab -e Then add this line to execute the script every
Monday at 2:30am:
30 2 * * 1 /usr/local/sbin/le-renew-webroot >> /var/log/le-renewal.log
The output produced by the command will be sent to a log file located at /var/log/le-renewal.log.
Conclusion
That's it! Your web server is now using a free Let's Encrypt TLS/SSL certificate to
securely serve HTTPS content.