How to Secure Apache2 with Let’s Encrypt on Ubuntu 22.04

4 min read

This guide shows you how to secure Apache2 with a free SSL certificate from Let’s Encrypt on Ubuntu 22.04 using Certbot. By the end, your site will serve traffic over HTTPS with automatic certificate renewal.

Prerequisites

Step 1: Set Up Your Apache Virtual Host

Certbot reads your Apache config to find the domain it needs to secure. Make sure you have a VirtualHost for your domain:

sudo nano /etc/apache2/sites-available/example.com.conf

Add a basic configuration:

<VirtualHost *:80>
    ServerName example.com
    ServerAlias www.example.com
    DocumentRoot /var/www/example.com

    <Directory /var/www/example.com/>
        AllowOverride All
        Require all granted
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

Enable the site and reload Apache:

sudo a2ensite example.com.conf
sudo apache2ctl configtest && sudo systemctl reload apache2

If configtest shows Syntax OK, you’re ready for the next step.

Step 2: Install Certbot via Snap

The Certbot team recommends installing via snap instead of apt. The snap package stays up to date automatically and is the officially supported method.

Remove any old Certbot packages

If you previously installed Certbot through apt, remove it first to avoid conflicts:

sudo apt remove certbot -y

Install Certbot with the Apache plugin

sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/local/bin/certbot
  • snap install --classic certbot — installs Certbot with full system access (needed to modify Apache configs and write certificates)
  • ln -s — creates a symlink so you can run certbot from anywhere

Step 3: Obtain and Install the SSL Certificate

Run Certbot with the --apache plugin. This verifies your domain, gets the certificate, updates your Apache config, and sets up an HTTP-to-HTTPS redirect:

sudo certbot --apache -d example.com -d www.example.com --non-interactive --agree-tos --no-eff-email --redirect -m you@example.com
  • --apache — uses the Apache plugin to handle config changes automatically
  • -d — the domain names to secure (include both root and www)
  • --non-interactive — runs without prompts
  • --agree-tos — accepts the Let’s Encrypt terms of service
  • --no-eff-email — skips the EFF newsletter signup
  • --redirect — adds HTTP-to-HTTPS redirect automatically
  • -m — email address for renewal notices and urgent security alerts

If successful, you’ll see output like:

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

Step 4: Verify the Apache Configuration

Certbot creates a new SSL VirtualHost file. Check it:

sudo nano /etc/apache2/sites-available/example.com-le-ssl.conf

You should see a VirtualHost block on port 443 with SSL directives:

<IfModule mod_ssl.c>
<VirtualHost *:443>
    ServerName example.com
    ServerAlias www.example.com
    DocumentRoot /var/www/example.com

    SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
    Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
</IfModule>

Certbot also adds redirect rules to your original port 80 VirtualHost using mod_rewrite, so all HTTP traffic is forwarded to HTTPS.

Test and reload:

sudo apache2ctl configtest && sudo systemctl reload apache2

Step 5: Test HTTPS and Auto-Renewal

Open https://example.com in your browser. You should see the padlock icon confirming HTTPS is active. Also try http://example.com to verify it redirects to HTTPS.

Let’s Encrypt certificates expire every 90 days. The Certbot snap package includes a systemd timer that checks for renewal twice a day. Test that it works:

sudo certbot renew --dry-run

If the dry run completes without errors, renewal is working. No cron job needed — the snap handles it.

Troubleshooting

Common issues and quick fixes:

  • “Unable to find a virtual host” — your ServerName in the Apache config doesn’t match the -d domain you passed to Certbot. Fix the VirtualHost and reload Apache before retrying.
  • “Problem binding to port 80” — another process is using port 80, or Apache isn’t running. Check with sudo ss -tlnp | grep :80.
  • “DNS problem: NXDOMAIN” — your domain’s A record doesn’t point to this server’s IP yet. Verify with dig example.com.
  • Rate limits — Let’s Encrypt allows 5 duplicate certificates per domain per week. Use the --staging flag when testing to avoid hitting limits.
  • mod_ssl not enabled — Certbot needs mod_ssl. Enable it with sudo a2enmod ssl && sudo systemctl restart apache2.

Conclusion

Your Apache2 server now serves traffic over HTTPS with a free Let’s Encrypt certificate that renews automatically. If you’re running Nginx on other servers, see How to Secure Nginx with Let’s Encrypt on Ubuntu 22.04. To set up monitoring on your Apache server, check out How to Install Datadog Agent with Apache2 on EC2 Ubuntu 22.04.