One of the greatest advances towards securing the Internet happened on April 12, 2016 when the Internet Security Research Group (ISRG) launched the “Let’s Encrypt” X.509 Transport Layer Security (TLS) (you may recognize it by the older SSL moniker) Certificate Authority. Major sponsors of the ISRG include the Electronic Frontier Foundation (EFF), the Mozilla Foundation, Akamai, and Cisco. The purpose of Let’s Encrypt is to provide free TLS certificates to anyone that can prove they own a domain so that they can secure the communications between their clients and their server through encryption. The service is fully automated and renewals are automated as well, keeping the certificates current and validated.

However, securing your website is but one communication channel that you’ll want to encrypt. If you run a mail server, you will also want to encrypt both the sending (server to server) communications (SMTP) as well as the client communications that happen from your personal computer to the mail server (IMAP). However, Let’s Encrypt wasn’t designed to automate these types of use cases, the focus for them is on web servers. Fortunately, these channels all use X.509 certificates and you can use your web server’s Let’s Encrypt TLS certificate to also secure your SMTP and IMAP communications as well.

Securing the Web Server

The first step to securing your web server is to get Let’s Encrypt installed and running on your server. Unfortunately, this is also where we run into some initial confusion. Ubuntu 16.04 LTS (which is what I run) has a native package called letsencrypt, but oddly the most current version of the Let’s Encrypt management package is actually called certbot. But, there is no package in Ubuntu 16.04 LTS for certbot. So, what are you supposed to do? Well, you CAN just use the native letsencrypt package, but you’ll have to handle renewals manually. As this is what is available natively, I’m going to cover just using letsencrypt initially for both initial certificate retrieval, configuration, and then walk through a renewal. I’ll then show you how to get certbot up and running on Ubuntu 16.04 LTS, so you can have automatic renewals.

Install Let’s Encrypt

I’m going to cover setting up Let’s Encrypt using the letsencrypt binary, this is how I started out. There are downsides, so you may want to skip ahead and perform the certbot installation rather than going through a migration later in the article. However, this will get you going, without having to add repositories to your installation, and then I’ll show you how to migrate to certbot afterwards.

To install letsencrypt on your Ubuntu 16.04 LTS installation just do:
sudo apt-get update
sudo apt-get install letsencrypt

You’ll now have a /usr/bin/letsencrypt binary installed on your system ready to assist you in acquiring a X.509 TLS certificate and later to renew it.

Obtaining your first X.509 TLS certificate

The assumption at this point is that you already have a web server up and running on your server. If you do not, then you’re going to need one before you move through the rest of this tutorial. The reason is that Let’s Encrypt will perform various validations by fetching files from your web server. Even if you don’t want to secure a web server and you only want a Let’s Encrypt certificate for SMTP and IMAP use, you’ll have to set up a web server to handle the validation steps. You can set one up that doesn’t serve any pages and just handles this validation if you’d like.

These instructions will be for the Apache2 webserver, but can be adapted to work with nginx as well. Modify your /etc/apache2/sites-enabled/000-default.conf file with the following lines:

# Add Alias For Lets Encrypt WebRoot Authentication Using ACME
AliasMatch ^/.well-known/acme-challenge/(.*)$ /var/www/html/.well-known/
acme-challenge/$1
Alias /.well-known/acme-challenge/ /var/www/html/.well-known/acme-challenge/
<Directory "/var/www/html/.well-known/acme-challenge/">
   Options None
   AllowOverride None
   ForceType text/plain
   RedirectMatch 404 "^(?!/\.well-known/acme-challenge/[\w-]{43}$)"
</Directory>

Restart Apache2 for these changes to take affect. These lines will allow the Let’s Encrypt server to pull a file from the /var/www/html/.well-known/acme-challenge directory in order to verify the identity of your web server. Make sure you create that directory for the next step.

mkdir /var/www/html/.well-known/acme-challenge

You’re now ready to pull a TEST certificate from Let’s Encrypt to confirm your installation is working. Please replace dnsadmin@mydomain.com with your administrative email (needs to be valid, this is where expiration notices will be sent) and replace mail.mydomain.com with your server name.

sudo letsencrypt certonly --agree-tos --rsa-key-size 4096 --renew-by-default -m dnsadmin@mydomain.com --webroot -w /var/www/html/ -d mail.mydomain.com --renew-by-default --test-cert

If all goes well, you should get a message like the following, indicating that a test certificate was created and pulled.

IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/mail.mydomain.com/fullchain.pem. Your cert
   will expire on 2017-11-24. To obtain a new version of the
   certificate in the future, simply run Let's Encrypt again.

Note: In my testing of —test-cert it appears that it DOES in fact create a private key and valid public keys for the certificate in question, and stores them in the directory indicated. However, these are TEST certificates and should be replaced with a non-test certificate after verifying that everything is working properly.

If the certificate was properly created, then you should be ready to create your new certificate, just remove —test-cert from the above command and re-run it:

