How To Setup A LetsEncrypt SSL Certificate For Your Rails App On Nginx

Muaad Abdirahman
3 min readJan 26, 2018

--

Let’s Encrypt is a Certificate Authority (CA) that provides an easy way to obtain and install free TLS/SSL certificates, thereby enabling encrypted HTTPS on web servers. It simplifies the process by providing a software client, Certbot, that attempts to automate most (if not all) of the required steps. Currently, the entire process of obtaining and installing a certificate is fully automated on both Apache and Nginx web servers. In this article, I will show you how to set it up for Nginx.

Steps:

  1. Create .well_known directory:
mkdir /usr/share/nginx/html/.well_known

2. Download Lets Encrypt client

sudo git clone https://github.com/letsencrypt/letsencrypt /opt/letsencrypt

3. When requesting for the certificate, I have always come across some locale error. To fix that, run the following commands:

export LC_ALL="en_US.UTF-8"
export LC_CTYPE="en_US.UTF-8"

4. If you have a firewall running on your server, make sure port 443 is open:

sudo ufw allow 443/tcp

5. Update your Nginx configuration. Add the following to your sites-available Nginx file:

location ~ /.well-known {
allow all;
root /usr/share/nginx/html;
}

This step is required for the next since LetsEncrypt is going to try to verify that you own the domain. It does so by writing a file to the .well_known directory we had created earlier.

6. Get the certificate:

/opt/letsencrypt/letsencrypt-auto certonly --webroot -w /usr/share/nginx/html -d 'mysite.com,www.mysite.com'

Update 1: You might run into an issue here where the certificate will fail to download. You will run into an error like this:

Certbot has problem setting up the virtual environment.We were not be able to guess the right solution from your pipoutput.

Last time I checked, there was no fix ready. You can find a few suggestions in this issue. The one solution that worked for me was setting this environment variable:

export VIRTUALENV_NO_DOWNLOAD=1

Update 2: You might also run into this error below:

You can find more on this error here in this GitHub issue. The solution as per this comment is running the command below:

export LC_ALL="C"

Once LetsEncrypt verifies your domain name, you will need to make changes to your Nginx config to be able to support requests to port 443.

You will make the following change to your sites-available Nginx config file.

7. Add these two lines at the top of your sites-available Nginx config file:

ssl_certificate /etc/letsencrypt/live/mysite.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mysite.com/privkey.pem;

8. You will need to redirect all HTTP traffic to HTTPS. To do that, add another server block:

server {
listen 80;
server_name mysite.com www.mysite.com;
return 301 https://www.mysite.com$request_uri;
}

9. Comment out or remove the lines that tell Nginx to listen on port 80:

#listen 80; ## listen for ipv4; this line is default and implied#listen [::]:80 ipv6only=on default_server;

10. And finally, paste these lines:

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
ssl_prefer_server_ciphers on;
ssl_stapling on;
ssl_stapling_verify on;
ssl_session_cache shared:SSL:128m;
ssl_session_timeout 120m;

NB: You should of course replace “mysite.com” with your domain name.

That should be enough to get you up and running with your free SSL certificate.

Your final configuration should look something like this:

Setting up auto-renew

To enable automatic renewal of your certificate, follow the following steps to create a Cron task that would handle it automatically for you:

1. Open crontab in your command line editor of choice:

sudo crontab -e

2. Paste in the following:

30 2 * * 1 /opt/letsencrypt/letsencrypt-auto renew >> /var/log/le-renew.log 
35 2 * * 1 /etc/init.d/nginx reload

This will create a new cron job that will execute the auto renew command every Monday at 2:30 am, and reload Nginx at 2:35am (so the renewed certificate will be used). The output produced by the command will be piped to a log file located at /var/log/le-renew.log. Create this log file if it doesn’t already exist:

touch /var/log/le-renew.log

That is it. Your SSL certificate is now up and running and it gets renewed automatically. You don’t have to keep an eye on it. Go save the world while protecting your users’ information.

--

--