SSL Configuration: Nginx vs Apache Complete Guide 2025
Nginx and Apache are the most popular web servers, each with unique SSL configuration approaches. This guide compares both and provides optimized configurations.
Nginx SSL Configuration
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name example.com www.example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
resolver 8.8.8.8 8.8.4.4 valid=300s;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
root /var/www/html;
index index.html;
}
Apache SSL Configuration
ServerName example.com
ServerAlias www.example.com
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [R=301,L]
ServerName example.com
ServerAlias www.example.com
DocumentRoot /var/www/html
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
SSLProtocol -all +TLSv1.2 +TLSv1.3
SSLCipherSuite HIGH:!aNULL:!MD5
SSLHonorCipherOrder on
SSLSessionCache "shmcb:/var/cache/mod_ssl/scache(512000)"
SSLSessionCacheTimeout 300
SSLSessionTickets off
SSLUseStapling on
SSLStaplingCache "shmcb:logs/ssl_stapling(32768)"
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
Performance Comparison
| Feature | Nginx | Apache |
|---|---|---|
| SSL Performance | Excellent | Good |
| Memory Usage | Low | Higher |
| Configuration | Simple | More complex |
| HTTP/2 Support | Native | Module required |
Best Practices (Both Servers)
- Use TLS 1.2 and 1.3 only
- Enable OCSP stapling
- Configure session caching
- Disable session tickets
- Enable HSTS
- Use strong cipher suites
- Enable HTTP/2
Web Server Market Share
Nginx and Apache dominate the web server market, powering over 60% of all websites globally. Understanding their SSL/TLS implementation differences is crucial for optimal security and performance. While both servers support modern TLS standards, their configuration approaches and performance characteristics differ significantly.
Architecture Differences
Apache uses a process-based or thread-based architecture, creating new processes or threads for each connection. This approach is resource-intensive under high load. Nginx uses an event-driven, asynchronous architecture that handles thousands of concurrent connections with minimal resource usage. These architectural differences significantly impact SSL/TLS performance.
SSL Performance Comparison
Nginx typically outperforms Apache for SSL/TLS connections due to its efficient event-driven architecture. Nginx can handle 10,000+ concurrent SSL connections on modest hardware, while Apache may struggle with 1,000 connections. However, Apache's modular architecture provides more flexibility for complex configurations.
Configuration Philosophy
Apache uses a hierarchical configuration with .htaccess files and virtual host contexts. SSL directives can be placed in multiple locations, providing flexibility but potentially causing confusion. Nginx uses a single configuration file structure with included files, making SSL configuration more centralized and easier to audit.
Advanced Nginx SSL Configuration
# Production-Ready Nginx SSL Configuration
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.com www.example.com;
# Certificates
ssl_certificate /etc/nginx/ssl/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/privkey.pem;
ssl_trusted_certificate /etc/nginx/ssl/chain.pem;
# Modern SSL Configuration
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384';
ssl_prefer_server_ciphers on;
ssl_ecdh_curve X25519:secp384r1;
# Session Resumption
ssl_session_cache shared:SSL:50m;
ssl_session_timeout 1d;
ssl_session_tickets off;
# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
# Security Headers
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
# Logging
access_log /var/log/nginx/ssl_access.log combined;
error_log /var/log/nginx/ssl_error.log warn;
location / {
root /var/www/html;
index index.html;
}
}
Advanced Apache SSL Configuration
# Production-Ready Apache SSL Configuration
ServerName example.com
ServerAlias www.example.com
DocumentRoot /var/www/html
# Enable SSL
SSLEngine on
SSLCertificateFile /etc/apache2/ssl/fullchain.pem
SSLCertificateKeyFile /etc/apache2/ssl/privkey.pem
SSLCertificateChainFile /etc/apache2/ssl/chain.pem
# Modern SSL Configuration
SSLProtocol -all +TLSv1.2 +TLSv1.3
SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384
SSLHonorCipherOrder on
SSLCompression off
# Session Resumption
SSLSessionCache "shmcb:/var/cache/mod_ssl/scache(512000)"
SSLSessionCacheTimeout 86400
SSLSessionTickets off
# OCSP Stapling
SSLUseStapling on
SSLStaplingCache "shmcb:logs/ssl_stapling(32768)"
SSLStaplingResponderTimeout 5
SSLStaplingReturnResponderErrors off
# Security Headers
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
Header always set X-Frame-Options "SAMEORIGIN"
Header always set X-Content-Type-Options "nosniff"
Header always set X-XSS-Protection "1; mode=block"
# Logging
CustomLog /var/log/apache2/ssl_access.log combined
ErrorLog /var/log/apache2/ssl_error.log
Performance Tuning
Nginx Performance Optimization
Nginx worker processes should match CPU cores. Use worker_connections to control maximum concurrent connections per worker. Enable sendfile and tcp_nopush for efficient file serving. Configure appropriate buffer sizes for SSL operations.
Apache Performance Optimization
Choose appropriate MPM (Multi-Processing Module): prefork for compatibility, worker for better performance, or event for best performance with SSL. Tune MaxRequestWorkers and ThreadsPerChild based on available memory and expected load. Enable mod_http2 for HTTP/2 support.
Load Balancing and High Availability
Both Nginx and Apache can function as SSL-terminating load balancers. Nginx excels at this role due to its efficient connection handling. Apache requires mod_proxy_balancer and careful tuning for load balancing scenarios. Consider dedicated load balancers like HAProxy for large-scale deployments.
Monitoring and Logging
Implement comprehensive SSL logging including protocol versions, cipher suites, and handshake times. Use log analysis tools to identify performance bottlenecks and security issues. Monitor SSL certificate expiration and renewal status.
Migration Strategies
Migrating between Nginx and Apache requires careful planning. Test SSL configurations thoroughly in staging environments. Use gradual rollout strategies with traffic splitting. Maintain configuration documentation for both platforms during transition periods.