Every server I’ve inherited from a previous admin has had at least one glaring security gap — an outdated Apache version, directory listing left on, or server signatures broadcasting exactly which software versions an attacker should target. In this post I want to walk through the hardening checklist I personally run through on every Apache server I manage.
Why Apache Security Hardening Matters
Apache powers a huge share of the web, which makes it a constant target for automated scanners and opportunistic attackers. Most successful attacks I’ve seen aren’t sophisticated zero-days — they’re exploiting known vulnerabilities in outdated versions, misconfigured permissions, or default settings nobody bothered to change.
Prerequisites
- Root or sudo access to your server
- Apache 2.4.x installed (if you’re on 2.2, upgrading should be your first priority)
- A backup of your current configuration before making changes
- A staging environment to test hardening changes before applying to production
Step 1: Keep Apache and Modules Updated
This sounds obvious, but it’s the number one thing I check first. Outdated Apache installations are the single biggest attack surface.
sudo apt update && sudo apt upgrade apache2 # Debian/Ubuntu
sudo yum update httpd # CentOS/RHEL
I set up unattended security updates on most servers I manage, specifically for security patches:
sudo apt install unattended-upgrades
sudo dpkg-reconfigure --priority=low unattended-upgrades
Step 2: Hide Apache Version and OS Information
By default, Apache happily tells the world exactly what version it’s running and what OS it’s on — information that makes an attacker’s job much easier. I always disable this:
ServerTokens Prod
ServerSignature Off
ServerTokens Prod reduces the Server header to just “Apache” with no version number. ServerSignature Off removes the version info from error pages and directory listings.
Step 3: Disable Directory Listing
If directory listing is left on and there’s no index file, Apache will happily show visitors a full listing of every file in that directory — including files you never meant to expose.
<Directory /var/www/>
Options -Indexes
</Directory>
I cover this in more depth in my dedicated post on preventing directory listing, but it belongs on every hardening checklist.
Step 4: Restrict Access to Sensitive Files
I always block access to hidden files, backup files, and version control directories that shouldn’t be publicly reachable:
<FilesMatch "^\.">
Require all denied
</FilesMatch>
<FilesMatch "(\.bak|\.config|\.sql|\.old|~)$">
Require all denied
</FilesMatch>
<DirectoryMatch "\.git">
Require all denied
</DirectoryMatch>
I’ve personally found exposed .git directories on client sites during audits — an easy way for an attacker to reconstruct an entire codebase.
Step 5: Disable Unnecessary Modules
Fewer active modules mean a smaller attack surface. I run through the loaded module list and disable anything not in active use:
apache2ctl -M
sudo a2dismod status
sudo a2dismod autoindex
sudo a2dismod cgi
sudo systemctl restart apache2
Step 6: Protect Against Clickjacking and MIME Sniffing
I add security headers to every site I manage, regardless of what the application itself does:
<IfModule mod_headers.c>
Header always set X-Frame-Options "SAMEORIGIN"
Header always set X-Content-Type-Options "nosniff"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Header always set Permissions-Policy "geolocation=(), microphone=(), camera=()"
</IfModule>
Step 7: Limit Request Size to Prevent DoS
Oversized requests can be used to exhaust server resources. I cap request body size based on the application’s actual needs:
LimitRequestBody 10485760
That example caps requests at 10MB — adjust based on whether your site handles file uploads.
Step 8: Enable mod_security (Web Application Firewall)
I dedicate an entire separate post to setting up mod_security in detail, but it deserves a mention here as one of the most effective defenses against SQL injection, XSS, and other common attack patterns. At minimum, install it and run the OWASP Core Rule Set.
Step 9: Set Correct File and Directory Permissions
Misconfigured permissions are a recurring issue I find during audits. My baseline:
sudo find /var/www -type d -exec chmod 755 {} \;
sudo find /var/www -type f -exec chmod 644 {} \;
sudo chown -R www-data:www-data /var/www
Never run Apache as root, and never leave writable directories more permissive than they need to be.
Step 10: Disable TRACE Method
The HTTP TRACE method can be exploited in cross-site tracing attacks. I disable it globally:
TraceEnable off
Step 11: Configure Timeout Values
Long default timeouts can be abused in slow-connection denial-of-service attacks (like Slowloris). I tighten these:
Timeout 60
RequestReadTimeout header=20-40,MinRate=500 body=20,MinRate=500
Real-World Use Case
During a security audit for a client’s Magento store, I found ServerSignature On, directory listing enabled on the uploads folder, and an exposed .git directory containing database credentials in a config file’s commit history. After applying the hardening steps above, a follow-up penetration test came back clean on all previously flagged issues.
Common Mistakes to Avoid
- Leaving default error pages that reveal stack traces or file paths.
- Running Apache processes as root instead of a dedicated low-privilege user.
- Forgetting to test configuration changes in staging before pushing to production, which can lock out legitimate traffic if rules are too aggressive.
- Assuming a firewall alone is sufficient protection without application-layer hardening.
Troubleshooting Tips
If you apply security headers and notice functionality breaking (like embedded iframes failing), check whether X-Frame-Options is too restrictive for your use case — you may need ALLOW-FROM exceptions or a more nuanced Content-Security-Policy instead. If mod_security starts blocking legitimate traffic, review your audit log at /var/log/apache2/modsec_audit.log and add targeted rule exceptions rather than disabling the whole module.
Security and Performance Best Practices
- Run regular vulnerability scans with tools like Nikto or OpenVAS.
- Subscribe to the Apache security announcements mailing list.
- Combine server hardening with a Web Application Firewall and rate limiting.
- Rotate and audit access logs regularly for suspicious patterns.
Frequently Asked Questions
Is mod_security necessary if I already have a firewall? Yes. A network firewall filters traffic at the IP/port level, while mod_security inspects HTTP request content for application-layer attacks like SQL injection and XSS — they solve different problems.
How often should I update Apache? As soon as security patches are released. I recommend enabling automatic security updates or at minimum checking weekly.
Does hiding the Apache version really improve security? It reduces the ease of automated reconnaissance, though it’s not a substitute for actually patching vulnerabilities — it’s one layer among many.
Can hardening break my website? Overly aggressive rules can, which is why I always test in staging first and roll out changes incrementally.
Summary and Key Takeaways
Apache security isn’t a single setting — it’s a checklist of layered defenses: keep software updated, hide unnecessary information, restrict access to sensitive files, disable unused modules, add security headers, and enforce sane permissions and timeouts. None of these steps is glamorous, but together they close the door on the vast majority of opportunistic attacks I see in the wild.
