Introduction

Serving your Apache site over HTTPS encrypts traffic between clients and your server, preventing passive interception and tampering. Let's Encrypt is a Certificate Authority (CA) that provides free TLS/SSL certificates, enabling encrypted HTTPS on web servers without the cost and complexity of traditional certificate authorities.

Certbot, the official Let's Encrypt client, automates the entire process of obtaining, installing, and renewing SSL certificates for Apache on Ubuntu 20.04. With a single command, you can configure your web server to serve encrypted traffic and automatically renew certificates before they expire.

This tutorial uses a separate virtual host file instead of Apache's default configuration file for setting up the website that will be secured by Let's Encrypt. We recommend creating new Apache virtual host files for each domain hosted on a server, as this helps to avoid common mistakes and maintains the default configuration files as a fallback setup.

[info]

Deploy your frontend applications from GitHub using an app platform. Let the cloud provider focus on scaling your app.

Key Takeaways

apache illustration for: Key Takeaways

Automated Certificate Management: Certbot's Apache plugin automates SSL certificate installation and configuration, handling certificate issuance, Apache virtual host updates, and HTTP to HTTPS redirects in a single interactive command.

Automatic Renewal: Let's Encrypt certificates expire after 90 days, but Certbot's built-in systemd timer service automatically renews certificates twice daily when they're within 30 days of expiration, ensuring continuous HTTPS coverage without manual intervention.

TLS Configuration: Once HTTPS is working, review Apache’s TLS settings to turn off legacy protocols, keep Certbot’s defaults where possible, and enable HSTS only after confirming your site functions correctly over HTTPS.

Multiple Domain Support: Certbot can secure multiple domains and subdomains simultaneously by detecting all domains configured in your Apache virtual hosts, allowing you to enable HTTPS for your main domain and www subdomain in one operation.

Troubleshooting Essentials: Common certificate issuance failures include DNS misconfiguration, firewall blocking ports 80/443, incorrect virtual host ServerName directives, and rate limiting from Let's Encrypt. Verify DNS records, firewall rules, and Apache configuration before retrying.

[warning]

Note: Ubuntu 20.04 reached end of life (EOL) in April 2025 and no longer receives security updates. While the commands and procedures in this tutorial still work on Ubuntu 20.04, we recommend upgrading to a supported Ubuntu version (22.04 LTS or 24.04 LTS) for security and support. The commands in this tutorial are compatible with newer Ubuntu versions as well.

Understanding TLS, HTTPS, and Let's Encrypt

TLS (Transport Layer Security) is the cryptographic protocol that secures data transmission between web browsers and servers. HTTPS (HTTP Secure) uses TLS to encrypt HTTP traffic, preventing tampering and man-in-the-middle attacks.

Let's Encrypt is a free, automated, and open Certificate Authority operated by the Internet Security Research Group (ISRG). It provides Domain Validation (DV) certificates that verify domain ownership through automated challenges, making SSL/TLS encryption accessible to everyone without cost or complex verification processes.

Certbot is the official ACME (Automated Certificate Management Environment) client for Let's Encrypt. The Apache plugin (python3-certbot-apache) integrates directly with Apache's configuration system, automatically detecting virtual hosts, obtaining certificates, and configuring SSL settings without manual file editing.

Let's Encrypt certificates are free, automatically renewable, and issued within minutes. The 90-day validity period encourages automation and reduces the impact of compromised certificates.

Note: To understand more about the differences between SSL and TLS protocols, please refer to this article on TLS vs. SSL: What's the Difference?.

Prerequisites

To follow this tutorial, you will need:

  • A fully registered domain name. This tutorial will use your_domain as an example throughout. You can purchase a domain name on Namecheap, get one for free on Freenom, or use the domain registrar of your choice.
  • An A record with your_domain pointing to your server's public IP address.
  • An A record with www.your_domain pointing to your server's public IP address.

[warning]

Important: Ensure your domain's DNS records have fully propagated before proceeding. You can verify DNS resolution using dig your_domain or nslookup your_domain. Certbot requires valid DNS resolution to complete the HTTP-01 challenge that verifies domain ownership.

Installing Certbot and Required Packages

