Configure Apache SSL hardening with perfect forward secrecy and modern security protocols

Intermediate 25 min Jun 02, 2026 105 views
Ubuntu 24.04 Debian 12 AlmaLinux 9 Rocky Linux 9

Harden Apache HTTP server with modern SSL/TLS configuration, perfect forward secrecy cipher suites, and security headers to protect against common web vulnerabilities and ensure compliance with security standards.

Prerequisites

  • Apache HTTP server
  • Root or sudo access
  • Basic understanding of SSL/TLS concepts

What this solves

Apache's default SSL configuration uses outdated protocols and weak cipher suites that expose your web applications to security vulnerabilities. This tutorial configures Apache with modern TLS protocols, perfect forward secrecy (PFS) cipher suites, and essential security headers including HSTS, CSP, and X-Frame-Options to protect against man-in-the-middle attacks, protocol downgrade attacks, and common web vulnerabilities.

Step-by-step configuration

Update system packages

Start by updating your package manager to ensure you have the latest security patches and Apache modules.

sudo apt update && sudo apt upgrade -y
sudo dnf update -y

Install Apache and SSL modules

Install Apache HTTP server with the SSL module and headers module required for security hardening.

sudo apt install -y apache2 apache2-utils
sudo a2enmod ssl
sudo a2enmod headers
sudo a2enmod rewrite
sudo dnf install -y httpd mod_ssl
sudo systemctl enable httpd

Generate SSL certificate

Create a self-signed certificate for testing or use an existing certificate from Let's Encrypt or a commercial CA.

sudo mkdir -p /etc/apache2/ssl
sudo openssl req -x509 -nodes -days 365 -newkey rsa:4096 \
  -keyout /etc/apache2/ssl/apache-selfsigned.key \
  -out /etc/apache2/ssl/apache-selfsigned.crt \
  -subj "/C=US/ST=State/L=City/O=Organization/OU=OrgUnit/CN=example.com"
Note: For production environments, use certificates from Let's Encrypt or a commercial CA. See our Apache HTTP/2 SSL tutorial for Let's Encrypt integration.

Configure SSL security settings

Create a dedicated SSL security configuration file with modern cipher suites and perfect forward secrecy.

# SSL Security Configuration

Disable SSLv2, SSLv3, and TLS 1.0/1.1

SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1

Perfect Forward Secrecy cipher suites

SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384

Honor cipher order preference of the server

SSLHonorCipherOrder on

Use secure renegotiation

SSLInsecureRenegotiation off

Disable SSL compression to prevent CRIME attacks

SSLCompression off

OCSP Stapling for better performance

SSLUseStapling on SSLStaplingCache "shmcb:logs/stapling-cache(150000)"

Modern Diffie-Hellman parameters

SSLOpenSSLConfCmd DHParameters "/etc/ssl/certs/dhparam.pem"
# SSL Security Configuration

Disable SSLv2, SSLv3, and TLS 1.0/1.1

SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1

Perfect Forward Secrecy cipher suites

SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384

Honor cipher order preference of the server

SSLHonorCipherOrder on

Use secure renegotiation

SSLInsecureRenegotiation off

Disable SSL compression to prevent CRIME attacks

SSLCompression off

OCSP Stapling for better performance

SSLUseStapling on SSLStaplingCache "shmcb:logs/stapling-cache(150000)"

Modern Diffie-Hellman parameters

SSLOpenSSLConfCmd DHParameters "/etc/ssl/certs/dhparam.pem"

Generate strong Diffie-Hellman parameters

Create custom Diffie-Hellman parameters for perfect forward secrecy. This process takes several minutes.

sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
Security Note: For high-security environments, use 4096-bit DH parameters, though this increases handshake time. The command would be sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 4096

Configure security headers

Create a configuration file for essential HTTP security headers including HSTS, CSP, and clickjacking protection.

# HTTP Security Headers

HTTP Strict Transport Security (HSTS)

Force HTTPS for 1 year, include subdomains

Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"

Prevent clickjacking attacks

Header always set X-Frame-Options "SAMEORIGIN"

Prevent MIME type sniffing

Header always set X-Content-Type-Options "nosniff"

Enable XSS protection

Header always set X-XSS-Protection "1; mode=block"

Referrer Policy - limit information leakage

Header always set Referrer-Policy "strict-origin-when-cross-origin"

Content Security Policy (basic - customize for your application)

Header always set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self'; connect-src 'self'; frame-src 'none'; object-src 'none';"

Permissions Policy (formerly Feature Policy)

Header always set Permissions-Policy "geolocation=(), microphone=(), camera=(), payment=(), usb=(), accelerometer=(), gyroscope=(), magnetometer=()"

Remove server signature for security

ServerTokens Prod ServerSignature Off

Hide Apache version

Header always unset Server Header always set Server "Apache"
# HTTP Security Headers

HTTP Strict Transport Security (HSTS)

Force HTTPS for 1 year, include subdomains

Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"

Prevent clickjacking attacks

Header always set X-Frame-Options "SAMEORIGIN"

Prevent MIME type sniffing

Header always set X-Content-Type-Options "nosniff"

Enable XSS protection

Header always set X-XSS-Protection "1; mode=block"

Referrer Policy - limit information leakage

Header always set Referrer-Policy "strict-origin-when-cross-origin"

Content Security Policy (basic - customize for your application)

Header always set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self'; connect-src 'self'; frame-src 'none'; object-src 'none';"

Permissions Policy (formerly Feature Policy)

Header always set Permissions-Policy "geolocation=(), microphone=(), camera=(), payment=(), usb=(), accelerometer=(), gyroscope=(), magnetometer=()"

Remove server signature for security