sudo letsencrypt certonly --agree-tos --rsa-key-size 4096 --renew-by-default -m dnsadmin@mydomain.com --webroot -w /var/www/html/ -d mail.mydomain.com --renew-by-default

Install your new Let’s Encrypt certificate for Apache2

You should now have your X.509 certificate and associated private key, as well as the CA public key chain all stored in /etc/letsencrypt/live/mail.mydomain.com which was the directory you specified.

To utilize these certificates, you’ll have to modify the SSL configuration for your Apache2 webserver. The SSL configuration is stored in /etc/apache2/sites-enabled/default-ssl.conf. Modify the various certificate lines to reflect:

SSLCertificateFile    /etc/letsencrypt/live/mail.mydomain.com/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/mail.mydomain.com/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/mail.mydomain.com/fullchain.pem

These three lines will instruct your Apache web server to use your Let’s Encrypt certificates to secure TLS communications with clients. Restart Apache2 after making these changes.

Install your new Let’s Encrypt certificate for Postfix

To utilize your new certificates within your Postfix installation, edit the /etc/postfix/main.cf file with the following changes, some of these will also strengthen the security of your Postfix installation, you technically will only need the cert_file and key_file lines, but the rest are best practice:

smtpd_use_tls=yes
smtpd_tls_auth_only = yes
smtpd_tls_cert_file = /etc/letsencrypt/live/mail.mydomain.com/fullchain.pem
smtpd_tls_key_file = /etc/letsencrypt/live/mail.mydomain.com/privkey.pem
#Disable Poodle
smtp_tls_security_level = may
smtpd_tls_mandatory_protocols=!SSLv2,!SSLv3
smtp_tls_mandatory_protocols=!SSLv2,!SSLv3
smtpd_tls_protocols=!SSLv2,!SSLv3
smtp_tls_protocols=!SSLv2,!SSLv3
Changes to SSL Ciphers
tls_preempt_cipherlist = yes
smtpd_tls_mandatory_ciphers = high
tls_high_cipherlist = ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384

Now restart Postfix to start using the new configuration.

Install your new Let’s Encrypt certificate for Dovecot

To utilize your new certificates within your Dovecot installation, edit the /etc/dovecot/conf.d/10-ssl.conf file with the following changes:

ssl_cert = </etc/letsencrypt/live/mail.mydomain.com/fullchain.pem
ssl_key = </etc/letsencrypt/live/mail.mydomain.com/privkey.pem

Then restart your Dovecot service to begin using them.

Testing your new installations

First, let’s test your Apache2 web server. You should just go to https://mail.mydomain.com/ and it should show you a lock icon without any errors displayed. You should then inspect the certificate coming from your server where you should see something like:

Certificate Inspection

If the certificate is working for your Apache2 installation, then move on to testing Postfix and Dovecot. In order to test both, you can go to the site EmailSecurityGrader. Plug in your mydomain.com and an email where they can send your report and hopefully you’ll find out you have a secure Postfix and Dovecot installation.

Renewing your Let’s Encrypt certificate

By default, Let’s Encrypt TLS certificates are good for 90 days. That means that every 90 days (or a bit sooner), you’ll need to renew your X.509 certificate with Let’s Encrypt. Since we used letsencrypt there is no automated way to renew these certificates, but it’s not that hard.

Just re-run the original command you used to acquire the certificate in the first place:

sudo letsencrypt certonly --agree-tos --rsa-key-size 4096 --renew-by-default -m dnsadmin@mydomain.com --webroot -w /var/www/html/ -d mail.mydomain.com --renew-by-default

This should renew the certificate and install it. You’ll need to restart all of your services (Apache2, Postfix, Dovecot) to get them to use the renewed versions of the certificate. You should also test your services following the renewal, just to ensure that the renewal did in fact work properly.

Migrating to Certbot

Certbot is the official client from EFF for Let’s Encrypt. You can read more about Certbot here. It also offers a lot of other features, such as automatic configuration for various services (e.g. Apache2).

If you followed my tutorial above, you’re using letsencrypt. To install certbot on Ubuntu 16.04 LTS, perform the following:

sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update
sudo install certbot

You should now have a working certbot installation. To use it, you can just replace letsencrypt in the tutorial commands with certbot. However, we want to do a little bit of automation, so the first thing is to check if it will automatically renew our existing certificates:

sudo certbot renew —dry-run

The —dry-run will simulate a renewal and you’ll be able to find any errors. If everything works properly, you’re ready to auto-renew your certificates. To do this, you should set up a crontab entry under the root user that will run twice a day and check for renewals (twice a day is the suggestion provided in the documentation, if the certs are not due for renewal, nothing will happen). Here is the crontab entry on my server:

52 0,12 /usr/bin/certbot renew --quiet

You will now automatically renew your certificates when their expiration date is close.

Note: You’ll need to also restart your various servers so they see the new certificate (this could be accomplished by writing a script that restarts all three servers and then calling that script in the above crontab entry with —post-hook or —renew-hook).

Hope this helps you get established with Let's Encrypt X.509 TLS certificates on all of your services.