Certbot and the Apache plugin are installed via Ubuntu's package manager. The certbot package provides the core ACME client, while python3-certbot-apache adds Apache-specific automation capabilities.

Update your package index and install both packages:

				
					
sudo apt update

sudo apt install certbot python3-certbot-apache

				
			

You will be prompted to confirm the installation by pressing Y, then ENTER.

The python3-certbot-apache plugin enables Certbot to:

  • Automatically detect Apache virtual hosts from your configuration files
  • Modify virtual host configurations to enable SSL
  • Reload Apache after certificate installation
  • Configure HTTP to HTTPS redirects

Note: If you prefer manual certificate management or need more control over the SSL configuration, you can install only certbot and use the certonly method instead of --apache. This tutorial focuses on the automated approach, but we'll cover manual configuration alternatives in the troubleshooting section.

After installation, verify Certbot is working correctly by using:

				
					
certbot --version

				
			

You should see output showing the Certbot version number.

Next, we'll verify your Apache virtual host configuration to ensure Certbot can detect your domains correctly.

For example, after running certbot --version, you might see output like:

				
					
certbot 2.9.0

				
			

If you see a similar version number, you're ready to continue.

Checking Your Apache Virtual Host Configuration

Certbot automatically detects domains from your Apache virtual host ServerName and ServerAlias directives. Before running Certbot, verify these settings are correctly configured in your virtual host file.

Open your domain's virtual host configuration file:

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

				
			

Your virtual host should include ServerName and ServerAlias directives that match your domain. A typical configuration looks like this:

				
					
<VirtualHost *:80>

 ServerName your_domain

 ServerAlias www.your_domain

 DocumentRoot /var/www/your_domain

 ...

</VirtualHost>

				
			

If your virtual host configuration doesn't match this structure, update it accordingly. The ServerName should be your primary domain, and ServerAlias should include the www subdomain and any other aliases you want to secure.

Once you have updated your configuration, check that your Apache settings are valid:

				
					
sudo apache2ctl configtest

				
			

You should see Syntax OK as a response. If you encounter errors, review your virtual host file for typos or syntax issues. Once validated, reload Apache to apply any changes:

				
					
sudo systemctl reload apache2

				
			

With your virtual host properly configured, Certbot will automatically detect both your main domain and www subdomain when you run the certificate issuance command.

Allowing HTTPS Through the Firewall

If you have the UFW firewall enabled, you'll need to adjust the settings of your firewall to allow HTTPS traffic to your server. Upon installation, Apache registers a few different UFW application profiles. We can use the Apache Full profile to allow both HTTP and HTTPS traffic on your server.

To verify what kind of traffic is currently allowed on your server, you can use:

				
					
sudo ufw status

				
			

If you followed our Apache installation guides, your output should show only HTTP traffic (port 80) is allowed:

				
					
[secondary_label Output]

Status: active



To Action From

-- ------ ----

OpenSSH ALLOW Anywhere 

Apache ALLOW Anywhere 

OpenSSH (v6) ALLOW Anywhere (v6) 

Apache (v6) ALLOW Anywhere (v6)

				
			

The "Apache" profile only allows HTTP on port 80. To enable HTTPS, switch to the "Apache Full" profile which allows both HTTP and HTTPS:

				
					
sudo ufw allow 'Apache Full'

sudo ufw delete allow 'Apache'

				
			

Verify the change by using:

				
					
sudo ufw status

				
			
				
					
[secondary_label Output]

Status: active



To Action From

-- ------ ----

OpenSSH ALLOW Anywhere 

Apache Full ALLOW Anywhere 

OpenSSH (v6) ALLOW Anywhere (v6) 

Apache Full (v6) ALLOW Anywhere (v6) 

				
			

Note: If you're using iptables directly instead of UFW, ensure ports 80 and 443 are open. You can check with sudo iptables -L -n and add rules if needed: sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT and sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT.

Your firewall is now configured to allow HTTPS traffic. You're ready to obtain your SSL certificate.

Obtaining and Installing a Let's Encrypt SSL Certificate

Certbot's Apache plugin automates certificate issuance, installation, and Apache configuration in a single interactive command. Run certbot --apache to start the process:

				
					
