Skip to content
DevOps devops domains 6 min read

Securing Apache with Certbot

HTTPS (HyperText Transfer Protocol Secure) is what turns the padlock icon on in your browser. It encrypts the traffic between a visitor and your server so nobody in between can read or tamper with it. If you run a website on the Apache web server (one of the oldest and most widely used web servers on Linux), the easiest way to get HTTPS is Certbot — a free tool that talks to Let’s Encrypt, gets you a real SSL/TLS certificate, and rewrites your Apache config for you. This page walks through doing exactly that on Ubuntu, end to end.

What Certbot does for Apache

A certificate is a small file that proves your server really owns your domain. Without one, browsers show a scary “Not Secure” warning. Certbot automates the whole certificate lifecycle: it proves you control the domain, downloads the certificate, and — with the Apache plugin — edits your Apache virtual host (a “vhost” is Apache’s config block for one website) so the site serves HTTPS immediately.

The key piece is the Apache plugin, a package called python3-certbot-apache. It knows how to read and write Apache config files, so Certbot doesn’t just hand you a certificate and leave you to wire it up by hand. It creates a new SSL vhost and can add an automatic redirect from http:// to https://.

When to use this: you have an Apache site already serving plain HTTP on a real domain (not an IP address) and you want HTTPS with the least effort. When NOT to use this: if you sit behind a separate load balancer or CDN (Content Delivery Network) that already terminates TLS for you, or if you use Nginx instead — in that case see the Nginx Certbot page.

Before you start

You need three things in place:

  1. A domain name (for example example.com) with a DNS A record (the record that maps a name to an IPv4 address) pointing at your server’s public IP.
  2. Apache already installed and serving the site on port 80 (HTTP).
  3. The firewall allowing HTTP and HTTPS.

Check Apache is running and open the firewall:

sudo systemctl status apache2
sudo ufw allow 'Apache Full'
sudo ufw status

ufw is the Uncomplicated Firewall, Ubuntu’s simple front end for managing firewall rules. The Apache Full profile opens both port 80 (HTTP) and port 443 (HTTPS).

Output:

Status: active

To                         Action      From
--                         ------      ----
Apache Full                ALLOW       Anywhere
Apache Full (v6)           ALLOW       Anywhere (v6)

Certbot proves you own the domain by briefly serving a file over port 80. If your DNS A record is wrong or port 80 is blocked, the challenge fails and you get no certificate. Fix DNS first.

Install Certbot and the Apache plugin

On Ubuntu 22.04 and 24.04 the recommended way to install Certbot is via snap, the universal package format that ships with Ubuntu. This gives you the newest Certbot version. Install the core tool, then make the certbot command available system-wide:

sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot

The Apache plugin ships inside the snap, so no separate install is needed. If you prefer the older apt route instead, you would run sudo apt install certbot python3-certbot-apache — but snap is preferred in 2026 because it stays current automatically.

Verify it works:

certbot --version

Output:

certbot 3.1.0

Run Certbot for Apache

This is the one command that does everything. The --apache flag tells Certbot to use the Apache plugin: get the certificate and edit your Apache config.

sudo certbot --apache -d example.com -d www.example.com

The -d flag lists each domain name the certificate should cover. Include www if people reach your site that way.

The first time, Certbot asks for an email (used for expiry warnings) and to agree to the terms. Then it works through the challenge and offers the redirect choice:

Output:

Saving debug log to /var/log/letsencrypt/letsencrypt.log

Requesting a certificate for example.com and www.example.com

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-09-13.

Deploying certificate
Successfully deployed certificate for example.com to /etc/apache2/sites-available/example-le-ssl.conf
Successfully deployed certificate for www.example.com to /etc/apache2/sites-available/example-le-ssl.conf
Congratulations! You have successfully enabled HTTPS on https://example.com and https://www.example.com

Notice Certbot created a brand-new file ending in -le-ssl.conf. That is the SSL vhost it built for you.

The SSL vhost Certbot creates

Certbot copies your original vhost, switches it to port 443, and points it at the new certificate files. The result in /etc/apache2/sites-available/example-le-ssl.conf looks like this:

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

    SSLEngine on
    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>

The Include line pulls in modern, secure TLS settings (protocols and ciphers) that Certbot maintains, so you do not have to tune them yourself.

The HTTP to HTTPS redirect

If you chose the redirect, Certbot edits your original port 80 vhost to forward everyone to HTTPS. It adds rewrite rules like this to /etc/apache2/sites-available/example.conf:

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

    RewriteEngine on
    RewriteCond %{SERVER_NAME} =example.com [OR]
    RewriteCond %{SERVER_NAME} =www.example.com
    RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>

R=permanent sends an HTTP 301 status, telling browsers and search engines the move to HTTPS is permanent. Certbot also enables the needed modules (ssl and rewrite) and reloads Apache automatically.

Certbot choiceWhat happensWhen to pick it
Redirect (recommended)All HTTP traffic forwarded to HTTPSAlmost always — you want every visitor on HTTPS
No redirectHTTP and HTTPS both served separatelyOnly during migration or special API needs

Verify it worked

Test the redirect and the certificate from the command line:

curl -I http://example.com

Output:

HTTP/1.1 301 Moved Permanently
Location: https://example.com/
curl -I https://example.com

Output:

HTTP/2 200
server: Apache/2.4.58 (Ubuntu)

A 301 on HTTP and 200 on HTTPS means the redirect and certificate are both live. You can also open the site in a browser and click the padlock.

Renewal happens automatically

Let’s Encrypt certificates last 90 days. The Certbot snap installs a systemd timer (systemd is Ubuntu’s service manager; a timer is its built-in scheduler) that renews them in the background. Confirm it is active and do a dry run that simulates renewal without changing anything:

sudo systemctl list-timers | grep certbot
sudo certbot renew --dry-run

Output:

Congratulations, all simulations of the renewal succeeded:
  /etc/letsencrypt/live/example.com/fullchain.pem (success)

If the dry run passes, you never have to think about renewals again.

Best Practices

  • Always pick the redirect option so no visitor is ever left on insecure HTTP.
  • Run sudo certbot renew --dry-run after setup to confirm auto-renewal works before you forget about it.
  • Include every hostname (example.com, www.example.com, any subdomains) in one -d list so a single certificate covers them all.
  • Let Certbot manage the -le-ssl.conf file; edit your original vhost for app changes and re-run Certbot if you change domains.
  • Keep ufw rules tight: allow Apache Full (ports 80 and 443) but close anything else.
  • Check /var/log/letsencrypt/letsencrypt.log if a renewal or issuance ever fails — it explains exactly what went wrong.
Last updated June 15, 2026
Was this helpful?