Enabling HTTPS & SSL Using Let’s Encrypt & Certbot
In this post I’ll show you how to add HTTPS/SSL to an existing website that uses Apache HTTP Server. I’ll generate a free SSL/TLS certificate using Let’s Encrypt, specifically the Certbot ACME Client. Additionally, we’ll cover:
- how to enable automatic renewal of SSL/TLS certificates.
- how to setup re-writes in Apache such that all HTTP requests are re-directed to HTTPS.
- how to setup re-writes in Apache such that all requests to www.foobar.com are re-directed to foobar.com.
This post builds on a previous post that covered installing Apache Web Server on an Ubuntu 18.04 LTS server in AWS. Thus the steps shown here assume that Apache Web Server is already installed, and that the underlying Linux distribution is Debian in nature. I assume the website domain is foobar.com and that a HTTP (port 80) virtual host configuration already exists.
Certbot Installation
The Certbot ACME Client simplifies the process of generating and installing free Let’s Encrypt SSL/TLS certificates, and configuring your web server to use them. In other words, it makes life easy. And there are few things I value more than an easy life.
Certbot is an open source project and, in my view, one of the most wonderful tools I have come across in recent years. It also has great documentation; you can select customized documentation for your particular web server and operating system. For the purposes of this article, Apache Web Server and Ubuntu 18.04 LTS (bionic): https://certbot.eff.org/lets-encrypt/ubuntubionic-apache
Installation
We start by installing Certbot.
sudo apt update sudo add-apt-repository ppa:certbot/certbot sudo apt update sudo apt install certbot python-certbot-apache
Apache Plugin
Certbot has an Apache plugin. By running it, Certbot will generate your SSL/TLS certificate and automatically configure Apache Web Server to use it. This is the magic of Certbot.
If you prefer, you can add a –certonly switch to the command so that it won’t touch your Apache configuration. Then you can configure Apache by hand. But why would you prefer that? I’ve done it the hard way before, so this time I’m taking the soft option. I will explain what the script does.
sudo certbot --apache
This command will produce output similar to that below. I elected to enable HTTPS for both foobar.com and www.foobar.com. I also elected to allow the script to configure re-direction from HTTP to HTTPS.
ubuntu@ip-172-31-4-95:/etc/apache2$ sudo certbot --apache Saving debug log to /var/log/letsencrypt/letsencrypt.log Plugins selected: Authenticator apache, Installer apache Enter email address (used for urgent renewal and security notices) (Enter 'c' to cancel): webmaster@foobar.com - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Please read the Terms of Service at https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must agree in order to register with the ACME server at https://acme-v02.api.letsencrypt.org/directory - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - (A)gree/(C)ancel: A - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Would you be willing to share your email address with the Electronic Frontier Foundation, a founding partner of the Let's Encrypt project and the non-profit organization that develops Certbot? We'd like to send you email about our work encrypting the web, EFF news, campaigns, and ways to support digital freedom. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - (Y)es/(N)o: N Which names would you like to activate HTTPS for? - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1: foobar.com 2: www.foobar.com - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Select the appropriate numbers separated by commas and/or spaces, or leave input blank to select all options shown (Enter 'c' to cancel): Obtaining a new certificate Performing the following challenges: http-01 challenge for foobar.com http-01 challenge for www.foobar.com Enabled Apache rewrite module Waiting for verification... Cleaning up challenges Created an SSL vhost at /etc/apache2/sites-available/foobar.com-le-ssl.conf Deploying Certificate to VirtualHost /etc/apache2/sites-available/foobar.com-le-ssl.conf Enabling available site: /etc/apache2/sites-available/foobar.com-le-ssl.conf Deploying Certificate to VirtualHost /etc/apache2/sites-available/foobar.com-le-ssl.conf Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1: No redirect - Make no further changes to the webserver configuration. 2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for new sites, or if you're confident your site works on HTTPS. You can undo this change by editing your web server's configuration. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 2 Enabled Apache rewrite module Redirecting vhost in /etc/apache2/sites-enabled/foobar.com.conf to ssl vhost in /etc/apache2/sites-available/foobar.com-le-ssl.conf - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Congratulations! You have successfully enabled https://foobar.com and https://www.foobar.com You should test your configuration at: https://www.ssllabs.com/ssltest/analyze.html?d=foobar.com https://www.ssllabs.com/ssltest/analyze.html?d=www.foobar.com - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at: /etc/letsencrypt/live/foobar.com/fullchain.pem Your key file has been saved at: /etc/letsencrypt/live/foobar.com/privkey.pem Your cert will expire on 2019-07-19. To obtain a new or tweaked version of this certificate in the future, simply run certbot again with the "certonly" option. To non-interactively renew *all* of your certificates, run "certbot renew" - Your account credentials have been saved in your Certbot configuration directory at /etc/letsencrypt. You should make a secure backup of this folder now. This configuration directory will also contain certificates and private keys obtained by Certbot so making regular backups of this folder is ideal. - If you like Certbot, please consider supporting our work by: Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate Donating to EFF: https://eff.org/donate-le ubuntu@ip-172-31-4-95:/etc/apache2$
Certificates
This generated certificates are:
- /etc/letsencrypt/live/foobar.com/fullchain.pem
- /etc/letsencrypt/live/foobar.com/privkey.pem
HTTPS (Port 443) Virtual Host Configuration
Certbot automatically generates an Apache virtual host configuration for HTTPS (port 443) based on your HTTP (port 80) configuration. As per my earlier post, my HTTP (port 80) virtual host configuration is:
<VirtualHost *:80> Include sites-available/foobar.com.common.conf </VirtualHost>
It produces a new file: /etc/apache2/sites-available/foobar.com-le-ssl.conf
With the following quite obvious contents:
<IfModule mod_ssl.c> <VirtualHost *:443> Include sites-available/foobar.com.common.conf Include /etc/letsencrypt/options-ssl-apache.conf SSLCertificateFile /etc/letsencrypt/live/foobar.com/fullchain.pem SSLCertificateKeyFile /etc/letsencrypt/live/foobar.com/privkey.pem </VirtualHost> </IfModule>
HTTPS (Port 443) Virtual Host Enabling
Certbot automatically enables the HTTPS virtual host. Thus it does the equivalent of:
sudo a2ensite foobar.com-le-ssl.conf sudo systemctl reload apache2
Apache SSL Module Enabling
It also automatically enables the Apache SSL module. Thus it does the equivalent of:
sudo a2enmod ssl sudo systemctl reload apache2
SSL/TLS Version Configuration
The /etc/letsencrypt/options-ssl-apache.conf file referenced in the virtual host configuration is automatically generated. This configures various SSL options. Of particular interest is the the SSLProtocol field that limits the supported SSL and TLS versions. As can be seen, Certbot disables the obsolete V2 and V3 of SSL.
SSLProtocol all -SSLv2 -SSLv3 SSLCipherSuite ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS SSLHonorCipherOrder on SSLCompression off
HTTP URL Rewrites
Commands are automatically added to the HTTP (port 80) virtual host file to automatically re-write HTTP requests to HTTPS. These rules rewrite http://foobar.com to https://foobar.com and http://www.foobar.com to https://www.foobar.com. In this way, it becomes impossible to access the site over HTTP.
<VirtualHost *:80> Include sites-available/foobar.com.common.conf RewriteEngine on RewriteCond %{SERVER_NAME} =foobar.com [OR] RewriteCond %{SERVER_NAME} =www.foobar.com RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent] </VirtualHost>
Automatic Certificate Renewal
Automatic renewals are enabled by Certbot creating a cron job /etc/cron.d/certbot that triggers renewal checks every 12 hours.
# /etc/cron.d/certbot: crontab entries for the certbot package # # Upstream recommends attempting renewal twice a day # # Eventually, this will be an opportunity to validate certificates # haven't been revoked, etc. Renewal will only occur if expiration # is within 30 days. # # Important Note! This cronjob will NOT be executed if you are # running systemd as your init system. If you are running systemd, # the cronjob.timer function takes precedence over this cronjob. For # more details, see the systemd.timer manpage, or use systemctl show # certbot.timer. SHELL=/bin/sh PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin 0 */12 * * * root test -x /usr/bin/certbot -a \! -d /run/systemd/system && perl -e 'sleep int(rand(43200))' && certbot -q renew
Manual Tweaks
Although the Certbot Apache plugin does a great job of configuring Apache, there’s still a couple of things I like to tweak.
WWW Redirection
The automatic configuration will still serve https://www.foobar.com. So I add the following lines to /etc/apache2/sites-available/foobar.com-le-ssl.conf so that https://www.foobar.com is redirected to https://foobar.com.
RewriteEngine On RewriteCond %{SERVER_NAME} =www.foobar.com RewriteRule ^ https://foobar.com%{REQUEST_URI} [END,NE,R=permanent]
More Efficient HTTP Redirection
I modify LetsEncrypt’s modification to the port 80 virtual host file to make it more efficient. By definition, all accesses to port 80 need to be redirected to HTTPS, so we don’t need any re-write condition. I also ensure www is stripped, so it won’t be done again on port 443.
<VirtualHost *:80> Include sites-available/foobar.com.common.conf RewriteEngine on RewriteRule ^ https://foobar.com%{REQUEST_URI} [END,NE,R=permanent] </VirtualHost>