sudo certbot --apache

				
			

Certbot will prompt you through several configuration steps:

Step 1: Email Address

Enter a valid email address for renewal notifications and security notices:

				
					
[secondary_label Output]

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

Plugins selected: Authenticator apache, Installer apache

Enter email address (used for urgent renewal and security notices) (Enter 'c' to

cancel): you@your_domain

				
			

Step 2: Terms of Service

Agree to Let's Encrypt's terms of service by pressing A and then ENTER:

				
					
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Please read the Terms of Service at

https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must

agree in order to register with the ACME server at

https://acme-v02.api.letsencrypt.org/directory

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

(A)gree/(C)ancel: A

				
			

Step 3: Domain Selection

Certbot automatically detects domains from your Apache virtual hosts. Select which domains to secure:

				
					
Which names would you like to activate HTTPS for?

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

1: your_domain

2: www.your_domain

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Select the appropriate numbers separated by commas and/or spaces, or leave input

blank to select all options shown (Enter 'c' to cancel): 

				
			

Leave the prompt blank and press ENTER to secure all listed domains (recommended).

Step 4: Certificate Issuance

Certbot performs the HTTP-01 challenge to verify domain ownership:

				
					
Obtaining a new certificate

Performing the following challenges:

http-01 challenge for your_domain

http-01 challenge for www.your_domain

Enabled Apache rewrite module

Waiting for verification...

Cleaning up challenges

Created an SSL vhost at /etc/apache2/sites-available/your_domain-le-ssl.conf

Enabled Apache socache_shmcb module

Enabled Apache ssl module

Deploying Certificate to VirtualHost /etc/apache2/sites-available/your_domain-le-ssl.conf

Enabling available site: /etc/apache2/sites-available/your_domain-le-ssl.conf

Deploying Certificate to VirtualHost /etc/apache2/sites-available/your_domain-le-ssl.conf

				
			

Step 5: HTTP to HTTPS Redirect

Choose whether to redirect all HTTP traffic to HTTPS:

				
					
Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

1: No redirect - Make no further changes to the webserver configuration.

2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for

new sites, or if you're confident your site works on HTTPS. You can undo this

change by editing your web server's configuration.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 2

				
			

Select option 2 to enable automatic HTTP to HTTPS redirects (recommended for security).

Certificate Installation Complete

After successful installation, Certbot displays certificate details:

				
					
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Congratulations! You have successfully enabled https://your_domain and

https://www.your_domain



You should test your configuration at:

https://www.ssllabs.com/ssltest/analyze.html?d=your_domain

https://www.ssllabs.com/ssltest/analyze.html?d=www.your_domain

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



IMPORTANT NOTES:

 - Congratulations! Your certificate and chain have been saved at:

 /etc/letsencrypt/live/your_domain/fullchain.pem

 Your key file has been saved at:

 /etc/letsencrypt/live/your_domain/privkey.pem

 Your cert will expire on 2020-07-27. To obtain a new or tweaked

 version of this certificate in the future, simply run certbot again

 with the "certonly" option. To non-interactively renew *all* of

 your certificates, run "certbot renew"

 - Your account credentials have been saved in your Certbot

 configuration directory at /etc/letsencrypt. You should make a

 secure backup of this folder now. This configuration directory will

 also contain certificates and private keys obtained by Certbot so

 making regular backups of this folder is ideal.

 - If you like Certbot, please consider supporting our work by:



 Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate

 Donating to EFF: https://eff.org/donate-le



				
			

Certbot has created a new SSL virtual host configuration file at /etc/apache2/sites-available/your_domain-le-ssl.conf and enabled it. Your certificates are stored in /etc/letsencrypt/live/your_domain/.

Configuring Apache Virtual Hosts for HTTPS

Certbot automatically creates and configures an SSL virtual host, but understanding the configuration helps with troubleshooting and customization. The SSL virtual host file contains your certificate paths and basic SSL settings.

View your SSL virtual host configuration:

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

				
			

A typical Certbot-generated SSL virtual host looks like this:

				
					
[label /etc/apache2/sites-available/your_domain-le-ssl.conf]

<IfModule mod_ssl.c>

