Search

HTTPS - Part 2 : Implementation


September 23, 2020 | 4 mins Jérémy Bernard

Introduction

As we have seen in the first part of this article dedicated to HTTPS, regarding web communication, security is essential. This second part is dedicated to its implementation, to show how easy it is to deploy free certificates, valid for 90 days and issued by a certified authority. To do so we will use Docker, Certbot and Nginx on a Linux server. Although this article does not deal with other web servers (like Apache for example), it is of course possible to implement HTTPS on those as well.

Prerequisites

  • Point the DNS record of the domain name to be secured to the server. In this article, we will use tls.example.com as an example.
  • Install Docker.
  • Install Nginx.
  • Make sure that no process is listening on ports 80 nor 443.

Step 1 - Retrieve Certificate

We will first use the official Certbot Docker Container to retrieve a TLS certificate for our subdomain to be secured:

docker run -it --rm --name certbot -p 80:80 -p 443:443 -v "/etc/letsencrypt:/etc/letsencrypt" -v "/var/lib/letsencrypt:/var/lib/letsencrypt" certbot/certbot certonly --standalone --email "user@example.com" -d "tls.example.com"

This command will start the Certbot application container. Let’s see what parameters are used here, starting with those passed to Docker itself:

  • -it tells Docker that we want to be able to interact with the application. You’ll probably have to accept the Certbot terms of use the first time you use Certbot.
  • --rm will delete the container once its work is done, without deleting the recovered certificates of course.
  • -p 80:80 -p 443:443 exposes the HTTP (80) and HTTPS (443) ports of the container, so it could be reached by Let’s Encrypt, which will in turn verify that you are the owner of the server.
  • -v "/etc/letsencrypt:/etc/letsencrypt" -v "/var/lib/letsencrypt:/var/lib/letsencrypt exposes to the container the folders necessary for Certbot to persistently store certificates on the server. Without these settings, the certificates would simply be destroyed along with the container at the end of execution.
  • certbot/certbot tells Docker which container to launch. Here is the official Certbot container.

The following parameters are those passed directly to Certbot:

  • certonly tells Certbot that we just want to retrieve a certificate.
  • --standalone launches the application in standalone mode, i.e. with its own web server (hence the need to pass the HTTP/HTTPS ports to the container, as seen above).
  • --email allows Let’s Encrypt to have a point of contact with the certificate holder and thus send him an email when the expiration date of the certificate is approaching.
  • -d indicates the domain name or sub-domain concerned by the certificate. It may be interesting to note that you can indicate several “-d domain_name” options here, if you want to have a single certificate for several domain names. The certificate in question will then have the name of the first domain passed as a parameter.

Once the command is executed, if everything went smoothly, you will find the certificate in the folder “/etc/letsencrypt/live/”.

Note that you can also retrieve a wildcard certificate, managing all the sub-domains of a domain name. In our example, this “super-certificate” can be retrieved by passing “*.example.com” to the “-d” option of Certbot. To do this, the apex DNS of “example.com” must of course point to your server.

Step 2 - Renewing certificates

This step is very simple, just use the “renew” parameter of Certbot:

docker run -it --rm --name certbot -p 80:80 -p 443:443 -v "/etc/letsencrypt:/etc/letsencrypt" -v "/var/lib/letsencrypt:/var/lib/letsencrypt" certbot/certbot renew

As you can see, this docker command is quite the same as the previous one. The only change here is the “renew” instruction passed to Certbot, which will check for each stored certificate if the expiration date is approaching (less than 10 days by default) and renew them if necessary.  

Step 3 - Using the certificate with Nginx

Now that our certificate is retrieved, let’s see what we have to do in Nginx to use HTTPS through this commented configuration example:

server {
    listen      443 ssl; # HTTPS port + ssl
    server_name tls.example.com; # Domain name

    ssl_certificate /etc/letsencrypt/live/tls.example.com/fullchain.pem; # Certificate path
    ssl_certificate_key /etc/letsencrypt/live/tls.example.com/privkey.pem; # Key path
    ssl_protocols TLSv1.2; # Enable encryption
    ssl_prefer_server_ciphers on;
    ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';

    root /www/;
}

server {
    listen      80; # HTTP port
    server_name tls.example.com; # Domain name
    return 301 https://$host$request_uri; # Automatic redirect to HTTPS
}

Conclusion

You can see how easy it is to implement HTTPS with Docker, Certbot and Nginx. If you want to learn more about it, feel free to read the detailed documentation of Nginx’s TLS configuration.

References

Author(s)

Jérémy Bernard

Mainly JavaScript and backend stuff.

Site is Ready for Offline Use