Apache
04 / 07

Performance & Security

Apache Performance & Security

A default Apache install is not tuned for production. Enabling caching, tuning KeepAlive, hiding server info, and adding security headers are the essential steps before going live.

KeepAlive & Connection Tuning

# In apache2.conf or vhost config

# KeepAlive — reuse TCP connections for multiple requests
KeepAlive On
MaxKeepAliveRequests 100        # Max requests per connection (0 = unlimited)
KeepAliveTimeout 5              # Seconds to wait for next request (lower = more efficient)

# Timeout settings
Timeout 60                      # Request timeout in seconds
RequestReadTimeout header=20-40,MinRate=500 body=20,MinRate=500

# Limit request sizes (protect against large body attacks)
LimitRequestBody 10485760       # 10 MB max request body

# mod_cache with mod_cache_disk
sudo a2enmod cache cache_disk
<IfModule mod_cache_disk.c>
    CacheEnable disk /
    CacheRoot /var/cache/apache2/mod_cache_disk
    CacheDirLevels 2
    CacheDirLength 1
    CacheDefaultExpire 3600     # 1 hour default
    CacheMaxExpire 86400        # 24 hour max
    CacheIgnoreHeaders Set-Cookie
</IfModule>

Security Hardening

# Hide server version and OS info
ServerTokens Prod              # Show only "Apache" not version
ServerSignature Off            # Remove version from error pages

# Disable directory listing globally
<Directory />
    Options -Indexes
    AllowOverride None
    Require all denied         # Deny everything by default, open up explicitly
</Directory>

<Directory /var/www/html>
    Options -Indexes +FollowSymLinks
    AllowOverride All
    Require all granted
</Directory>

# Block access to hidden files (.git, .env, .htpasswd)
<FilesMatch "^.">
    Require all denied
</FilesMatch>

# Block access to sensitive extensions
<FilesMatch ".(sql|bak|config|log|sh)$">
    Require all denied
</FilesMatch>

# Basic auth with .htpasswd
sudo apt install apache2-utils
htpasswd -c /etc/apache2/.htpasswd admin    # Create file and add user
htpasswd /etc/apache2/.htpasswd editor      # Add another user

<Directory /var/www/html/private>
    AuthType Basic
    AuthName "Restricted Area"
    AuthUserFile /etc/apache2/.htpasswd
    Require valid-user
</Directory>

# mod_ratelimit — limit bandwidth per connection
sudo a2enmod ratelimit
<Location /downloads>
    SetOutputFilter RATE_LIMIT
    SetEnv rate-limit 400        # 400 KB/s per connection
</Location>

Security Headers & mod_security

# Add security headers (in vhost or .htaccess)
sudo a2enmod headers

<IfModule mod_headers.c>
    # Prevent clickjacking
    Header always set X-Frame-Options "SAMEORIGIN"
    # Prevent MIME type sniffing
    Header always set X-Content-Type-Options "nosniff"
    # XSS protection (legacy browsers)
    Header always set X-XSS-Protection "1; mode=block"
    # HSTS — force HTTPS for 2 years including subdomains
    Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
    # Content Security Policy
    Header always set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'"
    # Referrer policy
    Header always set Referrer-Policy "strict-origin-when-cross-origin"
</IfModule>

# Install ModSecurity WAF
sudo apt install libapache2-mod-security2
sudo a2enmod security2
sudo cp /etc/modsecurity/modsecurity.conf-recommended /etc/modsecurity/modsecurity.conf
# Change DetectionOnly to On to enforce rules
sudo sed -i "s/SecRuleEngine DetectionOnly/SecRuleEngine On/" /etc/modsecurity/modsecurity.conf

# Test config and reload
sudo apachectl configtest && sudo systemctl reload apache2

# Check for misconfigurations causing 403/500 errors
sudo tail -50 /var/log/apache2/error.log
sudo journalctl -u apache2 --since "5 minutes ago"

Keep your own version of these notes — editable, searchable, and organised by your stack.

Start free