ServerTokens Prod ServerSignature Off

Hide Apache version

Header always unset Server Header always set Server "Apache"

Create secure virtual host

Configure a virtual host with SSL hardening and security headers applied.


    ServerName example.com
    ServerAlias www.example.com
    
    # Redirect all HTTP to HTTPS
    RewriteEngine On
    RewriteCond %{HTTPS} !=on
    RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]



    ServerName example.com
    ServerAlias www.example.com
    DocumentRoot /var/www/html
    
    # SSL Configuration
    SSLEngine on
    SSLCertificateFile /etc/apache2/ssl/apache-selfsigned.crt
    SSLCertificateKeyFile /etc/apache2/ssl/apache-selfsigned.key
    
    # Apply security configurations
    Include /etc/apache2/conf-available/ssl-security.conf
    Include /etc/apache2/conf-available/security-headers.conf
    
    # Logging
    ErrorLog ${APACHE_LOG_DIR}/secure-site-error.log
    CustomLog ${APACHE_LOG_DIR}/secure-site-access.log combined
    
    # Additional security directives
    
        AllowOverride None
        Require all granted
        Options -Indexes -Includes -ExecCGI
    
    
    # Deny access to sensitive files
    
        Require all denied
    

    ServerName example.com
    ServerAlias www.example.com
    
    # Redirect all HTTP to HTTPS
    RewriteEngine On
    RewriteCond %{HTTPS} !=on
    RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]



    ServerName example.com
    ServerAlias www.example.com
    DocumentRoot /var/www/html
    
    # SSL Configuration
    SSLEngine on
    SSLCertificateFile /etc/httpd/ssl/apache-selfsigned.crt
    SSLCertificateKeyFile /etc/httpd/ssl/apache-selfsigned.key
    
    # Apply security configurations
    Include /etc/httpd/conf.d/ssl-security.conf
    Include /etc/httpd/conf.d/security-headers.conf
    
    # Logging
    ErrorLog logs/secure-site-error.log
    CustomLog logs/secure-site-access.log combined
    
    # Additional security directives
    
        AllowOverride None
        Require all granted
        Options -Indexes -Includes -ExecCGI
    
    
    # Deny access to sensitive files
    
        Require all denied
    

Enable configurations and restart Apache

Enable the security configurations and virtual host, then restart Apache to apply changes.

sudo a2enconf ssl-security
sudo a2enconf security-headers
sudo a2ensite secure-site
sudo a2dissite 000-default
sudo apache2ctl configtest
sudo systemctl restart apache2
sudo mkdir -p /etc/httpd/ssl
sudo cp /etc/apache2/ssl/apache-selfsigned.* /etc/httpd/ssl/
sudo httpd -t
sudo systemctl restart httpd

Configure firewall rules

Open HTTP and HTTPS ports in the firewall to allow web traffic.

sudo ufw allow 'Apache Full'
sudo ufw --force enable
sudo ufw status
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
sudo firewall-cmd --list-services

Test SSL configuration and security validation

Verify SSL certificate and protocols

Test the SSL configuration using OpenSSL to ensure proper protocol and cipher suite negotiation.

# Test TLS 1.3 connection
openssl s_client -connect example.com:443 -tls1_3 -servername example.com

Test TLS 1.2 connection

openssl s_client -connect example.com:443 -tls1_2 -servername example.com

Test that weak protocols are disabled (should fail)

openssl s_client -connect example.com:443 -tls1_1 -servername example.com openssl s_client -connect example.com:443 -ssl3 -servername example.com

Test cipher suites and perfect forward secrecy

Verify that only strong cipher suites with PFS are available.

# Test ECDHE cipher (should work - provides PFS)
openssl s_client -connect example.com:443 -cipher 'ECDHE-RSA-AES256-GCM-SHA384'

Test weak cipher (should fail)

openssl s_client -connect example.com:443 -cipher 'RC4-SHA'

List all available ciphers

nmap --script ssl-enum-ciphers -p 443 example.com

Verify security headers

Check that all security headers are properly configured and transmitted.

# Test security headers
curl -I https://example.com

Test specific headers

curl -s -D- https://example.com | grep -i "strict-transport-security\|x-frame-options\|x-content-type-options\|content-security-policy"

Verify your setup

# Check Apache status and SSL module
sudo systemctl status apache2
sudo apache2ctl -M | grep ssl

Verify SSL certificate

openssl x509 -in /etc/apache2/ssl/apache-selfsigned.crt -text -noout

Test HTTPS redirect

curl -I http://example.com

Check SSL Labs rating (replace with your domain)

Visit: https://www.ssllabs.com/ssltest/analyze.html?d=example.com

Common issues

SymptomCauseFix
SSL handshake failuresWeak cipher suites or protocolsCheck SSLCipherSuite and SSLProtocol directives
Browser certificate warningsSelf-signed certificateUse Let's Encrypt or commercial CA certificate
HSTS not workingHeaders module not enabledsudo a2enmod headers && sudo systemctl restart apache2
Configuration test failsSyntax errors in config filessudo apache2ctl configtest to identify issues
OCSP stapling errorsMissing intermediate certificatesAdd SSLCertificateChainFile directive with chain
Perfect Forward Secrecy failingMissing DH parametersEnsure /etc/ssl/certs/dhparam.pem exists and is referenced

Next steps

Running this in production?

Want this handled for you? Setting this up once is straightforward. Keeping it patched, monitored, backed up and tuned across environments is the harder part. See how we run infrastructure like this for European SaaS and e-commerce teams.

Automated install script

Run this to automate the entire setup

Need help?

Don't want to manage this yourself?

We handle infrastructure security hardening for businesses that depend on uptime. From initial setup to ongoing operations.