Using Let's Encrypt certificates

22 Oct 2015

Now that Let's Encrypt is a trusted certificate authority in major browsers and that I got access to the beta program, I decided to take it for a spin in my server with nginx (and uWSGI).


Pretty straightforward:

$ git clone https://github.com/letsencrypt/letsencrypt

I saved that into /opt/letsencrypt just in case.


Also pretty straightforward:

$ ./letsencrypt-auto --agree-dev-preview --server https://acme-v01.api.letsencrypt.org/directory auth

This will setup the virtual environment that letsencrypt will use in all future executions. Once that's done, you are asked for authentication options (manual or automatic). When choosing the manual one (at least for the first time), you have to introduce your email address, which I guess is the one used to sign up/register domains.

Now it's time to get the certificate. You will be prompted for a space/comma separated list of domains for which to generate the certificate, in my case rmedgar.com and www.rmedgar.com. Let's Encrypt needs to verify ownership of the server in which the certificate is going to be deployed, so it asks you to create a file with specific contents that should be served by your HTTP server. Funny thing is, rmedgar.com just redirects to www.rmedgar.com, which is my Flask application running under uWSGI, and given that I'm no expert in these matters, this may be problematic.

But never fear! The tool provides you with another alternative: running a very simple python server that serves the authentication file, and it even gives you the commands to execute!. I don't really mind having a bit of downtime here, so taking down nginx for a bit is no problem:

# systemctl stop uwsgi.service
# systemctl stop nginx.service

The authentication tokens are given to you one by one for each domain you introduced previously, so after running the server command given to me, I had to validate for www.rmedgar.com. Because I didn't want to risk it, good old Ctrl+Z to stop the server, create the file with the content, and then:

# fg

Voilá, authenticated and certificate generated. The server is not needed anymore, so simply interrupt its execution.

Using the certificate

Given that I am generating the certificate in my own computer instead of in the server itself, I have to copy things around. The letsencrypt tool tells you that your certificates live in /etc/letsencrypt/live/YOUR_DOMAIN. The files there are actually symbolic links to /etc/letsencrypt/archive/YOUR_DOMAIN/fileX.pem.

Now, I'm just going to copy two files to the server:

fullchain.pem ~> /etc/ssl/rmedgar_com.pem
privkey.pem ~> /etc/ssl/rmedgar_com.key

Time to setup nginx! The plan is: redirect all HTTP requests to HTTPS and have the domain/subdomains listen to port 443. My edited /etc/nginx/sites-available/default/ file looks like this:

server {
        listen 80;
        # All subdomains
        # server_name rmedgar.com *.rmedgar.com;
        server_name rmedgar.com www.rmedgar.com;

        return 301 https://$host$request_uri$is_args$args;

server {
        listen 443 ssl;

        ssl on;
        ssl_certificate /etc/ssl/rmedgar_com.pem;
        ssl_certificate_key /etc/ssl/rmedgar_com.key;


I'm not using the *.rmedgar.com wildcard here because only www.rmedgar.com is whitelisted, but in the future I'd like the rest to use HTTPS as well.

Restart nginx (and uWSGI) and done:

# systemctl restart nginx.service
# systemctl restart uwsgi.service

Tags: ssl security certificate let's encrypt nginx


My name is Rafael Medina, and I like code.

More about me.