Secure Apache with Let’s Encrypt on Ubuntu

To protect Apache with Let’s Encrypt on Ubuntu, install Certbot, prepare an Apache virtual host for the domain, execute sudo certbot --apache, improve the TLS settings, and confirm that certificates renew automatically. Once these steps are complete, visitors can reach the website over HTTPS with a trusted certificate provided by Let’s Encrypt, a nonprofit certificate authority operated by the Internet Security Research Group (ISRG).

Let’s Encrypt issues free domain-validated (DV) TLS certificates. Certbot is the recommended ACME client for Ubuntu. It requests certificates, confirms that you control the requested domain, and configures Apache so the website can be delivered securely over HTTPS.

This guide is applicable to Ubuntu 22.04 LTS, Ubuntu 24.04 LTS (Noble Numbat), and Ubuntu 26.04 LTS (Resolute Raccoon) with Apache 2.4. The configuration uses a dedicated virtual host instead of depending entirely on Apache’s default site. If your server still runs Ubuntu 20.04, use an Ubuntu 20.04 version of the same process.

The website can run on any cloud virtual machine, while the required DNS entries can be managed through the control panel provided by your hosting or DNS provider.

Version note: The commands in this guide were verified on Ubuntu 22.04, 24.04, and 26.04 LTS with Apache packages supplied by the standard repositories. Ubuntu 26.04 LTS was released in April 2026. Certbot is installed through snap following the EFF instructions rather than the older apt install certbot method. Automatic renewals are handled by a systemd timer, typically snap.certbot.renew.timer when Certbot is installed with snap.

Key Takeaways

  • Install Certbot with sudo snap install --classic certbot and ensure /snap/bin/certbot can be accessed through your PATH.
  • Before executing sudo certbot --apache, confirm that the Apache virtual host contains the correct ServerName and ServerAlias settings.
  • Allow HTTPS traffic through UFW with sudo ufw allow 'Apache Full' and remove the more limited Apache profile if it is no longer required.
  • Let’s Encrypt certificates are valid for 90 days. Certbot tries to renew a certificate once fewer than 30 days remain.
  • Improve TLS security through /etc/apache2/mods-available/ssl.conf or a dedicated configuration file by turning off TLS 1.0 and TLS 1.1, activating OCSP stapling, and adding HSTS through mod_headers.
  • Test the renewal process with sudo certbot renew --dry-run. If an error occurs, review /var/log/letsencrypt/letsencrypt.log.
  • Certificate requests are limited. Review the Let’s Encrypt rate limits, including the example restriction of 50 certificates per registered domain per week.
  • For Ubuntu 26.04 LTS, the same snap-based Certbot installation method and standard Apache directories remain applicable. Confirm installed versions with lsb_release, apache2 -v, and openssl version.

How Let’s Encrypt Certificate Issuance Works

The sequence below gives a simplified overview of the Let’s Encrypt certificate issuance process.

  1. A browser sends a request to https://your_domain.
  2. Apache returns the certificate stored in /etc/letsencrypt/live/your_domain/.
  3. During the initial Certbot execution, Certbot either creates a temporary challenge resource or relies on the Apache plugin to prove control of the domain through port 80.
  4. The Let’s Encrypt ACME API provides the certificate. Certbot keeps the private keys on your server, while Let’s Encrypt does not retain your private key.
  5. A systemd timer runs certbot renew twice per day and renews qualifying certificates before expiration.

Unless a DNS-based validation plugin is used, including the type required for wildcard certificates, incoming connections on port 80 must reach the server so HTTP-01 validation can succeed.

Prerequisites

Before starting this procedure, confirm that you have:

  • An Ubuntu 22.04, 24.04, or 26.04 LTS server configured with a non-root account that has sudo privileges and a suitable firewall. When creating a new cloud virtual machine and selecting the newest LTS release listed here, choose an Ubuntu 26.04 LTS image.
  • A registered domain name. This guide uses your_domain as the example placeholder.
  • DNS A records for your_domain and www.your_domain pointing to the public IP address of the server. Manage these entries through your DNS provider.
  • Apache installed with a dedicated virtual host configuration stored at /etc/apache2/sites-available/your_domain.conf.
  • Optionally, UFW configured as the firewall for the server.

