How to Secure Apache with Let’s Encrypt SSL on Ubuntu 22.04

Secure Apache with SSL on Ubuntu 22.04 – DevAnswers.net

This guide covers Ubuntu 22.04. Read the Ubuntu 26.04 edition.

We may earn a referral fee at no additional cost to you when you shop through the links on this page.

Ubuntu 22.04 LTS (Jammy Jellyfish), released April 2022, is a stable long-term support release with security updates until April 2027 (extendable to 2032 with Ubuntu Pro). This guide uses Certbot with the Apache plugin to obtain and configure a free Let’s Encrypt SSL certificate for your web server.

The following steps cover installing Certbot, obtaining a free Let’s Encrypt SSL certificate for your domain, configuring Apache for HTTPS with automatic HTTP redirection, enabling HSTS security headers, and setting up automatic certificate renewal.

Prerequisites 

Before you begin, ensure you have:

  • A server running Ubuntu 22.04 (Jammy Jellyfish) with a non-root user that has sudo privileges. See our initial server setup guide for Ubuntu 22.04 (Jammy Jellyfish) if needed.
  • Apache installed with a virtual host configured. Follow our How to Install Apache on Ubuntu 22.04 (Jammy Jellyfish) guide first.
  • A registered domain name with its DNS A record pointing to your server’s public IP address. Both example.com and www.example.com should resolve to the server. Let’s Encrypt does not issue certificates for bare IP addresses.
  • Ports 80 and 443 open in your firewall. If you followed the Apache guide and allowed Apache Full in UFW, both ports are already open.

Installing Certbot 

Certbot is the official Let’s Encrypt client that automates certificate issuance and Apache configuration. Install it along with the Apache plugin:

Terminal
sudo apt update && sudo apt install -y certbot python3-certbot-apache

Verify the installation:

Terminal
certbot --version

You should see the Certbot version number in the output, confirming a successful installation.

Obtaining an SSL Certificate 

Before requesting a certificate, verify that your domain resolves to your server’s IP address:

Terminal
host example.com

The output should show your server’s public IP. If it doesn’t, update your DNS A record at your domain registrar and wait for propagation before continuing.

DNS must be pointed correctly. Let’s Encrypt verifies domain ownership by making an HTTP request to your server on port 80. If your domain doesn’t resolve to this server, the certificate request will fail. DNS propagation can take up to 48 hours after changes.

Run Certbot with the Apache plugin to obtain and install your certificate. Replace example.com with your actual domain:

Terminal
sudo certbot --apache -d example.com -d www.example.com
If you only use one domain (no www subdomain), omit the second -d flag. You can also secure multiple subdomains by adding additional -d flags (e.g., -d blog.example.com).

Certbot will prompt you for the following:

  1. Email address — for certificate expiry notifications and account recovery. Enter a valid email.
  2. Terms of Service — you must agree (Y) to proceed.
  3. EFF mailing list — optional. Enter Y or N based on your preference.

Ubuntu 22.04 note: Certbot 1.x may ask whether to redirect HTTP traffic to HTTPS. Select option 2 (Redirect) to enable automatic redirection. On newer systems with Certbot 2.x, this is configured automatically.

If successful, you will see output confirming the certificate was issued and deployed:

Output
Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/example.com/fullchain.pem
Key is saved at:         /etc/letsencrypt/live/example.com/privkey.pem
This certificate expires on 2026-05-20.

Deploying certificate
Successfully deployed certificate for example.com
Successfully deployed certificate for www.example.com

Congratulations! You have successfully enabled HTTPS on
https://example.com and https://www.example.com
What Certbot did behind the scenes:
  • Obtained a trusted certificate from Let’s Encrypt via an HTTP-01 challenge
  • Created an SSL virtual host at /etc/apache2/sites-available/example.com-le-ssl.conf
  • Enabled Apache’s mod_ssl and mod_rewrite modules
  • Configured HTTP-to-HTTPS redirection in your original virtual host
  • Applied recommended TLS settings from /etc/letsencrypt/options-ssl-apache.conf
  • Reloaded Apache to apply all changes
Certbot failed? Common causes:
  • Domain not resolving: Verify your DNS A record points to this server’s IP
  • Port 80 blocked: Ensure sudo ufw status shows Apache Full allowed
  • No matching virtual host: Certbot needs an Apache virtual host with a ServerName matching your domain
  • Rate limit exceeded: Let’s Encrypt allows 5 duplicate certificates per domain per week. Wait and retry later.

Verifying HTTPS 

Open your browser and visit https://example.com. You should see your site served over HTTPS with a padlock icon in the address bar.

