Free SSL certificates on Linux

SSL certificates to secure connections are nowadays an essential part of any system connected to the internet. The great folks over https://letsencrypt.org provide a free service to automatically issue valid certificates that are widely accepted so there is no excuse not to use them on every possible occasion.

This the same technology that secures connectivity when you are using https to access a webpage, connect to a service to send or receive e-mails, or transfer files. Let’s Encrypt issued millions of certificates in the past and they quickly became the number one provider of certificates.

It has always been possible to issue self-signed certificates but they come with compatibility issues, browser warnings, and various other nuisances that are automatically taken care of by using a proper certificate signed by a well-accepted authority.

Certificate expiry and automation

Most commercially available certificates are issued with 1-3 (and sometimes 5) years of validity. Their renewal (and the payment for it) is not automatic and they need to be copied to all the servers using them after renewal manually. This also means that any data breach that involves the certificate’s private key will offer the possibility to impersonate the cert’s owner until it expires. Let’s Encrypt certificates, on the other hand, are short-lived – the expiry is three months and they are supposed to be renewed one month before expiry automatically.

Technically, Let’s Encrypt certificates can only be issued automatically, by using a dedicated client. The conventional way of generating a certificate request using OpenSSL then submitting it to the certificate authority on a webpage doesn’t work with Let’s Encrypt, because the only way to use their service is running a client that connects to them using their standard API for issuing, validating, and renewing certificates.

Domain validation

The SSL certificates are connected to domain names, so proof of domain ownership should be provided to Let’s Encrypt to verify that the cert is issued to the rightful owner. There are two ways to validate a domain, custom DNS records or HTTP validation. The issuer server generates a random validation challenge that should be presented in DNS or HTTP so simply adding a static record or file to the webroot is not enough – the Let’s Encrypt client should take care of the validation by running a custom DNS or HTTP server or manually putting the challenge file into a pre-defined webroot location.

Introducing Cerbot

Certbot is the recommended command-line client to acquire, renew and manage Let’s Encrypt certificates. To run it, you will need a supported operating system, including Linux, Windows and MacOSX.

The client is downloadable from https://certbot.eff.org or installable by the operating system’s default package manager. It’s written in Python3, so it can run anywhere even without a package available by using Pip, to install it as a python package.

Installation under Debian or Ubuntu:

# apt-get install certbot

It depends on a couple of Python3 packages, so they will be installed as well.

Standalone operation

Most of the time, you’ll be running Certbot with a Webserver (Apache or Nginx) already installed. Certbot is also capable of running in standalone mode that will spin up a temporary webserver for the challenge-response validation so you won’t need one.

To acquire a certificate, simply run “certbot certonly” and select the appropriate options. Please make sure to allow firewall connections (outgoing to their API server and incoming to port 80), otherwise it will fail to run

# certbot certonly
...
1: Spin up a temporary webserver (standalone)
2: Place files in webroot directory (webroot)
Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 1
Enter email address (used for urgent renewal and security notices) (Enter 'c' to
cancel): test@email.com
...
Please enter in your domain name(s) (comma and/or space separated)  (Enter 'c'
to cancel): test.techtipbits.com
...
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/test.techtipbits.com/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/test.techtipbits.com/privkey.pem
...

If all goes well, the certificate is saved under /etc/letsencrypt/live and it’s ready to be used with your choice of server software.

The expiry is 3 months, they can all be automatically renewed by periodically running “certbot renew” – any certificate that’s >2 months old will be renewed on the next run.

By default, systemd or a cron job will automatically run “certbot renew” twice a day to make sure your certificates do not expire. If Certbot was installed manually, you’ll need to take care of it yourself by creating a cron job that runs “certbot renew” at least once a week (they advise to run this twice daily)

Example cron line to be saved in system wide cron (/etc/crontab or /etc/cron.d/certbot):

@weekly root certbot -q renew

Running Certbot with a web server installed

If a webserver is already installed, Cerbot won’t be able to spin up its own to server the challenge-response requests so we will need to find another way to verify web requests. Since a web server is already running on the machine, we can simply save those response files in the web root of the web server and allow it to serve these requests on its own.

This method doesn’t depend on what kind of webserver it is because all it needs is the file path of the webroot to save those temporary files for verification. In our example, the webroot is /var/www/html (the default in Debian) and we’re running Apache

# certbot certonly
...
1: Spin up a temporary webserver (standalone)
2: Place files in webroot directory (webroot)
Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 2
Please enter in your domain name(s) (comma and/or space separated)  (Enter 'c'
to cancel): test2.techtipbits.com
Input the webroot for test2.techtipbits.com: (Enter 'c' to cancel): /var/www/html
...
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/test2.techtipbits.com/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/test2.techtipbits.com/privkey.pem

Using Let’s Encrypt certificates

Certificate files are all saved under /etc/letsencrypt/live/domainname. They are mostly symlinks to numbered files in /etc/letsencrypt/archive but the bottom line is that they’re accessible at standard locations:

# ls -l /etc/letsencrypt/live/test.techtipbits.com/
total 4
lrwxrwxrwx 1 root root   44 Jun 14 12:02 cert.pem -> ../../archive/test.techtipbits.com/cert1.pem
lrwxrwxrwx 1 root root   45 Jun 14 12:02 chain.pem -> ../../archive/test.techtipbits.com/chain1.pem
lrwxrwxrwx 1 root root   49 Jun 14 12:02 fullchain.pem -> ../../archive/test.techtipbits.com/fullchain1.pem
lrwxrwxrwx 1 root root   47 Jun 14 12:02 privkey.pem -> ../../archive/test.techtipbits.com/privkey1.pem
-rw-r--r-- 1 root root  692 Jun 14 12:02 README

Here is an example httpd.conf block to configure Apache to use these in a virtual host:

SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/<your-domain>/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/<your-domain>/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/<your-domain>/chain.pem

Every time a certificate is renewed, these files / symlinks are updated to reflect the latest changes in certificates. Some services need to be reloaded to refresh SSL settings, including updated certificates. Certbot provides a mechanism to achieve this, files under /etc/letsencrypt/renewal-hooks/post are run after certificate updates – simply create a shell script that reloads sensitive services and chmod +x it to make it executable.

Related Posts