CertHaloSSL expiry monitoring · by IncubXperts

How to install or renew an SSL certificate on Apache

Install an SSL certificate on Apache httpd step by step, with mod_ssl, an HTTPS virtual host, HTTP-to-HTTPS redirect, TLS 1.2/1.3 and renewal.

CertHalo teamUpdated 2 min read

Applies toApache httpd 2.4UbuntuDebianRHELLet's Encrypt

This guide installs an SSL certificate on Apache httpd 2.4 with a secure configuration, then covers renewal. Paths are for Debian and Ubuntu; on RHEL, Rocky and Fedora the main configuration lives in /etc/httpd/ and the service is called httpd.

Quickest path: Let's Encrypt with Certbot

sudo apt install certbot python3-certbot-apache   # Debian/Ubuntu
sudo certbot --apache -d example.com -d www.example.com

Certbot creates the HTTPS virtual host and sets up renewal; see Renew Let's Encrypt with Certbot. Use the manual steps below for commercial certificates.

1. Enable the modules

sudo a2enmod ssl headers rewrite

On RHEL-based systems, install mod_ssl instead (sudo dnf install mod_ssl).

2. Put the certificate files in place

  • Full chain: your certificate followed by the intermediate certificate(s): cat your_domain.crt ca_bundle.crt > fullchain.crt.
  • Private key, readable only by root.
sudo mkdir -p /etc/ssl/example.com
sudo cp fullchain.crt example.com.key /etc/ssl/example.com/
sudo chmod 600 /etc/ssl/example.com/example.com.key

3. Configure the virtual hosts

Create /etc/apache2/sites-available/example.com-ssl.conf:

<VirtualHost *:80>
    ServerName example.com
    ServerAlias www.example.com
    Redirect permanent / https://example.com/
</VirtualHost>

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

    SSLEngine on
    # Apache 2.4.8+: the full chain goes in SSLCertificateFile
    SSLCertificateFile    /etc/ssl/example.com/fullchain.crt
    SSLCertificateKeyFile /etc/ssl/example.com/example.com.key

    # TLS 1.3 needs Apache 2.4.36+ built with OpenSSL 1.1.1+
    SSLProtocol -all +TLSv1.2 +TLSv1.3

    Header always set Strict-Transport-Security "max-age=31536000"
</VirtualHost>

Enable it:

sudo a2ensite example.com-ssl

On Apache older than 2.4.8, keep your own certificate in SSLCertificateFile and point SSLCertificateChainFile at the intermediate bundle. If the intermediate is left out entirely, browsers may still work while apps fail; see Fix an incomplete certificate chain.

For ciphers that suit your Apache and OpenSSL versions, use the Mozilla SSL Configuration Generator (Intermediate profile).

4. Test and reload

sudo apachectl configtest
sudo systemctl reload apache2      # httpd on RHEL/Fedora

configtest should print Syntax OK. Then check the site with the SSL checker: a complete chain, hostname match and only TLS 1.2/1.3 give grade A.

Renewing

Replace the certificate and key files at the same paths, then run configtest and reload. Apache keeps using the old certificate until it reloads. With Certbot's --apache plugin, renewals reload Apache automatically; with other methods, add a deploy hook.

Troubleshooting

  • SSL Library Error / "key values mismatch" on start: the private key doesn't belong to the certificate.
  • Wrong certificate served: another virtual host on port 443 matches first. Check ServerName/ServerAlias, and run sudo apachectl -S to see which virtual host answers each name.
  • Old certificate still served after renewal: Apache wasn't reloaded, or a load balancer or CDN in front holds its own copy.

CertHalo checks your Apache sites on a schedule and emails you before the certificate expires. Monitor 3 certificates free.

Check your certificate now

See when it expires, who issued it, whether the chain is complete and if it's been revoked. Free, no sign-up.

Want a reminder before it expires? Monitor 3 certificates free.

More guides