By Erika Heidi and Vinayak Baranwal
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.
Deploy your frontend applications from GitHub using DigitalOcean App Platform. Let DigitalOcean focus on scaling your app.
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.
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.
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?.
To follow this tutorial, you will need:
One Ubuntu server set up by following this initial server setup for Ubuntu tutorial, including a sudo non-root user and a firewall.
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.
Both of the following DNS records set up for your server. You can follow this introduction to DigitalOcean DNS documentation for details on how to add them.
your_domain pointing to your server’s public IP address.www.your_domain pointing to your server’s public IP address.Apache installed by following How To Install the Apache Web Server on Ubuntu. Be sure that you have a virtual host file for your domain. This tutorial will use /etc/apache2/sites-available/your_domain.conf as an example.
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.
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:
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.
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.
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:
OutputStatus: 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
OutputStatus: 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.
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:
Enter a valid email address for renewal notifications and security notices:
OutputSaving 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
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
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).
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
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).
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/.
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:
<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 hostSSLCertificateFile: 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 keyInclude /etc/letsencrypt/options-ssl-apache.conf: Includes Certbot’s recommended SSL configurationIf 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:
<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.
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.
Visit your domain using HTTPS in a web browser:
https://your_domain
Your browser should display:
Click the lock icon to view certificate details, including expiration date and certificate chain.
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.
Use SSL Labs Server Test to get a comprehensive security analysis:
https://www.ssllabs.com/ssltest/analyze.html?d=your_domainSSL Labs tests:
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.
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.
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.
Check that the Certbot renewal timer is active:
sudo systemctl status certbot.timer
You should see output indicating the service is active and enabled:
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
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:
OutputProcessing /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)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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.
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.
Let’s Encrypt sends email notifications to the address you provided during setup when:
Monitor these emails to catch renewal issues early. You can update your email address:
sudo certbot update_account --email new_email@example.com
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.
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.
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:
<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
# 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"
</VirtualHost>
</IfModule>
Key security enhancements:
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".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.
Ensure required Apache modules are enabled:
sudo a2enmod headers
sudo a2enmod ssl
sudo systemctl reload apache2
Test your Apache configuration for syntax errors:
sudo apache2ctl configtest
If the test passes, reload Apache:
sudo systemctl reload apache2
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:
Note: For more information on TLS configuration and security best practices, see our guide on TLS vs. SSL: What’s the Difference?.
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.
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:
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.
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.
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.confEach 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.
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.
Symptom: Certbot fails with “Failed to verify domain ownership” or “Connection refused” errors.
Causes:
Solutions:
Verify DNS resolution:
dig your_domain +short
nslookup your_domain
Ensure the A record points to your server’s IP address.
Check firewall rules:
sudo ufw status
Port 80 must be open for HTTP-01 challenges. Verify with:
sudo ufw allow 80/tcp
Verify Apache is running:
sudo systemctl status apache2
Test HTTP accessibility:
curl -I http://your_domain
You should receive an HTTP response. If not, check Apache configuration and virtual host settings.
Symptom: certbot renew fails or certificates expire unexpectedly.
Causes:
Solutions:
Check renewal logs:
sudo tail -50 /var/log/letsencrypt/letsencrypt.log
Test renewal manually:
sudo certbot renew --dry-run -v
The -v flag provides verbose output showing exactly where renewal fails.
Verify DNS and firewall haven’t changed:
dig your_domain +short
sudo ufw status
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
Symptom: Apache fails to start or SSL connections fail after certificate installation.
Causes:
Solutions:
Enable SSL module:
sudo a2enmod ssl
sudo systemctl restart apache2
Verify certificate files exist:
sudo ls -la /etc/letsencrypt/live/your_domain/
You should see fullchain.pem, privkey.pem, chain.pem, and cert.pem.
Test Apache configuration:
sudo apache2ctl configtest
Fix any syntax errors reported.
Check Apache error logs:
sudo tail -50 /var/log/apache2/error.log
Symptom: Website loads but shows security warnings or redirects fail.
Causes:
Solutions:
Check browser console for mixed content warnings: Update all HTTP resource URLs to HTTPS in your website’s HTML, CSS, and JavaScript.
Verify redirect configuration:
sudo cat /etc/apache2/sites-available/your_domain.conf
Ensure redirect rules are correct and not causing loops.
Test redirect:
curl -I http://your_domain
Should return 301 Moved Permanently with Location: https://your_domain/.
Symptom: Browsers show “Not Secure” or certificate warnings.
Causes:
Solutions:
Verify certificate chain:
openssl s_client -connect your_domain:443 -servername your_domain
Check for “Verify return code: 0 (ok)” in the output.
Check system time:
date
timedatectl status
Incorrect system time can cause certificate validation failures. Sync time if needed:
sudo timedatectl set-ntp true
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.
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.
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.
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".
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.
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.
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.
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/.
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.
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.
Expand your knowledge with these helpful resources:
If you have questions about using Certbot, the Certbot documentation provides comprehensive guides and troubleshooting resources.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
Dev/Ops passionate about open source, PHP, and Linux. Former Senior Technical Writer at DigitalOcean. Areas of expertise include LAMP Stack, Ubuntu, Debian 11, Linux, Ansible, and more.
Building future-ready infrastructure with Linux, Cloud, and DevOps. Full Stack Developer & System Administrator. Technical Writer @ DigitalOcean | GitHub Contributor | Passionate about Docker, PostgreSQL, and Open Source | Exploring NLP & AI-TensorFlow | Nailed over 50+ deployments across production environments.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!
can you make it for ngnix?
getting
code
An unexpected error occurred:
AttributeError: module ‘acme.challenges’ has no attribute ‘TLSSNI01’
The original Ubuntu 20.04 package have this bugs it did not install the right python3-certbot-nginx
So the only solution for ubuntu (AMD64) are via snap
sudo snap install certbot --beta --classicor
sudo add-apt-repository ppa:ahasenack/certbot-tlssni01-1875471
sudo apt-get update
Thanks to Andreas for making his PPA available temporarily to fixed the problem
I hope this will help people who want to upgrade to 20.04
You can re-run “certbot --apache” so that the script can automatically redirect http to https. In case you originally chose to not auto-configure this.
I can confirm that this works like a charm on Ubuntu 20.04. Simple! Thanks.
Step 3 /etc/apache2/sites-available/your_domain.conf
… ServerName your_domain ServerAlias www.your_domain …
do I need to change the name like this if my domain name is examplesite
/etc/apache2/sites-available/examplesite.conf
… ServerName examplesite ServerAlias www.examplesite …
Thanks a lot, everything works fine. All I had to do was enter
sudo a2dissite default-ssl.conf
Hi, thanks for your guide.
One question, can I follow this guide with a subdomain? So that I don’t have to purchase and maintain another domain name?
Im trying to increase the security of the access of phpmyadmin of my server.
Thanks.
E: Package ‘python-virtualenv’ has no installation candidate when I execute sudo certbot --apache Anyone else facing this?
:~# sudo certbot --apache
Bootstrapping dependencies for Debian-based OSes... (you can skip this with --no-bootstrap)
Ign:1 http://ppa.launchpad.net/certbot/certbot/ubuntu focal InRelease
Hit:2 http://archive.ubuntu.com/ubuntu focal InRelease
Err:3 http://ppa.launchpad.net/certbot/certbot/ubuntu focal Release
404 Not Found [IP: 2001:67c:1560:8008::15 80]
Hit:4 https://repos.insights.digitalocean.com/apt/do-agent main InRelease
Get:5 http://mirrors.digitalocean.com/ubuntu focal InRelease [265 kB]
Hit:6 http://mirrors.digitalocean.com/ubuntu focal-updates InRelease
Hit:7 http://mirrors.digitalocean.com/ubuntu focal-backports InRelease
Hit:8 http://security.ubuntu.com/ubuntu focal-security InRelease
Reading package lists... Done
E: The repository 'http://ppa.launchpad.net/certbot/certbot/ubuntu focal Release' does not have a Release file.
N: Updating from such a repository can't be done securely, and is therefore disabled by default.
N: See apt-secure(8) manpage for repository creation and user configuration details.
apt-get update hit problems but continuing anyway...
Reading package lists... Done
Building dependency tree
Reading state information... Done
Note, selecting 'python-is-python2' instead of 'python'
Note, selecting 'python-dev-is-python2' instead of 'python-dev'
Package python-virtualenv is not available, but is referred to by another package.
This may mean that the package is missing, has been obsoleted, or
is only available from another source
E: Package 'python-virtualenv' has no installation candidate
Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.
Full documentation for every DigitalOcean product.
The Wave has everything you need to know about building a business, from raising funding to marketing your product.
Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.
New accounts only. By submitting your email you agree to our Privacy Policy
Scale up as you grow — whether you're running one virtual machine or ten thousand.
Sign up and get $200 in credit for your first 60 days with DigitalOcean.*
*This promotional offer applies to new accounts only.