Verify Your Ubuntu and Apache Environment

Before installing or renewing certificates, perform several checks on the server. These commands confirm that the system is running one of the supported LTS releases and that Apache is available.

Check the Ubuntu Release

The output should look similar to Ubuntu 22.04.x LTS, Ubuntu 24.04.x LTS, or Ubuntu 26.04.x LTS.

Check the Apache Version

Confirm that Apache is installed and record the installed version. Package revisions can change whenever security updates or routine maintenance releases become available.

An example of the first line from a current LTS system is:


Server version: Apache/2.4.58 (Ubuntu)

The value can differ on Ubuntu 22.04 or 26.04. You can compare the installed package with Ubuntu package search for the appropriate suite: jammy, noble, or resolute.

Check the OpenSSL Version

TLS 1.2 and TLS 1.3 require OpenSSL 1.1.1 or later. Ubuntu 22.04 and newer releases provide OpenSSL 3.x.

Confirm Apache Is Running


sudo systemctl is-active apache2

The expected output is active. If Apache is not installed yet, install it before moving forward. The same apt install apache2 procedure is applicable to Ubuntu 24.04 and 26.04.

Ubuntu LTS Codename Approximate Apache Version in Default Repositories
22.04 Jammy 2.4.52 or newer
24.04 Noble 2.4.58 or newer
26.04 Resolute 2.4.x; run apache2 -v on your server

A precise Apache package revision for Ubuntu 26.04 is deliberately not specified because security updates may change the package build identifier. Treat the output of apache2 -v on the actual virtual machine as the authoritative value.

Step 1: Install Certbot on Ubuntu

For Ubuntu 22.04, 24.04, and 26.04, the Certbot project recommends installing the snap package instead of using Certbot packages from the standard apt repositories.

Install snapd and Certbot

Refresh the package index and install snapd. Some minimal server images and cloud images already include it.


sudo apt update
sudo apt install snapd -y

Update the snap core runtime before Certbot is installed. This is recommended for newly created Ubuntu 22.04, 24.04, and 26.04 servers.


sudo snap install core
sudo snap refresh core

Remove older Certbot packages installed through apt so the snap installation is used instead.


sudo apt remove certbot python3-certbot-apache 2>/dev/null || true

Install Certbot through snap.


sudo snap install –classic certbot

Create the recommended symbolic link so the certbot command can be executed normally.


sudo ln -sf /snap/bin/certbot /usr/bin/certbot

Verify the installed Certbot version.

A Certbot version number should be displayed. Since snap updates the software, the precise version changes over time.

Verify that the Apache plugin is installed and available.

The list of plugins should include an apache entry.


snap list certbot
systemctl list-timers –all | grep -i certbot

With a snap-based installation, snap.certbot.renew.timer will commonly appear after the first successful execution of certbot --apache.

Ubuntu 26.04 LTS Notes

Ubuntu 26.04 LTS (Resolute Raccoon) continues using the same essential paths and tools found in Ubuntu 22.04 and 24.04, including /etc/apache2/, a2ensite, apachectl configtest, and the UFW Apache Full profile. Certbot continues to store certificates inside /etc/letsencrypt/.

If running certbot starts an unexpected installation, identify every Certbot binary available on the system.

Remove outdated apt packages and keep the /usr/bin/certbot symbolic link that points to /snap/bin/certbot.

Step 2: Check the Apache Virtual Host Configuration

Certbot reads the ServerName and ServerAlias directives in an Apache virtual host to determine which hostnames can be added to the certificate.

Open the configuration file for the website.


sudo nano /etc/apache2/sites-available/your_domain.conf

Confirm that the following directives exist inside the <VirtualHost *:80> block.


ServerName your_domain
ServerAlias www.your_domain

If required, enable the website together with the Apache SSL module, and then reload Apache.