<VirtualHost *:443>

 ServerName your_domain

 ServerAlias www.your_domain

 DocumentRoot /var/www/your_domain



 SSLEngine on

 SSLCertificateFile /etc/letsencrypt/live/your_domain/fullchain.pem

 SSLCertificateKeyFile /etc/letsencrypt/live/your_domain/privkey.pem

 Include /etc/letsencrypt/options-ssl-apache.conf

</VirtualHost>

</IfModule>

				
			

Key directives:

  • SSLEngine on: Enables SSL/TLS for this virtual host
  • SSLCertificateFile: Path to the full certificate chain (leaf + intermediate certificates). On Apache 2.4.8+ (including Ubuntu 20.04), fullchain.pem already contains the complete chain, so the deprecated SSLCertificateChainFile directive is not used or needed.
  • SSLCertificateKeyFile: Path to the private key
  • Include /etc/letsencrypt/options-ssl-apache.conf: Includes Certbot's recommended SSL configuration

If you enabled HTTP to HTTPS redirects, Certbot also modified your HTTP virtual host to include redirect rules. Verify the redirect is working by checking your HTTP virtual host:

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

				
			

You should see redirect rules similar to:

				
					
[label /etc/apache2/sites-available/your_domain.conf]

<VirtualHost *:80>

 ServerName your_domain

 ServerAlias www.your_domain

 

 RewriteEngine on

 RewriteCond %{SERVER_NAME} =your_domain [OR]

 RewriteCond %{SERVER_NAME} =www.your_domain

 RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]

</VirtualHost>

				
			

This configuration redirects all HTTP requests to their HTTPS equivalents using a 301 permanent redirect.

Testing HTTPS and SSL Configuration

Verify your SSL certificate installation using browser checks, command-line tools, and external SSL analyzers. Multiple verification methods ensure your certificate is correctly installed and trusted.

Browser Verification

Visit your domain using HTTPS in a web browser:

				
					
https://your_domain

				
			

Your browser should display:

  • A lock icon in the address bar
  • No security warnings
  • The certificate details showing Let's Encrypt as the issuer

Click the lock icon to view certificate details, including expiration date and certificate chain.

Command-Line Testing

Test HTTPS connectivity and certificate details using curl:

				
					
curl -I https://your_domain

				
			

You should see HTTP headers confirming the HTTPS connection. For more detailed SSL information:

				
					
curl -vI https://your_domain 2>&1 | grep -i ssl

				
			

Verify the certificate chain using OpenSSL:

				
					
openssl s_client -connect your_domain:443 -servername your_domain < /dev/null 2>/dev/null | openssl x509 -noout -dates -issuer

				
			

This displays the certificate's validity dates and issuer information.

External SSL Analysis

Use SSL Labs Server Test to get a comprehensive security analysis:

  1. Visit https://www.ssllabs.com/ssltest/analyze.html?d=your_domain
  1. Wait for the analysis to complete (may take a few minutes)
  1. Review the grade (aim for A or A+) and recommendations

SSL Labs tests:

  • Certificate validity and trust chain
  • Protocol support (TLS 1.2, TLS 1.3)
  • Cipher suite strength
  • Key exchange security
  • Overall configuration security

Note: If you encounter SSL connection errors during testing, refer to our guide on How to Fix SSL Connect Errors: Causes and Solutions for troubleshooting steps.

Verify HTTP to HTTPS Redirect

Test that HTTP requests redirect to HTTPS:

				
					
curl -I http://your_domain

				
			

You should see a 301 Moved Permanently response with a Location header pointing to the HTTPS URL:

				
					
HTTP/1.1 301 Moved Permanently

Location: https://your_domain/

				
			

If all tests pass, your SSL certificate is correctly installed and configured.

Setting Up Automatic Certificate Renewal

Let's Encrypt certificates expire after 90 days, but Certbot's systemd timer automatically renews certificates twice daily when they're within 30 days of expiration. This ensures continuous HTTPS coverage without manual intervention.

Verify Auto-Renewal Service Status

Check that the Certbot renewal timer is active:

				
					
sudo systemctl status certbot.timer

				
			

