Installing SSL Certificates on Apache

Step-by-step guide to configuring SSL/TLS on Apache with mod_ssl. Covers virtual hosts, cipher suites, HSTS, OCSP stapling, and common pitfalls.


Before You Start

Apache uses mod_ssl for TLS. You need three things:

  • Certificate file (SSLCertificateFile) -- your server's PEM certificate
  • Private key file (SSLCertificateKeyFile) -- the matching private key
  • Chain file (SSLCertificateChainFile or included in the cert) -- intermediate CA certificates

Don't have a certificate yet? Generate a test one at getaCert.com to follow along, or get a CA-signed certificate at /casign.

Enable mod_ssl

On Debian/Ubuntu:

sudo a2enmod ssl
sudo a2enmod headers
sudo systemctl restart apache2

On RHEL/CentOS:

sudo yum install mod_ssl
sudo systemctl restart httpd

Basic SSL Virtual Host

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

    SSLEngine on
    SSLCertificateFile      /etc/ssl/certs/example.com.pem
    SSLCertificateKeyFile   /etc/ssl/private/example.com.key
    SSLCertificateChainFile /etc/ssl/certs/chain.pem
</VirtualHost>

Test the config before restarting:

apachectl configtest
sudo systemctl reload apache2

Production-Ready Configuration

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

    SSLEngine on
    SSLCertificateFile      /etc/ssl/certs/example.com.pem
    SSLCertificateKeyFile   /etc/ssl/private/example.com.key
    SSLCertificateChainFile /etc/ssl/certs/chain.pem

    # Modern TLS only
    SSLProtocol             all -SSLv3 -TLSv1 -TLSv1.1
    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

    # HSTS - tell browsers to always use HTTPS
    Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains"

    # OCSP Stapling
    SSLUseStapling          on
    SSLStaplingResponderTimeout 5
    SSLStaplingReturnResponderErrors off
</VirtualHost>

# OCSP Stapling cache (must be outside VirtualHost)
SSLStaplingCache shmcb:/var/run/ocsp(128000)

# Redirect HTTP to HTTPS
<VirtualHost *:80>
    ServerName example.com
    Redirect permanent / https://example.com/
</VirtualHost>

Installing a PKCS#12 (.p12) Certificate

If you downloaded a .p12 bundle from getaCert.com, extract the PEM files first:

# Extract the certificate
openssl pkcs12 -in certificate.p12 -clcerts -nokeys -out cert.pem

# Extract the private key
openssl pkcs12 -in certificate.p12 -nocerts -nodes -out key.pem

# Extract the CA chain (if included)
openssl pkcs12 -in certificate.p12 -cacerts -nokeys -out chain.pem

The default password for getaCert.com PKCS#12 files is password. Change it for production use.

Verify Your Configuration

After reloading Apache, test your SSL setup:

# Quick test
openssl s_client -connect example.com:443 -servername example.com

# Check certificate details
openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -text -noout

# Or use our SSL checker
# https://getacert.com/check

Common Apache SSL Mistakes

Wrong file permissions

Apache needs to read the private key but nobody else should:

sudo chmod 600 /etc/ssl/private/example.com.key
sudo chown root:root /etc/ssl/private/example.com.key

Missing chain file

If browsers show "certificate not trusted" but the cert itself is valid, you're probably missing the intermediate chain. Either provide SSLCertificateChainFile separately or concatenate it into your cert file:

cat example.com.pem intermediate.pem > fullchain.pem

Mixed content after enabling HTTPS

Your site loads over HTTPS but images, scripts, or stylesheets still reference http://. Fix by using relative URLs or protocol-relative paths in your HTML, or add a Content-Security-Policy header:

Header set Content-Security-Policy "upgrade-insecure-requests"

Port 443 not listening

If Apache won't start with SSL, check that port 443 is configured in /etc/apache2/ports.conf:

Listen 443

Apache vs Nginx SSL Performance

Apache's mod_ssl and nginx's SSL implementation are both built on OpenSSL, so raw TLS performance is similar. The main differences:

  • Apache prefork creates a new process per connection -- higher memory for many concurrent TLS sessions
  • Apache event/worker MPM handles concurrent connections more efficiently, similar to nginx
  • Session caching works differently: Apache uses SSLSessionCache, nginx uses ssl_session_cache

For most sites, the difference is negligible. Choose based on what you already run.

Next Steps


More in Guides