sudo a2ensite your_domain.conf
sudo a2enmod ssl
sudo systemctl reload apache2

Validate the Apache configuration syntax before each reload.

The expected result is Syntax OK. Resolve any configuration errors before reloading Apache.


sudo systemctl reload apache2

Step 3: Allow HTTPS Through the Firewall

If UFW is active, allow both HTTP and HTTPS connections by enabling the Apache Full application profile.

Inspect the firewall rules currently in place.

If only the Apache profile for port 80 is permitted, enable the broader profile.


sudo ufw allow ‘Apache Full’

Once the original HTTP-only rule is no longer needed, delete it.


sudo ufw delete allow ‘Apache’

Review the resulting firewall configuration.

UFW Profile Open Ports Typical Use
Apache 80/tcp HTTP traffic only
Apache Full 80/tcp, 443/tcp HTTP and HTTPS traffic
Apache (v6) / Apache Full (v6) The same ports over IPv6 Servers using both IPv4 and IPv6

HTTP-01 certificate renewal continues to rely on port 80, so this port should remain reachable after HTTPS has been enabled.

Step 4: Obtain a Let’s Encrypt SSL Certificate

Run Certbot using its Apache integration.

Certbot asks for several pieces of information:

  1. An email address that can receive security and renewal notifications.
  2. Agreement to the Let’s Encrypt Subscriber Agreement.
  3. An optional decision about joining the EFF mailing list.
  4. The hostnames to include in the certificate, usually your_domain and www.your_domain.

When the process succeeds, the output can resemble the example below. Actual expiration dates and paths depend on the local setup.


Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/your_domain/fullchain.pem
Key is saved at: /etc/letsencrypt/live/your_domain/privkey.pem
This certificate expires on YYYY-MM-DD.
These files will be updated when the certificate renews.
Certbot has set up a scheduled task to automatically renew this certificate in the background.

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

Visit https://your_domain in a web browser. The browser should indicate that the connection uses a valid certificate through its secure-connection or lock indicator.

Certificate File Locations

Path Purpose
/etc/letsencrypt/live/your_domain/fullchain.pem The certificate for the domain combined with the intermediate chain; Apache normally references this file through SSLCertificateFile.
/etc/letsencrypt/live/your_domain/privkey.pem The private key referenced through SSLCertificateKeyFile.
/etc/letsencrypt/live/your_domain/cert.pem The domain certificate without the additional intermediate chain.
/etc/letsencrypt/live/your_domain/chain.pem The intermediate certificate chain.
/etc/letsencrypt/live/your_domain/README Information created by Certbot.
/etc/letsencrypt/renewal/your_domain.conf The renewal configuration belonging to the certificate.

Files inside the live/ directory are symbolic links. When Certbot renews a certificate, it updates the targets of these links.

For more information about private keys and certificate signing requests, refer to an OpenSSL guide that explains SSL certificates, keys, and CSRs.

Test the Website with SSL Labs

After applying the TLS improvements in Step 5, test the domain with the SSL Labs Server Test to receive an independent external assessment.

Step 5: Harden TLS and HTTP Security Headers

Certbot activates HTTPS, but further configuration can remove outdated protocols and add stronger HTTP security headers.

Enable the Apache Headers Module

Configure SSL Protocols and Cipher Suites

Open the Apache SSL module configuration file.


sudo nano /etc/apache2/mods-available/ssl.conf

Add or update the directives shown below. The comments explain what each option is intended to do.

# Allow TLS 1.2 and TLS 1.3 while turning off SSLv3, TLS 1.0, and TLS 1.1.

SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1

# Use modern AEAD cipher suites and let Apache negotiate an appropriate option with the client.

SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384

# Let clients choose cipher preference, which is suitable for TLS 1.3.

SSLHonorCipherOrder off

# Turn on OCSP stapling so Apache can include revocation information during the TLS handshake.

SSLUseStapling on
SSLStaplingCache “shmcb:${APACHE_RUN_DIR}/ssl_stapling(32768)”

