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 |
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).
Workflow: Verify SSL Certificate Setup
- Use
openssl s_clientto connect to the server - Check that the certificate chain is complete
- Confirm that the certificate matches the domain name
- 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.