Skip to main content

Configuring SSL/TLS Certificates

1. Enabling SSL Module

Directive Values Description
LoadModule ssl_module modules/mod_ssl.so Loads the SSL module into the server
SSLEngine on | off Enables or disables SSL for the current context

Example: Enabling SSL Module

<IfModule ssl_module>
    LoadModule ssl_module modules/mod_ssl.so
    SSLEngine on
</IfModule>

2. Configuring SSLEngine Directive

Directive Values Description
SSLEngine on, off, start Enables or disables SSL/TLS for a virtual host or directory. on enables it, off disables it, and start enables it only if a client requests a secure connection.

Example: Enabling SSL for a Virtual Host

<VirtualHost *:443>
    ServerName example.com
    SSLEngine on
    SSLCertificateFile /path/to/certificate.crt
    SSLCertificateKeyFile /path/to/private.key
</VirtualHost>
Note: The SSLEngine directive must be set to on for any SSL/TLS configuration to take effect.

3. Setting SSL Certificate File

Directive Values Description
SSLCertificateFile /path/to/certificate.crt Path to the SSL certificate file (PEM format)
SSLCertificateKeyFile /path/to/private.key Path to the private key file (PEM format)
SSLCertificateChainFile /path/to/chain.crt Path to the certificate chain file (optional)

Example: Basic SSL Configuration

<VirtualHost *:443>
    ServerName example.com
    SSLEngine on
    SSLCertificateFile /etc/ssl/certs/example.com.crt
    SSLCertificateKeyFile /etc/ssl/private/example.com.key
    SSLCertificateChainFile /etc/ssl/certs/intermediate.crt
</VirtualHost>
Note: Ensure the certificate file and key are readable by the Apache user. The certificate must be in PEM format.

4. Setting SSL Private Key

Directive Description Default Notes
SSLCertificateKeyFile Specifies the file path to the private key for the server certificate None Required when using SSL/TLS
SSLOptions Configures various SSL options for the server None Can include StdEnvVars, ExportCertData

Example: Setting SSL Private Key

<VirtualHost *:443>
    ServerName example.com
    SSLEngine on
    SSLCertificateFile /etc/ssl/certs/example.com.crt
    SSLCertificateKeyFile /etc/ssl/private/example.com.key
</VirtualHost>
Note: The private key must be readable by the Apache process and not accessible to others.

5. Configuring Certificate Chain

Directive Description Values Notes
SSLCertificateChainFile Specifies the file containing the certificate chain for the server certificate /path/to/chain.pem Used to provide intermediate certificates needed for trust chain validation
SSLCertificateChainPath Specifies the directory containing certificate files to be used in the chain /path/to/certs/ Alternative to SSLCertificateChainFile, useful for directory-based certificate management

Example: Setting up Certificate Chain

<VirtualHost *:443>
    ServerName example.com
    SSLEngine on
    SSLCertificateFile /etc/ssl/certs/server.crt
    SSLCertificateChainFile /etc/ssl/certs/chain.pem
    SSLCertificateKeyFile /etc/ssl/private/server.key
</VirtualHost>
Note: The certificate chain must be in the correct order, starting with the server certificate and ending with the root CA certificate.

6. Setting CA Certificate

Directive Values Description
SSLCACertificatePath /etc/ssl/certs/ Directory containing CA certificates in PEM format
SSLCACertificateFile /etc/ssl/certs/ca-bundle.crt File containing CA certificates in PEM format

Example: Setting CA Certificate Path

<VirtualHost *:443>
    SSLEngine on
    SSLCertificateFile /etc/ssl/certs/server.crt
    SSLCertificateKeyFile /etc/ssl/private/server.key
    SSLCACertificatePath /etc/ssl/certs/
</VirtualHost>
Note: Ensure the CA certificate files are readable by the Apache user.

7. Generating Self-Signed Certificates

Self-signed certificates are useful for testing or internal use where external validation is not required. They can be generated using the OpenSSL command-line tool.

Command Description Notes
openssl req -new -x509 -days 365 -nodes -out server.crt -keyout server.key Generate a self-signed certificate and private key Creates a 365-day valid certificate with no passphrase

Example: Generate Self-Signed Certificate

openssl req -new -x509 -days 365 -nodes -out server.crt -keyout server.key
Note: The generated certificate will not be trusted by browsers or clients unless explicitly added to their trust store.

8. Installing Let's Encrypt Certificates

Example: Install Certbot for Apache on Ubuntu

# Update package index
sudo apt update

# Install Certbot and Apache plugin
sudo apt install certbot python3-certbot-apache