From the command line, verify the HTTPS response headers:

Terminal
curl -sI https://example.com

You should see HTTP/2 200 (or HTTP/1.1 200 OK) at the top of the response.

Next, verify that HTTP requests are automatically redirected to HTTPS:

Terminal
curl -sI http://example.com

You should see a 301 Moved Permanently response with a Location header pointing to https://example.com/. This confirms that all HTTP traffic is being redirected to the secure HTTPS version.

For a comprehensive security assessment, test your domain at SSL Labs. With Certbot’s default TLS configuration, you should receive an A or A+ rating.

Strengthening SSL Security 

Certbot’s default configuration provides solid SSL security, including modern TLS protocols and cipher suites managed via /etc/letsencrypt/options-ssl-apache.conf. To further protect your site, enable HTTP Strict Transport Security (HSTS), which instructs browsers to always use HTTPS even if a user types http:// in the address bar.

First, enable the Apache headers module:

Terminal
sudo a2enmod headers

Create a configuration file for SSL security headers:

Terminal
sudo nano /etc/apache2/conf-available/ssl-headers.conf

Add the following content:

ssl-headers.conf
<IfModule mod_headers.c>
    Header always set Strict-Transport-Security "max-age=31536000"
</IfModule>

Save and exit (press CTRL + X, press Y, then press ENTER)

Using a separate configuration file (rather than editing Certbot’s virtual host) keeps your customizations cleanly separated from Certbot-managed files and applies the header to all SSL virtual hosts on this server.

Enable the configuration, test, and reload Apache:

Terminal
sudo a2enconf ssl-headers
sudo apache2ctl configtest && sudo systemctl reload apache2

Verify the HSTS header is present:

Terminal
curl -sI https://example.com | grep -i strict

You should see:

Output
strict-transport-security: max-age=31536000
The max-age=31536000 value tells browsers to remember the HTTPS-only policy for one year (31,536,000 seconds). Once your site is stable on HTTPS, you can optionally add includeSubDomains and submit your domain to the HSTS preload list for browser-level enforcement. Only do this when you are certain all subdomains support HTTPS.

Automatic Certificate Renewal 

Let’s Encrypt certificates are valid for 90 days. Certbot installs a systemd timer that automatically checks for renewal twice daily and renews any certificate within 30 days of expiry.

Verify the renewal timer is active:

Terminal
sudo systemctl status certbot.timer

You should see active (waiting) in the output, along with the next scheduled run time.

Test the renewal process with a dry run (simulates renewal without making any changes):

Terminal
sudo certbot renew --dry-run

If the dry run completes without errors, automatic renewal is working correctly. You should see Congratulations, all simulated renewals succeeded in the output.

Certbot handles everything automatically. You do not need to set up cron jobs or manually renew certificates. If renewal fails, Certbot sends a notification to the email address you provided during setup.

Important File Locations 

Key paths for managing SSL certificates on Ubuntu 22.04 (Jammy Jellyfish):

  • Certificate (full chain): /etc/letsencrypt/live/example.com/fullchain.pem — The complete certificate chain sent to browsers.
  • Private Key: /etc/letsencrypt/live/example.com/privkey.pem — Your certificate’s private key. Keep this secure.
  • Apache SSL Virtual Host: /etc/apache2/sites-available/example.com-le-ssl.conf — Certbot-generated HTTPS configuration.
  • Renewal Configuration: /etc/letsencrypt/renewal/example.com.conf — Settings used for automatic renewal.
  • SSL Options: /etc/letsencrypt/options-ssl-apache.conf — Certbot-maintained TLS protocol and cipher settings.
  • HSTS Headers: /etc/apache2/conf-available/ssl-headers.conf — Custom security headers (created above).
  • Certbot Log: /var/log/letsencrypt/letsencrypt.log — Detailed log for troubleshooting certificate operations.

Conclusion 

Your Ubuntu 22.04 (Jammy Jellyfish) server is now secured with a free Let’s Encrypt SSL certificate, automatic HTTP-to-HTTPS redirection, HSTS security headers, and automated 90-day certificate renewal.

With SSL in place, your LAMP stack is production-ready. Your site benefits from encrypted connections, improved search engine rankings, and browser trust indicators. Consider deploying your application (WordPress, Laravel, or another PHP framework) or exploring advanced configurations such as HTTP/2, OCSP stapling, and Content Security Policy headers.

That’s the build doneOptional next: How to Install WordPress on Apache on Ubuntu 22.04
Support DevAnswers
Written, tested and maintained by one developer. Your support keeps these guides accurate and ad-light.
Buy me a coffee

Comments

Leave a reply