You should see output indicating the service is active and enabled:

				
					
[secondary_label Output]

● certbot.timer - Run certbot twice daily

 Loaded: loaded (/lib/systemd/system/certbot.timer; enabled; vendor preset: enabled)

 Active: active (waiting) since Tue 2020-04-28 17:57:48 UTC; 17h ago

 Trigger: Wed 2020-04-29 23:50:31 UTC; 12h left

 Triggers: ● certbot.service



Apr 28 17:57:48 fine-turtle systemd[1]: Started Run certbot twice daily.

				
			

The timer runs certbot.service twice daily. If the service isn't active, enable it:

				
					
sudo systemctl enable certbot.timer

sudo systemctl start certbot.timer

				
			

Test Certificate Renewal

Perform a dry run to verify the renewal process works without actually renewing certificates:

				
					
sudo certbot renew --dry-run

				
			

Successful output indicates renewal will work when certificates are due:

				
					
[secondary_label Output]

Processing /etc/letsencrypt/renewal/your_domain.conf

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

** DRY RUN: simulating 'certbot renew' close to cert expiry

** (The test certificates below have not been saved.)



Congratulations, all renewals succeeded. The following certs have been renewed:

 /etc/letsencrypt/live/your_domain/fullchain.pem (success)

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

				
			

[warning]

Important: If the dry run fails, investigate the error messages. Common issues include DNS misconfiguration, firewall blocking, or Apache configuration problems. Fix these before your certificate expires to avoid service interruption.

Manual Renewal (If Needed)

While automatic renewal should handle certificate updates, you can manually renew certificates:

				
					
sudo certbot renew

				
			

This command only renews certificates that are within 30 days of expiration. To force renewal of all certificates regardless of expiration date:

				
					
sudo certbot renew --force-renewal

				
			

Note: Let's Encrypt has rate limits (50 certificates per registered domain per week). Avoid unnecessary renewals to prevent hitting these limits. The automatic renewal process respects these limits and only renews when necessary.

Renewal Notifications

Let's Encrypt sends email notifications to the address you provided during setup when:

  • Certificates are approaching expiration
  • Automatic renewal fails
  • Rate limits are approached

Monitor these emails to catch renewal issues early. You can update your email address:

				
					
sudo certbot update_account --email new_email@example.com

				
			

Hardening TLS Settings and Enabling HSTS

After obtaining your SSL certificate, harden your Apache TLS configuration by disabling legacy protocols, configuring strong cipher suites, and enabling security headers like HSTS. These changes reduce exposure to older protocol weaknesses and help keep Apache aligned with current TLS defaults.

Review Current SSL Configuration

Certbot includes a recommended SSL configuration file. View it:

				
					
sudo cat /etc/letsencrypt/options-ssl-apache.conf

				
			

This file contains Certbot's default SSL settings. While generally secure, you can enhance it further.

Customize TLS Configuration

Edit your SSL virtual host to add enhanced security settings:

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

				
			

Add or modify SSL directives within the <VirtualHost *:443> block:

				
					
[label /etc/apache2/sites-available/your_domain-le-ssl.conf]

&lt;IfModule mod_ssl.c&gt;

&lt;VirtualHost *:443&gt;

 ServerName your_domain

 ServerAlias www.your_domain

 DocumentRoot /var/www/your_domain



 SSLEngine on

 SSLCertificateFile /etc/letsencrypt/live/your_domain/fullchain.pem

 SSLCertificateKeyFile /etc/letsencrypt/live/your_domain/privkey.pem

 Include /etc/letsencrypt/options-ssl-apache.conf



 # Disable legacy SSL/TLS protocols

 SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1 +TLSv1.2 +TLSv1.3



 # Prefer server cipher order

 SSLHonorCipherOrder on



 # Disable SSL compression (mitigates CRIME attack)

 SSLCompression off



 # Enable OCSP stapling for improved performance

 SSLUseStapling on

 SSLStaplingCache "shmcb:/var/cache/apache2/ssl_stapling(32768)"



 # Security headers

 Header always set Strict-Transport-Security "max-age=15552000"

 Header always set X-Frame-Options DENY

 Header always set X-Content-Type-Options nosniff

 Header always set Referrer-Policy "strict-origin-when-cross-origin"

