Apache Hardening: The Guide to Amplify Your Security (with everything that can go wrong if you don't) Every default Apache configuration you ignore is an open door. This guide shows you exactly what each one means in practice — and how to close them, one by one.
Apache Hardening: The Guide to Amplify Your Security (with everything that can go wrong if you don't) Every default Apache configuration you ignore is an open door. This guide shows you exactly what each one means in practice — and how to close them, one by one. Introduction Apache HTTP Server is one of the most widely used web servers on the planet for over 25 years. And precisely because of that, it's also one of the most studied targets by attackers. Its default configuration is designed to work anywhere , not to be secure anywhere . This difference is what separates a healthy server from one that becomes a headline. In this guide, we'll go through each hardening item explaining three things: What the default configuration does (or fails to do) What an attacker can do with it — with real scenarios How to fix it , with configuration ready to copy By the end, you'll have Apache ready for production and will understand exactly why each line is there. ServerTokens and ServerSignature: you're delivering a treasure map What happens by default When Apache responds to any request, it includes a Server header that by default contains something like: And on error pages (404, 500, 403), it adds a footer: It may seem harmless. It's not. What this causes in practice Imagine you're running Apache 2.4.52 on Ubuntu. An attacker scanning the internet with Shodan, Censys, or a simple Python script discovers your server. In seconds: Queries the CVE database filtering by "Apache 2.4.52" — and finds a list of known vulnerabilities for that exact version. Knows it's Ubuntu , so knows which packages are installed, what the default file path is (/var/www/html), where logs are, who runs the service (www-data). Filters ready-made exploits on Exploit-DB or Metasploit that match your version. If there's an unpatched exploit, within minutes they're already testing. The cost of an attacker discovering all this went from "hours of reconnaissance" to "one HTTP request". You saved them work. Worse: automated scanners like Mirai and its derivatives scan the internet 24/7 looking for exactly vulnerable specific versions. It's not personal — it's industrial. The fix In /etc/apache2/conf-enabled/security.conf (Debian/Ubuntu) or /etc/httpd/conf/httpd.conf (RHEL/CentOS/Rocky): After that, the Server header becomes simply Apache. The attacker still knows it's Apache (there's no way to hide it 100%), but lost the version and operating system. They can't filter specific exploits without extra work anymore. Important: this is "security through obscurity" and doesn't replace keeping the server updated. But drastically reduces the number of automated attacks that can find you as a viable target. expose php: PHP shouting its version to the world What happens by default Every response generated by a PHP page brings a header like: What this causes Same problem as ServerTokens, with an aggravating factor: PHP vulnerabilities tend to be much more critical than Apache vulnerabilities, because PHP executes code. Some of the most well-known CVEs from recent years (CVE-2019-11043 in PHP-FPM, for example) allowed remote code execution with a single well-formed request. If the attacker knows you're running PHP 8.1.2, they consult that exact version's CVEs and try. If your version is vulnerable and hasn't been patched yet, it's game over. There's another less obvious side effect: bug bounty tools and aggressive scanners prioritize targets with old versions . Exposing your version is like hanging a sign that says "shoot here first". The fix In php.ini (use php --ini to discover the exact path): Restart Apache (or PHP-FPM, depending on your setup). The header disappears completely. Attention: if you use PHP-FPM, there are two different php.ini files — one for CLI and one for FPM. Adjust the FPM one (/etc/php/8.x/fpm/php.ini). TraceEnable: the HTTP method we forgot to kill What happens by default The TRACE HTTP method was created in the 90s for debugging purposes — when you send a TRACE, the server responds with the entire request it received, intact. By default, Apache comes with TraceEnable On. What this causes There's a known attack called Cross-Site Tracing (XST) . The idea: using JavaScript on a compromised page, an attacker forces the victim's browser to do a TRACE on the target server. The response includes all headers — including cookies marked as HttpOnly , which normally JavaScript can't read. Result: the attacker captures session cookies that should be inaccessible and hijacks the victim's session. It works to this day on misconfigured servers. Plus, automated vulnerability scanners mark TRACE enabled as medium severity vulnerability, which affects compliance scores (PCI-DSS, for example, requires TRACE disabled). The fix Done. No side effects, no impact on real applications. I don't know a single legitimate site that needs TRACE enabled in production. FileETag: leaking filesystem information What happens by default The ETag header is used for caching:…