Let’s Encrypt is a free, automated certificate authority run by the Internet Security Research Group (ISRG). It issues SSL certificates trusted by all major browsers, and the entire process — from validation to renewal — is handled automatically by a tool called Certbot.
This guide shows you how to secure Apache with Let’s Encrypt on Ubuntu 18.04, apply strong TLS settings, and configure automatic certificate renewal.
Prerequisites: Apache installed on your server with a virtual host configured for your domain, and a domain name pointing to your server’s IP address.
Install Certbot
Certbot is available in the Ubuntu default repositories. Update the package list and install it:
bash
sudo apt update<br>sudo apt install certbot<br>Generate Diffie-Hellman Parameters<br>A strong Diffie-Hellman (DH) group improves the security of key exchanges during TLS handshakes. Generate a 2048-bit DH parameter file:
bash
sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
This takes a few minutes. Increasing the size to 4096 bits gives stronger security but may take over 30 minutes to generate.
Obtain the SSL Certificate
Certbot uses the webroot plugin to verify that you control the domain. It places a temporary validation file on your server, and the Let’s Encrypt servers confirm it over HTTP.
Create the validation directory and set the correct permissions:
bash
sudo mkdir -p /var/lib/letsencrypt/.well-known<br>sudo chgrp www-data /var/lib/letsencrypt<br>sudo chmod g+s /var/lib/letsencrypt<br>Create two Apache configuration snippets. The first maps the ACME challenge path to your webroot directory:
/etc/apache2/conf-available/letsencrypt.conf
apache
Alias /.well-known/acme-challenge/ "/var/lib/letsencrypt/.well-known/acme-challenge/"<br>AllowOverride None Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec Require method GET POST OPTIONS<br>The second snippet applies strong TLS settings, disables older protocols (TLS 1.0 and 1.1), enables OCSP stapling, and sets security-focused HTTP headers including HSTS:
/etc/apache2/conf-available/ssl-params.conf
apache
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1<br>SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384<br>SSLHonorCipherOrder off<br>SSLSessionTickets off<br>SSLUseStapling On<br>SSLStaplingCache "shmcb:logs/ssl_stapling(32768)"<br>Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"<br>Header always set X-Frame-Options SAMEORIGIN<br>Header always set X-Content-Type-Options nosniff<br>SSLOpenSSLConfCmd DHParameters "/etc/ssl/certs/dhparam.pem"<br>Enable the required Apache modules and both config files, then reload:
bash
sudo a2enmod ssl<br>sudo a2enmod headers<br>sudo a2enmod http2<br>sudo a2enconf letsencrypt<br>sudo a2enconf ssl-params<br>sudo systemctl reload apache2<br>Run Certbot to request the certificate using the webroot plugin:
bash
sudo certbot certonly –agree-tos –email admin@example.com –webroot -w /var/lib/letsencrypt/ -d example.com -d www.example.com
On success, Certbot saves the certificate and private key to /etc/letsencrypt/live/example.com/.
Configure Apache for HTTPS
Edit your domain’s virtual host file to force HTTPS and use the new certificate:
/etc/apache2/sites-available/example.com.conf
apache
ServerName example.com ServerAlias www.example.com Redirect permanent / https://example.com/
ServerName example.com ServerAlias www.example.com Protocols h2 http/1.1 Redirect permanent / https://example.com/ DocumentRoot /var/www/example.com/public_html SSLEngine On SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
This forces HTTPS on all traffic and redirects the www subdomain to the non-www version. Reload Apache:
bash
sudo systemctl reload apache2
Your site now runs over HTTPS. Testing with the SSL Labs Server Test should return an A+ grade.
Set Up Automatic Certificate Renewal
Let’s Encrypt certificates expire after 90 days. Certbot installs a cron job that checks for expiring certificates twice daily and renews them automatically when they are within 30 days of expiry.
Add a reload hook so Apache picks up the renewed certificate without any manual steps. Edit /etc/cron.d/certbot so the entry reads:
bash
0 */12 * * * root test -x /usr/bin/certbot -a ! -d /run/systemd/system && perl -e 'sleep int(rand(3600))' && certbot -q renew --renew-hook "systemctl reload apache2"<br>Test the renewal process with a dry run:
bash
sudo certbot renew --dry-run<br>If no errors appear, your automatic renewal is configured correctly.
Apache is now secured with a free Let’s Encrypt SSL certificate on Ubuntu 18.04. Your site loads over HTTPS, your certificate renews itself automatically, and your server configuration scores an A+ on SSL Labs. Leave a comment below if you run into any issues.