&lt;/VirtualHost&gt;

&lt;/IfModule&gt;

				
			

Key security enhancements:

  • SSLProtocol: Disables insecure SSLv2, SSLv3, TLS 1.0, and TLS 1.1; enables only TLS 1.2 and TLS 1.3
  • SSLHonorCipherOrder: Server chooses cipher order, preferring stronger ciphers
  • SSLCompression: Disabled to prevent CRIME attack vulnerabilities
  • SSLUseStapling: Enables OCSP stapling for faster certificate validation
  • Strict-Transport-Security (HSTS): Instructs browsers to prefer HTTPS for a defined period (for example, 15552000 seconds / 180 days). The configuration example above intentionally uses a minimal header: Strict-Transport-Security "max-age=15552000". After you have confirmed that HTTPS works reliably across all hosts, you can strengthen it to Strict-Transport-Security "max-age=15552000; includeSubDomains" and, if you meet the requirements below, optionally to Strict-Transport-Security "max-age=15552000; includeSubDomains; preload".

[warning]

Important: If you choose to add the HSTS preload directive (for example, Strict-Transport-Security "max-age=15552000; includeSubDomains; preload"), it requires submission to the HSTS Preload List. Only include preload if you've submitted your domain and it's been accepted; otherwise, do not add preload to your HSTS header.

Enable Required Apache Modules

Ensure required Apache modules are enabled:

				
					
sudo a2enmod headers

sudo a2enmod ssl

sudo systemctl reload apache2

				
			

Verify Configuration

Test your Apache configuration for syntax errors:

				
					
sudo apache2ctl configtest

				
			

If the test passes, reload Apache:

				
					
sudo systemctl reload apache2

				
			

Test Enhanced Security

Re-run SSL Labs Server Test to verify your security improvements:

				
					
https://www.ssllabs.com/ssltest/analyze.html?d=your_domain

				
			

Your grade should improve, and you should see:

  • Only TLS 1.2 and TLS 1.3 supported
  • Strong cipher suites preferred
  • HSTS header present
  • OCSP stapling enabled

Note: For more information on TLS configuration and security best practices, see our guide on TLS vs. SSL: What's the Difference?.

Handling Multiple Domains and Virtual Hosts

Certbot can secure multiple domains and subdomains in a single certificate or issue separate certificates for each domain. The approach depends on your hosting setup and security requirements.

Single Certificate for Multiple Domains

When you run certbot --apache, Certbot detects all domains from your virtual hosts and can include them in one certificate. This is efficient but means all domains share the same certificate.

To add additional domains to an existing certificate:

				
					
sudo certbot --apache -d your_domain -d www.your_domain -d api.your_domain -d mail.your_domain

				
			

Certbot will:

  1. Detect the existing certificate
  1. Add the new domains to the certificate
  1. Update all relevant virtual hosts

Separate Certificates for Each Domain

For better security isolation, issue separate certificates for each domain:

				
					
sudo certbot --apache -d your_domain -d www.your_domain

sudo certbot --apache -d api.your_domain

sudo certbot --apache -d mail.your_domain

				
			

Each domain gets its own certificate and virtual host configuration.

Wildcard Certificates

For subdomain-heavy setups, use DNS-01 challenge to obtain wildcard certificates:

				
					
sudo certbot certonly --manual --preferred-challenges=dns -d "*.your_domain" -d your_domain

				
			

This requires manual DNS TXT record creation during issuance. Wildcard certificates cover all subdomains but require DNS access for renewal.

Note: Wildcard certificates are more complex to set up and renew. Consider whether multiple individual certificates or a wildcard certificate better fits your use case. For most scenarios, individual certificates per domain are simpler to manage.

Managing Multiple Virtual Hosts

When you have multiple virtual hosts, Certbot creates separate SSL configuration files for each:

  • /etc/apache2/sites-available/domain1-le-ssl.conf
  • /etc/apache2/sites-available/domain2-le-ssl.conf

Each SSL virtual host is independent, allowing different security configurations per domain if needed.

List all your certificates:

				
					
sudo certbot certificates

				
			