Protocol Apache 2.4 on Ubuntu 22.04, 24.04, and 26.04 Notes
TLS 1.3 Available with OpenSSL 3.x on Ubuntu 22.04 and later Used by current clients
TLS 1.2 Supported A widely used minimum version for production websites
TLS 1.1 and older Disabled through the SSLProtocol directive above Removing these protocol versions can improve SSL Labs results

Ubuntu 24.04 commonly supplies Apache 2.4.58 through the default repositories, while Ubuntu 22.04 includes 2.4.52 or a newer revision. On 26.04, run apache2 -v and review the resolute package suite at packages.ubuntu.com to identify the installed revision.

Add HSTS and Other Security Headers

Edit the SSL virtual host created by Certbot. Its filename usually ends with -le-ssl.conf.


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

Add the following directives inside the <VirtualHost *:443> section.

# Tell browsers to require HTTPS for one year and extend the rule to subdomains.

Header always set Strict-Transport-Security “max-age=31536000; includeSubDomains”

# Reduce the risk of MIME-type sniffing.

Header always set X-Content-Type-Options “nosniff”

# Limit frame embedding unless the application requires a different policy.

Header always set X-Frame-Options “SAMEORIGIN”

Check the Apache configuration and reload the service.


sudo apachectl configtest
sudo systemctl reload apache2

Certbot usually creates a redirect from HTTP to HTTPS. Confirm that http://your_domain redirects to an https:// URL. Apache redirects can also be configured manually when required.

Step 6: Verify Automatic Certificate Renewal

Let’s Encrypt certificates expire after 90 days. Certbot installs a systemd timer that checks twice each day for certificates that qualify for renewal.

For snap installations, inspect the commonly used renewal timer.


sudo systemctl status snap.certbot.renew.timer

If that unit does not exist, inspect the alternative timer.


sudo systemctl status certbot.timer

You can also search the full timer list for units associated with Certbot.


systemctl list-timers | grep -i certbot

Run a simulated certificate renewal.


sudo certbot renew –dry-run

A successful test can display a message similar to the following:


Congratulations, all simulated renewals succeeded:
/etc/letsencrypt/live/your_domain/fullchain.pem (success)

If Certificate Renewal Fails

  1. Inspect sudo less /var/log/letsencrypt/letsencrypt.log.
  2. Confirm that port 80 can be reached from the public internet through both the server firewall and any infrastructure-level firewall.
  3. Check that the DNS records for the domain still resolve to the current server.
  4. After fixing the issue, execute sudo certbot renew --dry-run again.

Let’s Encrypt sends expiration-related notifications to the email address registered with the certificate. In a production environment, however, email should not be the only method used to monitor certificate renewal.

Troubleshooting Common Let’s Encrypt and Apache Issues

Domain Validation Failures

  • DNS updates have not propagated: Run dig +short your_domain A and compare the returned IP address with the public IP of the server.
  • The wrong virtual host is being selected: The ServerName directive must match the domain requested through Certbot.
  • Port 80 is blocked: HTTP-01 validation requires inbound TCP connections on port 80. Review both infrastructure firewall rules and UFW.

Apache Errors After Running Certbot

Execute sudo apachectl configtest. Certbot changes configuration files located under /etc/apache2/sites-available/. If required, restore a backup or run sudo certbot --apache again after resolving issues such as an incorrect ServerName.

Certificate Rate Limit Errors

Let’s Encrypt enforces certificate rate limits. The stated certificates per registered domain limit is 50 per week; review the official documentation for current values. If a limit is reached, wait for the applicable limit window to reset or use the staging environment during testing.


sudo certbot –apache –staging

Certificates generated by the staging service are not trusted by standard browsers and should only be used for testing.

Firewall Blocking Certificate Renewal

The standard renewal setup continues to use HTTP-01 validation over port 80. Keep the Apache Full firewall profile enabled or explicitly allow both 80/tcp and 443/tcp.

Let’s Encrypt Compared with Paid Certificate Authorities

