Lab Write-up: Building and Hardening a Secure Apache Web Server

Lab Write-up: Complete Apache Web Server Hardening Guide for Linux

Proper Apache web server hardening is a foundational baseline for any security engineer or Linux system administrator. Default Apache installations broadcast sensitive OS details, leave directory listing enabled, and lack core HTTP security headers—making them easy targets for automated botnet scanners, footprinting tools, and OWASP Top 10 web application exploits.

In this hands-on cybersecurity lab write-up, I walk through configuring an Apache 2.4 web server on Ubuntu Linux to mitigate information disclosure, directory traversal, cross-site scripting (XSS), and clickjacking attacks.

âš¡ Quick Reference: Apache Hardening Checklist

Security Objective Target File Key Directive / Code
Disable Server Banners /etc/apache2/conf-enabled/security.conf

ServerTokens Prod

 

ServerSignature Off

Enforce Security Headers /etc/apache2/sites-available/000-default.conf

Header set X-Frame-Options "SAMEORIGIN"

 

Header set X-Content-Type-Options "nosniff"

Prevent Directory Browsing /var/www/html/.htaccess Options -Indexes
Block Sensitive Files /var/www/html/.htaccess <FilesMatch "^\."> Order allow,deny Deny from all </FilesMatch>

Why Apache Web Server Hardening Matters

When an unhardened web server processes incoming requests, it routinely exposes technical metadata to the public. Threat actors use banner-grabbing tools (like Nmap, Nikto, or curl) to identify exact Apache module versions and host OS details.

Once an attacker identifies an outdated module version, they can search databases like Exploit-DB for known CVEs. Hardening at the web server layer stops reconnaissance attempts early in the cyber attack lifecycle before an attacker can exploit application-level vulnerabilities.

Lab Architecture & Technical Environment

To simulate an enterprise edge deployment, I provisioned a dedicated Linux virtual machine with the following specifications:

  • Operating System: Ubuntu Server 22.04 LTS (Jammy Jellyfish)

  • Web Server Version: Apache/2.4.52 (Unix)

  • Network Interface: Private Subnet / Localhost Binding

  • Primary Objective: Harden the server baseline to pass automated compliance checks and secure HTTP response headers.

Step 1: Suppressing Server Banners & OS Information Disclosure

By default, Apache sends HTTP response headers containing explicit details about the operating system and installed modules (e.g., Server: Apache/2.4.52 (Ubuntu)).

To suppress these signatures and prevent attacker footprinting:

  1. Open the Apache security configuration file:

    Bash

    sudo nano /etc/apache2/conf-enabled/security.conf
    
  2. Locate and update the following directives:

    Apache

    # Suppress OS details and module versions in Server header
    ServerTokens Prod
    
    # Disable server version signature on footer of server-generated pages (e.g., 404 pages)
    ServerSignature Off
    
  3. Save the file and restart the Apache service:

    Bash

    sudo systemctl restart apache2
    
  • ServerTokens Prod instructs Apache to return only Server: Apache in the HTTP response header, withholding the sub-version and underlying Linux distro.

  • ServerSignature Off removes the version footer from system-generated documents like 404 Not Found or 403 Forbidden error pages.

Step 2: Injecting Core HTTP Security Headers

HTTP security headers instruct the victim’s web browser how to safely handle site content, neutralizing common client-side attack vectors like Cross-Site Scripting (XSS), MIME-sniffing, and Clickjacking.

  1. Enable the Apache headers module (mod_headers):

    Bash

    sudo a2enmod headers
    
  2. Edit your virtual host configuration file:

    Bash

    sudo nano /etc/apache2/sites-available/000-default.conf
    
  3. Add the following directives inside the <VirtualHost *:80> block:

    Apache

    <IfModule mod_headers.c>
        # Mitigate Clickjacking by restricting framing
        Header set X-Frame-Options "SAMEORIGIN"
    
        # Prevent MIME-type sniffing exploits
        Header set X-Content-Type-Options "nosniff"
    
        # Enable legacy browser XSS filtering
        Header set X-XSS-Protection "1; mode=block"
    </IfModule>
    
  4. Test the Apache configuration syntax and restart the server:

    Bash

    sudo apache2ctl configtest
    sudo systemctl restart apache2
    

Step 3: Hardening Directories & Restricting File Exposure via .htaccess

Allowing directory browsing (Indexes) allows attackers to enumerate unlinked files, backup archives (.bak), configuration scripts, and uploaded assets. Additionally, hidden environment files (such as .env or .git) must be explicitly blocked.

  1. Ensure .htaccess overrides are permitted in /etc/apache2/apache2.conf:

    Apache

    <Directory /var/www/html>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>
    
  2. Create or open the root .htaccess file:

    Bash

    sudo nano /var/www/html/.htaccess
    
  3. Insert the following access control directives:

    Apache

    # Disable directory listing globally
    Options -Indexes
    
    # Block access to dotfiles (.env, .git, .htaccess)
    <FilesMatch "^\.">
        Order allow,deny
        Deny from all
    </FilesMatch>
    

Setting Options -Indexes forces Apache to return a 403 Forbidden error whenever a user attempts to browse a directory path that lacks an index.html or index.php file.

Step 4: Verifying Apache Security Configurations with Curl

To confirm that our defensive configurations were successfully applied, I performed local HTTP header audits using curl.

Pre-Hardening Header Check (Vulnerable Baseline):

Plaintext

HTTP/1.1 200 OK
Date: Sat, 08 Aug 2026 18:00:00 GMT
Server: Apache/2.4.52 (Ubuntu) Mod_Python/3.3.1
Content-Type: text/html; charset=UTF-8

Post-Hardening Header Audit (Secured Baseline):

Run the verification command:

Bash

curl -I http://localhost

Verified Output:

Plaintext

HTTP/1.1 200 OK
Date: Sat, 08 Aug 2026 18:05:00 GMT
Server: Apache
X-Frame-Options: SAMEORIGIN
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Content-Type: text/html; charset=UTF-8

Key Takeaways

  1. Server Metadata Masked: The Server header now returns only Apache, omitting OS and patch levels.

  2. Security Headers Live: X-Frame-Options, X-Content-Type-Options, and X-XSS-Protection are active across all routes.

  3. Information Leakage Prevented: Attempting to access http://localhost/.env or browse /images/ returns an immediate 403 Forbidden response.

Frequently Asked Questions (FAQ)

What is the difference between ServerTokens Minimal and ServerTokens Prod?

ServerTokens Minimal returns the Apache version number (e.g., Server: Apache/2.4.52), whereas ServerTokens Prod strips all version numbers completely, returning only Server: Apache.

Does hiding the Apache version number make a server completely secure?

No. Hiding version banners is an example of defense-in-depth, not security through obscurity. It reduces noise from automated scanners, but robust patch management, web application firewalls (WAFs), and proper access controls are still required.

#CyberSecurity #HomeLab #SysAdmin #Hardening #BettyCoder

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Scroll to Top