This displays all certificates, their domains, expiration dates, and certificate file paths.

Common Issues and Troubleshooting

Certificate issuance and renewal can fail due to DNS misconfiguration, firewall rules, Apache configuration errors, or Let's Encrypt rate limits. Understanding common issues helps resolve problems quickly.

Issue 1: HTTP-01 Challenge Failure

Symptom: Certbot fails with "Failed to verify domain ownership" or "Connection refused" errors.

Causes:

  • DNS records not pointing to your server
  • Firewall blocking port 80
  • Apache not running or misconfigured
  • Incorrect virtual host ServerName

Solutions:

  1. Verify DNS resolution:
				
					
 dig your_domain +short

 nslookup your_domain

				
			

Ensure the A record points to your server's IP address.

  1. Check firewall rules:
				
					
 sudo ufw status

				
			

Port 80 must be open for HTTP-01 challenges. Verify with:

				
					
 sudo ufw allow 80/tcp

				
			
  1. Verify Apache is running:
				
					
 sudo systemctl status apache2

				
			
  1. Test HTTP accessibility:
				
					
 curl -I http://your_domain

				
			

You should receive an HTTP response. If not, check Apache configuration and virtual host settings.

Issue 2: Certificate Renewal Failures

Symptom: certbot renew fails or certificates expire unexpectedly.

Causes:

  • DNS changes breaking validation
  • Firewall rules changed
  • Apache configuration errors
  • Rate limiting from too many renewal attempts

Solutions:

  1. Check renewal logs:
				
					
 sudo tail -50 /var/log/letsencrypt/letsencrypt.log

				
			
  1. Test renewal manually:
				
					
 sudo certbot renew --dry-run -v

				
			

The -v flag provides verbose output showing exactly where renewal fails.

  1. Verify DNS and firewall haven't changed:
				
					
 dig your_domain +short

 sudo ufw status

				
			
  1. Check rate limits:

Let's Encrypt limits certificates to 50 per registered domain per week. If you've hit the limit, wait before retrying or use the staging environment for testing:

				
					
 sudo certbot --apache --staging

				
			

Issue 3: Apache SSL Configuration Errors

Symptom: Apache fails to start or SSL connections fail after certificate installation.

Causes:

  • Missing SSL module
  • Incorrect certificate file paths
  • Syntax errors in virtual host configuration

Solutions:

  1. Enable SSL module:
				
					
 sudo a2enmod ssl

 sudo systemctl restart apache2

				
			
  1. Verify certificate files exist:
				
					
 sudo ls -la /etc/letsencrypt/live/your_domain/

				
			

You should see fullchain.pem, privkey.pem, chain.pem, and cert.pem.

  1. Test Apache configuration:
				
					
 sudo apache2ctl configtest

				
			

Fix any syntax errors reported.

  1. Check Apache error logs:
				
					
 sudo tail -50 /var/log/apache2/error.log

				
			

Issue 4: Mixed Content or Redirect Loops

Symptom: Website loads but shows security warnings or redirects fail.

Causes:

  • HTTP resources loaded over HTTPS (mixed content)
  • Incorrect redirect rules
  • Proxy or load balancer misconfiguration

Solutions:

  1. Check browser console for mixed content warnings:

Update all HTTP resource URLs to HTTPS in your website's HTML, CSS, and JavaScript.

  1. Verify redirect configuration:
				
					
 sudo cat /etc/apache2/sites-available/your_domain.conf

				
			

Ensure redirect rules are correct and not causing loops.

  1. Test redirect:
				
					
 curl -I http://your_domain

				
			

Should return 301 Moved Permanently with Location: https://your_domain/.

Issue 5: Certificate Not Trusted by Browsers

Symptom: Browsers show "Not Secure" or certificate warnings.

Causes:

  • Incomplete certificate chain
  • System time incorrect
  • Certificate expired or revoked

Solutions:

  1. Verify certificate chain:
				
					
 openssl s_client -connect your_domain:443 -servername your_domain

				
			

Check for "Verify return code: 0 (ok)" in the output.

  1. Check system time:
				
					
 date

 timedatectl status

				
			

