
How to Secure Apache with Let’s Encrypt on Ubuntu 24
Securing Apache with Let’s Encrypt SSL certificates on Ubuntu 24 has become the standard approach for implementing HTTPS on web servers without the cost of commercial certificates. This combination provides enterprise-grade encryption using the widely-trusted Let’s Encrypt Certificate Authority, which offers free, automated SSL/TLS certificates with 90-day validity periods. You’ll learn how to install and configure Certbot, obtain certificates for single and multiple domains, set up automatic renewal, implement security headers, and troubleshoot common issues that can break your SSL implementation.
How Let’s Encrypt and Apache Integration Works
Let’s Encrypt operates on the ACME (Automatic Certificate Management Environment) protocol, which automates the entire certificate lifecycle through domain validation challenges. When you request a certificate, Let’s Encrypt’s servers verify domain ownership using either HTTP-01 challenges (placing verification files in your web root) or DNS-01 challenges (creating specific DNS TXT records).
The Certbot client handles this process by temporarily modifying your Apache configuration, creating verification endpoints, and automatically updating your virtual host configurations with SSL directives. Unlike commercial certificates that require manual CSR generation and lengthy validation processes, Let’s Encrypt certificates are issued within minutes and can be programmatically managed.
Apache’s mod_ssl module processes the certificates and handles TLS handshakes, while Certbot maintains certificate files in /etc/letsencrypt/live/ with symbolic links that automatically point to the latest certificate versions during renewals.
Prerequisites and System Preparation
Before starting the SSL implementation, ensure your Ubuntu 24 server meets these requirements:
- Apache 2.4+ installed and running
- Domain names pointing to your server’s public IP address
- Ports 80 and 443 open in your firewall
- Root or sudo access to the server
- At least 1GB free disk space for certificates and backups
Update your system packages and install required Apache modules:
sudo apt update && sudo apt upgrade -y
sudo apt install apache2 -y
sudo a2enmod ssl
sudo a2enmod rewrite
sudo systemctl restart apache2
Verify Apache is serving content and your domains resolve correctly:
sudo systemctl status apache2
curl -I http://yourdomain.com
dig +short yourdomain.com
Installing and Configuring Certbot
Ubuntu 24 includes Certbot in the default repositories, but installing via snap ensures you get the latest version with automatic updates:
sudo apt remove certbot
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot
Verify the installation and check available plugins:
certbot --version
certbot plugins
The Apache plugin should appear in the output, enabling automatic virtual host configuration. If you prefer manual certificate management without automatic Apache configuration, you can use the webroot plugin instead.
Obtaining SSL Certificates
For single domain certificates with automatic Apache configuration:
sudo certbot --apache -d yourdomain.com
For multiple domains or subdomains on the same certificate:
sudo certbot --apache -d yourdomain.com -d www.yourdomain.com -d api.yourdomain.com
During the process, Certbot will prompt you for:
- Email address for renewal notifications and security notices
- Agreement to Let’s Encrypt Terms of Service
- Optional sharing of email with Electronic Frontier Foundation
- Redirect preference (recommended: redirect HTTP to HTTPS)
For environments requiring more control, use the webroot plugin:
sudo certbot certonly --webroot -w /var/www/html -d yourdomain.com
This method places verification files in your document root without modifying Apache configurations, allowing you to manually implement SSL settings.
Apache SSL Configuration Optimization
Certbot’s automatic configuration provides basic SSL functionality, but production environments benefit from security enhancements. Examine the generated SSL virtual host:
sudo cat /etc/apache2/sites-available/yourdomain-le-ssl.conf
Enhanced SSL configuration with modern security practices:
<VirtualHost *:443>
ServerName yourdomain.com
DocumentRoot /var/www/html
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/yourdomain.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/yourdomain.com/privkey.pem
# Modern SSL Configuration
SSLProtocol -all +TLSv1.2 +TLSv1.3
SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384
SSLHonorCipherOrder off
SSLSessionTickets off
# Security Headers
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
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"
Header always set Content-Security-Policy "default-src 'self'"
# OCSP Stapling
SSLUseStapling on
SSLStaplingResponderTimeout 5
SSLStaplingReturnResponderErrors off
</VirtualHost>
Enable the headers module and restart Apache:
sudo a2enmod headers
sudo systemctl restart apache2
Automatic Certificate Renewal
Let’s Encrypt certificates expire after 90 days, requiring automated renewal for production environments. Certbot installs a systemd timer that runs twice daily:
sudo systemctl status snap.certbot.renew.timer
sudo systemctl list-timers snap.certbot.renew
Test the renewal process without actually renewing certificates:
sudo certbot renew --dry-run
For custom renewal workflows, create a renewal hook script:
sudo nano /etc/letsencrypt/renewal-hooks/post/reload-apache.sh
#!/bin/bash
/usr/bin/systemctl reload apache2
/usr/bin/logger "Let's Encrypt certificates renewed and Apache reloaded"
sudo chmod +x /etc/letsencrypt/renewal-hooks/post/reload-apache.sh
Monitor certificate expiration and renewal status:
sudo certbot certificates
openssl x509 -noout -dates -in /etc/letsencrypt/live/yourdomain.com/cert.pem
Security Best Practices and Hardening
Implement additional security measures beyond basic SSL configuration. Create a strong Diffie-Hellman group for perfect forward secrecy:
sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
Add the DH parameters to your SSL configuration:
SSLOpenSSLConfCmd DHParameters "/etc/ssl/certs/dhparam.pem"
Configure OCSP stapling globally in /etc/apache2/mods-available/ssl.conf:
SSLStaplingCache shmcb:/var/run/ocsp(128000)
SSLStaplingStandardCacheTimeout 3600
SSLStaplingErrorCacheTimeout 600
Implement certificate transparency monitoring by checking your certificates appear in CT logs:
curl -s "https://crt.sh/?q=yourdomain.com&output=json" | jq '.[0] | {id, name_value, not_before, not_after}'
Performance Optimization and Monitoring
SSL/TLS adds computational overhead, but proper configuration minimizes performance impact. Enable SSL session caching and HTTP/2:
sudo a2enmod http2
sudo systemctl restart apache2
Add HTTP/2 support to your SSL virtual host:
Protocols h2 http/1.1
Monitor SSL performance and connection statistics:
sudo apache2ctl server-status
openssl s_client -connect yourdomain.com:443 -status
Benchmark SSL handshake performance:
openssl s_time -connect yourdomain.com:443 -new -time 30
Configuration | Handshake Time (ms) | Cipher Suite | Security Level |
---|---|---|---|
Default Certbot | 250-300 | Mixed | Good |
Optimized TLS 1.2 | 180-220 | ECDHE-ECDSA | Excellent |
TLS 1.3 Enabled | 120-150 | Modern | Outstanding |
Common Issues and Troubleshooting
Certificate verification failures often occur due to DNS propagation delays or firewall restrictions. Check domain accessibility from external sources:
curl -I http://yourdomain.com/.well-known/acme-challenge/test
If Certbot fails with “Connection refused” errors, verify Apache is listening on port 80:
sudo netstat -tlnp | grep :80
sudo ufw status
Certificate renewal failures typically involve permission issues or Apache configuration errors. Check renewal logs:
sudo journalctl -u snap.certbot.renew
sudo certbot renew --force-renewal -v
Mixed content warnings occur when HTTPS pages load HTTP resources. Identify problematic resources:
grep -r "http://" /var/www/html/ --include="*.html" --include="*.php"
For wildcard certificates requiring DNS validation:
sudo certbot certonly --manual --preferred-challenges dns -d "*.yourdomain.com"
Apache SSL errors often indicate configuration syntax problems:
sudo apache2ctl configtest
sudo apache2ctl -S
Alternative Certificate Management Approaches
While Certbot remains the most popular choice, several alternatives offer different advantages:
Tool | Language | Key Features | Best Use Case |
---|---|---|---|
Certbot | Python | Official client, Apache integration | Standard deployments |
acme.sh | Shell | Lightweight, many DNS providers | Automation scripts |
Caddy | Go | Automatic HTTPS, reverse proxy | Modern applications |
Traefik | Go | Container integration, service discovery | Microservices |
For high-traffic environments, consider using acme.sh with DNS validation to avoid HTTP challenge limitations:
curl https://get.acme.sh | sh
~/.acme.sh/acme.sh --issue --dns dns_cf -d yourdomain.com
Integration with CI/CD and Infrastructure as Code
Automate SSL certificate management in deployment pipelines using Ansible playbooks:
- name: Install and configure Let's Encrypt certificate
community.crypto.acme_certificate:
account_key: /etc/ssl/private/account.key
challenge: http-01
csr: /etc/ssl/csr/yourdomain.csr
dest: /etc/ssl/certs/yourdomain.crt
terms_agreed: yes
acme_directory: https://acme-v02.api.letsencrypt.org/directory
Docker environments can leverage init containers for certificate provisioning:
version: '3.8'
services:
certbot:
image: certbot/certbot:latest
volumes:
- certs:/etc/letsencrypt
- webroot:/var/www/certbot
command: certonly --webroot --webroot-path=/var/www/certbot --email admin@yourdomain.com --agree-tos --no-eff-email -d yourdomain.com
For managed hosting solutions, consider using VPS or dedicated servers that provide root access for complete SSL certificate control and custom security configurations.
Monitor certificate health using external services and implement alerting for expiration warnings. Services like SSL Labs Server Test provide comprehensive security analysis, while CT monitoring tools track certificate issuance and potential security issues.
The combination of Apache and Let’s Encrypt on Ubuntu 24 provides a robust, cost-effective SSL solution that scales from simple websites to complex multi-domain applications. Regular monitoring, automated renewals, and security best practices ensure your implementation remains secure and performant over time.

This article incorporates information and material from various online sources. We acknowledge and appreciate the work of all original authors, publishers, and websites. While every effort has been made to appropriately credit the source material, any unintentional oversight or omission does not constitute a copyright infringement. All trademarks, logos, and images mentioned are the property of their respective owners. If you believe that any content used in this article infringes upon your copyright, please contact us immediately for review and prompt action.
This article is intended for informational and educational purposes only and does not infringe on the rights of the copyright owners. If any copyrighted material has been used without proper credit or in violation of copyright laws, it is unintentional and we will rectify it promptly upon notification. Please note that the republishing, redistribution, or reproduction of part or all of the contents in any form is prohibited without express written permission from the author and website owner. For permissions or further inquiries, please contact us.