Factor Let’s Encrypt Paid Certificate Authority
Cost Free Usually requires an annual certificate charge or subscription
Validation Domain validation (DV) DV, OV, or EV validation may be offered
Certificate lifetime 90 days with automatic renewal Often approximately one year
Wildcard certificates Supported through a DNS-01 challenge Supported and may include commercial assistance
Support Documentation and community-based support May provide vendor SLAs and telephone assistance
Typical use Public websites, APIs, and home lab systems Enterprise policies, EV needs, or environments requiring commercial support

Let’s Encrypt is a good fit when: you manage the server, certificate renewal is automated, and normal domain-validated HTTPS satisfies your requirements.

A paid certificate authority may be suitable when: an organization needs OV or EV validation, particular compliance documentation, or a commercial support agreement.

The CA/Browser Forum has discussed shorter maximum certificate lifetimes throughout the industry. Automated Certbot renewal remains a practical method on Ubuntu regardless of future changes to certificate validity periods. Monitor the Let’s Encrypt blog for policy updates.

Frequently Asked Questions About Let’s Encrypt, Apache, and Ubuntu

The questions below address common subjects involving Let’s Encrypt, Ubuntu, and Apache.

1. How Do You Use Let’s Encrypt with Apache on Ubuntu?

Install Certbot with snap, configure the Apache ServerName, permit incoming connections on ports 80 and 443, and run sudo certbot --apache. Certbot retrieves the certificate and updates the Apache configuration. A systemd timer then performs ongoing renewal checks.

2. How Do You Enable SSL in Apache2 on Ubuntu?

Activate mod_ssl by running sudo a2enmod ssl, obtain a certificate, and configure a virtual host to provide HTTPS on port 443. When Certbot’s Apache plugin is used, it generally creates a file named your_domain-le-ssl.conf.

3. How Do You Enable TLS 1.2 in Apache2?

Add SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1 to /etc/apache2/mods-available/ssl.conf. On current Ubuntu systems, this keeps TLS 1.2 and TLS 1.3 enabled. Run sudo apachectl configtest before applying the configuration with sudo systemctl reload apache2.

4. Is Let’s Encrypt Actually Free?

Yes. Let’s Encrypt does not charge for certificates. The service is operated by the nonprofit ISRG. More information is provided in the Let’s Encrypt FAQ. Certificate rate limits still apply.

5. How Long Does a Let’s Encrypt Certificate Remain Valid?

The standard validity period is 90 days. Certbot attempts renewal once fewer than 30 days remain before expiration. Use sudo certbot renew --dry-run to confirm that automated renewal functions correctly on the server.

Conclusion

You installed Certbot through snap, obtained a Let’s Encrypt certificate using the Apache integration, enabled HTTPS traffic through UFW, improved the TLS configuration, and confirmed automated certificate renewal on Ubuntu. The website can now deliver trusted HTTPS for your_domain.

If your server uses Nginx instead of Apache, use the corresponding process for protecting Nginx with Let’s Encrypt on Ubuntu. In local environments where a publicly trusted certificate authority is unnecessary, a self-signed SSL certificate can be used to test Apache.

Official resources include the Certbot documentation and the Let’s Encrypt documentation.

What to Do Next

  • Create a new Ubuntu 26.04 LTS cloud virtual machine and repeat the same procedure on the new server.
  • Install a complete LAMP stack on Ubuntu. The Apache and apt procedures used on Ubuntu 22.04 are also applicable in similar form to 24.04 and 26.04.
  • Direct the required DNS records to the server and use a managed application platform if you prefer automatic TLS without maintaining Certbot yourself.
  • Read Getting Started with Let’s Encrypt for additional information about ACME concepts beyond Apache.

Run Apache on a cloud virtual machine that provides snapshot and monitoring capabilities so configuration changes can be reverted if they create HTTPS problems.

Continue learning about compute, storage, networking, managed databases, and other cloud infrastructure services.

Learn more about cloud infrastructure products.

Source: digitalocean.com

Create a Free Account

Register now and get access to our Cloud Services.

Posts you might be interested in: