Apache HTTP Server has been running the web since 1995. It powers roughly a quarter of all websites and is deeply embedded in enterprise infrastructure. Its maturity is both an advantage and a liability: the server is well-understood and extensively documented, but its default configuration reflects decades of backward compatibility rather than modern security requirements.
Hardening Apache for production requires methodically disabling defaults that were appropriate in 2005 but are liabilities today.
Information Leakage
Disable Server Signature
Apache's default configuration announces its version number in HTTP response headers and on error pages:
Server: Apache/2.4.57 (Ubuntu) OpenSSL/3.0.10
This tells attackers exactly which vulnerabilities apply to your server. Disable it:
ServerTokens Prod
ServerSignature Off
ServerTokens Prod reduces the Server header to just "Apache." ServerSignature Off removes version information from error pages.
Disable Directory Listing
If no index file exists in a directory, Apache's default configuration displays a file listing. This exposes your directory structure, file names, and often sensitive files:
<Directory /var/www/html>
Options -Indexes
</Directory>
Remove Default Content
Apache ships with default welcome pages, documentation, and sample configurations. Remove them from production servers. They provide no value and can reveal information about your Apache version and modules.
Hide PHP and Other Technology Headers
If you run PHP behind Apache, the default configuration adds an X-Powered-By header:
X-Powered-By: PHP/8.2.1
Disable it in php.ini:
expose_php = Off
Similarly, check for and disable technology disclosure headers from any application framework running behind Apache.
Module Security
Disable Unnecessary Modules
Apache loads dozens of modules by default. Each module adds attack surface. Disable modules you do not use:
# List enabled modules
apachectl -M
# Disable a module
a2dismod autoindex
a2dismod status
a2dismod cgi
a2dismod userdir
Common modules that should be disabled unless actively needed: mod_autoindex (directory listings), mod_status (server status page), mod_cgi (CGI script execution), mod_userdir (user home directories), mod_info (server information page), and mod_include (server-side includes).
Secure mod_status
If you need mod_status for monitoring, restrict access:
<Location /server-status>
SetHandler server-status
Require ip 10.0.0.0/8
Require ip 127.0.0.1
</Location>
Never expose mod_status to the internet. It reveals detailed information about server performance, configuration, and connected clients.
Secure mod_proxy
If Apache acts as a reverse proxy, configure mod_proxy carefully:
ProxyRequests Off
<Proxy *>
Require all denied
</Proxy>
<Location /api>
ProxyPass http://backend:8080/api
ProxyPassReverse http://backend:8080/api
Require all granted
</Location>
ProxyRequests Off disables forward proxy functionality, which could be abused for anonymous browsing or SSRF attacks.
TLS Configuration
Use Modern Protocols
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 on
Enable HSTS
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains"
Enable OCSP Stapling
SSLUseStapling on
SSLStaplingCache "shmcb:logs/ssl_stapling(32768)"
Redirect HTTP to HTTPS
<VirtualHost *:80>
ServerName example.com
Redirect permanent / https://example.com/
</VirtualHost>
Access Control
Restrict by IP
For administrative interfaces and internal services:
<Location /admin>
Require ip 10.0.0.0/8
</Location>
Request Limiting
Limit request body size to prevent denial-of-service:
LimitRequestBody 1048576
LimitRequestFields 50
LimitRequestFieldSize 8190
LimitRequestLine 4094
Timeout Configuration
Set appropriate timeouts to prevent slow-loris attacks:
Timeout 60
KeepAliveTimeout 5
MaxKeepAliveRequests 100
Security Headers
Header always set X-Content-Type-Options "nosniff"
Header always set X-Frame-Options "DENY"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Header always set Permissions-Policy "camera=(), microphone=(), geolocation=()"
Header always set Content-Security-Policy "default-src 'self'"
File System Security
Deny Access to Sensitive Files
<FilesMatch "(^\.ht|\.git|\.env|\.bak|\.old|\.sql)">
Require all denied
</FilesMatch>
Restrict Document Root
<Directory />
Require all denied
Options None
AllowOverride None
</Directory>
<Directory /var/www/html>
Require all granted
Options -Indexes -FollowSymLinks
AllowOverride None
</Directory>
Start by denying access to everything, then explicitly allow the document root. Disable FollowSymLinks to prevent symlink attacks.
Disable .htaccess
If you do not need per-directory configuration overrides, disable .htaccess processing:
AllowOverride None
.htaccess files are processed on every request to the directory. Disabling them improves performance and prevents an attacker who can write files to the document root from modifying Apache's configuration.
Logging
Enable Comprehensive Logging
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %D %{SSL_PROTOCOL}x" combined_ssl
CustomLog /var/log/apache2/access.log combined_ssl
ErrorLog /var/log/apache2/error.log
LogLevel warn
Include TLS protocol version and request duration for security analysis. Forward logs to your SIEM for alerting and investigation.
How Safeguard.sh Helps
Safeguard.sh monitors the security of your Apache deployments by scanning server components for known vulnerabilities, tracking module versions and their security status, and generating SBOMs for your web server infrastructure. When a critical Apache CVE is published, Safeguard.sh identifies every instance in your environment that needs patching, helping you prioritize internet-facing servers that carry the highest risk.