aethercert
Documentation

Replace the SSL Certificate on Apache HTTP Server

Swap the SSL certificate on Apache 2.4 (Debian/Ubuntu and RHEL): find the vhost files, build the chain, check the key, apachectl configtest, graceful reload and verification.

Apache HTTP Server 2.4 reads the certificate and key from SSLCertificateFile and SSLCertificateKeyFile in each TLS virtual host. Since Apache 2.4.8, the certificate file can contain the intermediate certificates after the server certificate, so SSLCertificateChainFile is no longer needed.

Debian / UbuntuRHEL / Rocky / Alma
Configuration/etc/apache2//etc/httpd/ (TLS: conf.d/ssl.conf)
Typical certificate paths/etc/ssl/certs/, /etc/ssl/private//etc/pki/tls/certs/, /etc/pki/tls/private/
Serviceapache2httpd

Before you begin

  • Find which virtual host uses which files. apachectl -S lists the virtual hosts and their configuration files; grep shows the certificate lines:

    sudo apachectl -S
    sudo grep -Rn 'SSLCertificate' /etc/apache2 /etc/httpd 2>/dev/null
  • Prepare the server certificate (leaf.pem), the intermediate(s) (intermediates.pem) and the private key (private.key), all PEM. Do not include the root CA.

  • Back up the current files with their permissions:

    sudo cp -a /etc/pki/tls/certs/www.crt /etc/pki/tls/certs/www.crt.bak
    sudo cp -a /etc/pki/tls/private/www.key /etc/pki/tls/private/www.key.bak

Step-by-step certificate replacement

  1. Build the chain - server certificate first - and check that the key belongs to it:

    cat leaf.pem intermediates.pem > fullchain.pem
    openssl verify -untrusted intermediates.pem leaf.pem
    openssl pkey -in private.key -pubout | sha256sum
    openssl x509 -in leaf.pem -noout -pubkey | sha256sum

    openssl verify must print OK, and the two hashes must be identical.

  2. Install the files at the paths the virtual host uses. The key can be readable by root only: Apache's parent process runs as root and reads it, also on a graceful reload, before handing work to the child processes.

    sudo install -m 0644 fullchain.pem /etc/pki/tls/certs/www.crt
    sudo install -m 0600 private.key   /etc/pki/tls/private/www.key
    sudo restorecon -v /etc/pki/tls/certs/www.crt /etc/pki/tls/private/www.key  # SELinux systems
    SSLEngine on
    SSLCertificateFile    "/etc/pki/tls/certs/www.crt"
    SSLCertificateKeyFile "/etc/pki/tls/private/www.key"
  3. Test the configuration, then reload gracefully:

    sudo apachectl configtest
    sudo systemctl reload httpd      # RHEL
    # sudo systemctl reload apache2  # Debian/Ubuntu

    configtest checks the syntax, not whether key and certificate match - that is why step 1 checks it. On both distributions, systemctl reload performs a graceful restart: running requests finish, new connections get the new certificate, nobody is disconnected.

Encrypted private keys

A key with a passphrase makes Apache ask for it on every start and reload - a service started by systemd cannot answer, and the start fails. Either use an unencrypted key protected by file permissions (remove the passphrase with openssl pkey -in encrypted.key -out private.key), or configure SSLPassPhraseDialog with a program that supplies the passphrase, as your key-management policy requires.

Verify the new certificate

openssl s_client -connect www.example.com:443 -servername www.example.com -showcerts </dev/null
sudo journalctl -u httpd --since "10 minutes ago"     # or -u apache2

Check subject and SAN, issuer, expiry date and that the intermediate is sent - for every name-based virtual host, with its own name as -servername.

Rollback

Copy the .bak files back, run apachectl configtest, and reload. Keep the backup until the new certificate is verified.

Common problems

  • The change was made in the wrong configuration tree (apache2 vs httpd) or for the wrong virtual host.
  • The chain is incomplete, or the key does not match.
  • An encrypted key blocks the start or reload.
  • SELinux denies access to files without the right label (restorecon).
  • A different SNI virtual host was tested.

Automating certificate replacement with aethercert

The aethercert Apache preset writes the configured certificate/chain and private-key files and runs the configured reload command. The default is systemctl reload apache2; on RHEL-based systems set it to systemctl reload httpd.

See Deploy targets for the fields this preset takes, what it needs on the host, and how far it has been verified.

Sources

On this page