Incorrect system time can cause certificate validation failures. Sync time if needed:

				
					
 sudo timedatectl set-ntp true

				
			
  1. Verify certificate validity:
				
					
 sudo certbot certificates

				
			

Check expiration dates. Renew if certificates are expired.

Note: For more detailed troubleshooting of SSL/TLS issues, see our comprehensive guide on How to Fix SSL Connect Errors: Causes and Solutions.

FAQs

How do I secure Apache with Let's Encrypt on Ubuntu?

Install Certbot and the Apache plugin, then run sudo certbot --apache. Certbot will guide you through certificate issuance, automatically configure your Apache virtual hosts for HTTPS, and set up automatic renewal. Ensure your domain's DNS records point to your server and ports 80/443 are open in your firewall before running Certbot.

What is Certbot and how does it work?

Certbot is the official ACME client for Let's Encrypt that automates SSL certificate management. The Apache plugin (python3-certbot-apache) integrates with Apache's configuration system to detect virtual hosts, obtain certificates via HTTP-01 challenges, install certificates, and configure SSL settings automatically. It handles certificate renewal through a systemd timer service.

How do I enable HTTPS for multiple domains or subdomains?

Run certbot --apache with multiple -d flags: sudo certbot --apache -d domain1.com -d www.domain1.com -d domain2.com. Certbot can include multiple domains in one certificate or issue separate certificates. For wildcard certificates covering all subdomains, use the DNS-01 challenge: sudo certbot certonly --manual --preferred-challenges=dns -d "*.your_domain".

How can I automatically renew Let's Encrypt certificates?

Certbot includes a systemd timer (certbot.timer) that automatically renews certificates twice daily when they're within 30 days of expiration. Verify it's active with sudo systemctl status certbot.timer. Test renewal with sudo certbot renew --dry-run. Manual renewal: sudo certbot renew.

How do I test if my SSL certificate is installed correctly?

Use multiple verification methods: visit https://your_domain in a browser (check for lock icon), run curl -I https://your_domain, verify with OpenSSL (openssl s_client -connect your_domain:443), and test with SSL Labs Server Test for a comprehensive security analysis.

What are the best TLS settings for Apache?

Disable legacy protocols (SSLv2, SSLv3, TLS 1.0, TLS 1.1) and enable only TLS 1.2 and TLS 1.3. Configure strong cipher suites, disable SSL compression, enable OCSP stapling, and add security headers including HSTS. Certbot's default configuration in /etc/letsencrypt/options-ssl-apache.conf provides a good baseline that you can enhance further.

How do I redirect HTTP traffic to HTTPS?

Certbot can automatically configure HTTP to HTTPS redirects when you select option 2 during certbot --apache. This adds RewriteRule directives to your HTTP virtual host. To manually configure, add redirect rules to your port 80 virtual host or use Apache's Redirect directive: Redirect permanent / https://your_domain/.

What to do if Let's Encrypt certificate issuance fails?

Common causes include DNS misconfiguration, firewall blocking ports 80/443, incorrect Apache virtual host ServerName, or Let's Encrypt rate limits. Verify DNS resolution (dig your_domain), check firewall rules (sudo ufw status), ensure Apache is running and accessible on port 80, and review Certbot logs (sudo tail -50 /var/log/letsencrypt/letsencrypt.log) for specific error messages.

Conclusion

In this tutorial, you enabled HTTPS on an Apache server using a free Let’s Encrypt certificate on Ubuntu. You installed Certbot and the Apache plugin, issued a certificate for your virtual host, and confirmed that Apache is serving TLS traffic on port 443.

To keep the certificate current, verify that certbot.timer is enabled and run sudo certbot renew --dry-run periodically so you can catch renewal issues before expiration. If you customized your SSL virtual host, re-run sudo apache2ctl configtest after changes and validate the final configuration with your browser, curl, and an external SSL checker.

With HTTPS working end-to-end and renewal automated, you can review the hardening options in this guide (protocol settings, OCSP stapling, and HSTS) and apply them based on your site’s requirements.

Further Learning

Expand your knowledge with these helpful resources:

If you have questions about using Certbot, the Certbot documentation provides comprehensive guides and troubleshooting resources.