# Obtain certificate for domain
sudo certbot --apache -d example.com -d www.example.com
Command Description Notes
certbot --apache Install certificate using Apache plugin Automatically configures SSL in Apache
-d example.com Specify domain(s) to obtain certificate for Can be repeated for multiple domains
--dry-run Test run without installing certificate Use to verify configuration before actual install
Note: Certbot requires root privileges to modify Apache config files.
Warning: Ensure DNS records are correctly configured before running Certbot to avoid validation errors.

Installation Steps

  • Install Certbot with Apache plugin via package manager
  • Run certbot --apache -d domain.com
  • Certbot automatically configures Apache virtual hosts
  • Verify certificate is installed in /etc/letsencrypt/live/

9. Configuring Certificate Renewal

Example: Setting up automatic renewal with Certbot

sudo certbot --apache --agree-tos --redirect --hsts --staple-ocsp --email admin@example.com --domains example.com
Option Values Description
--apache true Installs and configures Apache modules for SSL
--agree-tos true Agrees to Let's Encrypt Terms of Service
--redirect true Automatically redirects HTTP to HTTPS
--hsts true Enables HTTP Strict Transport Security (HSTS)
--staple-ocsp true Enables OCSP stapling for improved performance
--email admin@example.com Contact email for security notices and renewal reminders
--domains example.com Domain(s) to obtain and install certificate for
Note: Certbot will automatically set up a cron job or systemd timer to renew certificates before they expire.
Warning: Ensure that your server can reach the internet and has proper DNS resolution for the domains involved to allow successful renewal.

Renewal Process Overview

  • Certbot checks if certificate is due for renewal (typically 30 days before expiration)
  • It renews the certificate using the same configuration
  • The renewal process updates the Apache config files with new certificate paths
  • Apache is automatically reloaded to apply changes

10. Setting Up Client Certificate Authentication

Directive Description Values Notes
SSLVerifyClient Enables client certificate verification off, on, require, optional Use require for mandatory client cert auth
SSLVerifyDepth Maximum number of intermediate certificates in the chain 1 to 10 Default is 1. Set higher for complex chains
SSLCACertificateFile Path to CA certificate file File path Required when using client certs from a CA
SSLCACertificatePath Directory containing CA certificates Directory path Alternative to SSLCACertificateFile
SSLClientCertificateCookie Name of cookie to store client certificate info String Optional, used for session persistence

Example: Basic Client Cert Setup

<VirtualHost *:443>
    SSLEngine on
    SSLCertificateFile /path/to/server.crt
    SSLCertificateKeyFile /path/to/server.key

    # Enable client cert auth
    SSLVerifyClient require
    SSLVerifyDepth 2
    SSLCACertificateFile /path/to/ca.crt

    # Optional: Cookie for session persistence
    SSLClientCertificateCookie client_cert
</VirtualHost>
Note: Client certificate authentication requires both server and client certificates to be properly configured and trusted.
Warning: Setting SSLVerifyClient to require will block access to the site for users without valid client certificates.

11. Testing Certificate Configuration

Example: Test SSL Configuration with OpenSSL

openssl s_client -connect example.com:443 -servername example.com
Command Description Output
openssl s_client Connects to a server and displays certificate info Certificate details, expiration, issuer
Note: Ensure the server name matches the certificate's Subject Alternative Name (SAN) or Common Name (CN).

Example: Validate Certificate Chain

openssl s_client -connect example.com:443 -showcerts

Workflow: Verify SSL Certificate Setup

  1. Use openssl s_client to connect to the server
  2. Check that the certificate chain is complete
  3. Confirm that the certificate matches the domain name
  4. Verify that the certificate is not expired

12. Troubleshooting Certificate Issues

Issue Possible Cause Solution
SSL Certificate not trusted Certificate is self-signed or issued by an untrusted CA Install the issuing CA certificate in the browser's trust store or use a certificate from a known CA
Certificate expired SSL certificate has passed its validity date Renew the certificate with a new valid one from a CA
Domain mismatch Certificate does not match the domain being accessed Ensure the certificate includes the correct Subject Alternative Names (SANs) or Common Name (CN)
Intermediate certificate missing Server does not send the intermediate certificate chain Configure Apache to include the full certificate chain in SSLCertificateChainFile
Private key mismatch Private key does not match the public key in the certificate Verify that the private key file matches the certificate using openssl x509 -noout -modulus -in cert.pem | openssl md5 and openssl rsa -noout -modulus -in key.pem | openssl md5
Permission denied Apache cannot read the certificate or key files Ensure proper file permissions (e.g., 600) and ownership (e.g., root:root) for certificate and key files

Example: Check certificate and key match

openssl x509 -noout -modulus -in /etc/ssl/certs/server.crt | openssl md5
openssl rsa -noout -modulus -in /etc/ssl/private/server.key | openssl md5
Note: Use openssl verify to check if the certificate is valid and trusted by the system.
Warning: Never expose private keys in logs or error messages. Ensure they are protected with strict file permissions.

Was this article helpful?