Apache Security Hardening: The Complete Configuration Guide
Apache security is not automatic. A default Apache installation broadcasts its version and module list to every visitor, accepts outdated TLS protocols, and provides no security headers whatsoever. This guide fixes every one of those issues with practical configuration snippets you can apply immediately.
Start by running a free ZeriFlow scan on your domain to establish a baseline security score. Then work through each section below and scan again at the end to confirm your improvements.
Hiding Server Information: ServerTokens and ServerSignature
By default, Apache includes its full version number and loaded modules in HTTP response headers and error pages. This is reconnaissance gold for attackers — they know exactly which version-specific vulnerabilities to attempt.
Add these directives to your main Apache configuration (usually /etc/apache2/apache2.conf or /etc/httpd/conf/httpd.conf):
ServerTokens Prod
ServerSignature OffServerTokens Prod: Reduces theServerheader toApacheonly, removing the version number and OS information.ServerSignature Off: Removes the server information footer from error pages and directory listings.
Disable directory listings:
Options -IndexesThis prevents Apache from generating a file browser when no index file exists in a directory — a common source of accidental information disclosure.
Disable unused modules: Apache ships with many modules enabled by default that you may not need. Run apache2ctl -M to list active modules and disable anything unused with a2dismod:
a2dismod status # Removes /server-status endpoint
a2dismod info # Removes /server-info endpoint
a2dismod autoindex # Disables directory listing (alternative to -Indexes)SSL/TLS Configuration: Enforcing Modern Protocols
Apache's default SSL configuration accepts protocols and ciphers that have known vulnerabilities. Here is a production-ready SSL configuration using mod_ssl:
<VirtualHost *:443>
ServerName yourdomain.com
SSLEngine on
SSLCertificateFile /etc/ssl/certs/yourdomain.crt
SSLCertificateKeyFile /etc/ssl/private/yourdomain.key
SSLCertificateChainFile /etc/ssl/certs/chain.crt
# Only TLS 1.2 and 1.3
SSLProtocol -all +TLSv1.2 +TLSv1.3
# Modern cipher suite (Mozilla Intermediate)
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
SSLHonorCipherOrder off
# OCSP Stapling
SSLUseStapling on
SSLStaplingResponderTimeout 5
SSLStaplingReturnResponderErrors off
</VirtualHost>
# Required for OCSP Stapling (outside VirtualHost)
SSLStaplingCache 'shmcb:/var/run/apache2/stapling_cache(128000)'HTTP to HTTPS redirect:
<VirtualHost *:80>
ServerName yourdomain.com
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</VirtualHost>Security Headers via mod_headers
Apache's mod_headers module lets you add security headers to every response. Ensure the module is enabled first:
a2enmod headers
systemctl restart apache2Then add these to your VirtualHost or to a global conf file:
<IfModule mod_headers.c>
Header always set X-Frame-Options 'DENY'
Header always set X-Content-Type-Options 'nosniff'
Header always set X-XSS-Protection '1; mode=block'
Header always set Referrer-Policy 'strict-origin-when-cross-origin'
Header always set Permissions-Policy 'geolocation=(), microphone=(), camera=()'
Header always set Strict-Transport-Security 'max-age=31536000; includeSubDomains; preload'
Header always set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' https:; frame-ancestors 'none';"
# Remove potentially leaky headers
Header unset X-Powered-By
Header unset X-AspNet-Version
Header unset X-AspNetMvc-Version
</IfModule>The always keyword ensures headers are sent on all response codes, including 3xx, 4xx, and 5xx — not just 200 OK responses.
.htaccess Security Configuration
For shared hosting or situations where you cannot modify the main Apache configuration, .htaccess files provide a powerful alternative. Place this in your site's root directory:
# Disable directory browsing
Options -Indexes -Includes
# Enable rewrite engine
RewriteEngine On
# Force HTTPS
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
# Block access to sensitive files
<FilesMatch '(\.(bak|conf|dist|fla|inc|ini|log|psd|sh|sql|swp|yaml|yml)|~)$'>
Require all denied
</FilesMatch>
# Block access to .git directory
RedirectMatch 404 /\.git
# Security headers (requires mod_headers)
<IfModule mod_headers.c>
Header always set X-Frame-Options 'SAMEORIGIN'
Header always set X-Content-Type-Options 'nosniff'
Header always set Strict-Transport-Security 'max-age=31536000'
</IfModule>
# Limit request size to prevent DoS
LimitRequestBody 10485760
# Disable HTTP TRACE method
TraceEnable offNote: .htaccess is processed on every request, adding slight overhead. For performance-critical applications, apply these settings in httpd.conf or a VirtualHost block with AllowOverride None and move all rules to the main configuration.
Rate Limiting With mod_ratelimit and mod_evasive
Apache does not have built-in rate limiting as flexible as Nginx, but mod_evasive provides basic DDoS and brute-force protection:
apt-get install libapache2-mod-evasive
a2enmod evasiveConfiguration in /etc/apache2/mods-available/evasive.conf:
<IfModule mod_evasive20.c>
DOSHashTableSize 2048
DOSPageCount 5
DOSSiteCount 50
DOSPageInterval 1
DOSSiteInterval 1
DOSBlockingPeriod 600
DOSLogDir /var/log/apache2/evasive
DOSEmailNotify your-email@domain.com
</IfModule>This blocks any IP that requests the same page more than 5 times per second or makes more than 50 requests to the site per second, for 600 seconds.
Verify Everything With ZeriFlow
After completing these changes, run apachectl -t to verify there are no syntax errors, then restart Apache with systemctl restart apache2.
Run a ZeriFlow security scan on your domain to verify: - Security headers are present and correctly formatted - TLS protocol version and cipher strength - Server information disclosure has been eliminated - HTTPS redirect is working - HSTS header configuration
FAQ
### Q: Should I use .htaccess or VirtualHost for security headers? A: VirtualHost (or the main httpd.conf) is always preferred for performance. .htaccess is parsed on every request, while VirtualHost directives are loaded once at startup. Use .htaccess only when you do not have access to the main configuration files.
### Q: How do I check which Apache modules are currently loaded?
A: Run apache2ctl -M (Ubuntu/Debian) or httpd -M (RHEL/CentOS). This lists all static and shared modules. Disable any module you do not actively use with a2dismod <module_name>.
### Q: Does ServerTokens Prod completely hide that I am running Apache?
A: It hides the version, but the Server: Apache header still reveals the server software. Completely hiding this requires the mod_security module with a custom SecServerSignature directive, or a reverse proxy (like Cloudflare) in front of your server.
### Q: Can I use Let's Encrypt certificates with this Apache SSL configuration?
A: Yes. Certbot automatically generates a compatible Apache SSL configuration when you run certbot --apache. Review the generated configuration against the snippet above to ensure strong protocols and ciphers are enforced — Certbot's defaults are good but occasionally conservative on older systems.
Conclusion
Apache security hardening is a systematic process. Start with information disclosure (ServerTokens, ServerSignature), move to TLS hardening, add security headers, and finish with rate limiting and access controls. Each layer adds protection that the previous layers cannot provide alone.
The configurations in this guide follow the Mozilla SSL Configuration guidelines and OWASP security header recommendations — the same standards used by major enterprises worldwide.
Scan your Apache server with ZeriFlow after applying these settings. The free scan runs 80+ security checks and gives you an objective score with specific, actionable findings for any remaining issues.