Apache2 Comprehensive Guide - Installation, Configuration, and Security Hardening
Apache HTTP Server (Apache2) is one of the world's most popular web servers. Developed and maintained by the Apache Software Foundation, it's an open-source, cross-platform web server that powers a significant percentage of websites on the internet.
Apache2 Web Server Guide
Table of Contents
- Introduction
- Installation
- Basic Configuration
- Virtual Hosts
- Security Configurations
- Performance Tuning
- Complex Issues and Solutions
- Advanced Functionality
- Troubleshooting
- References
Installation
On Debian/Ubuntu Systems with Security Hardening
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# Update package lists
sudo apt update
# Install Apache2 with minimal modules for security
sudo apt install apache2
# Install security modules
sudo apt install libapache2-mod-security2 libapache2-mod-qos
# Enable only essential modules and disable unnecessary ones
sudo a2enmod ssl
sudo a2enmod headers
sudo a2enmod security2
sudo a2enmod rewrite
sudo a2enmod qos
# Disable dangerous or unnecessary modules
sudo a2dismod status
sudo a2dismod autoindex
sudo a2dismod userdir
sudo a2dismod info
sudo a2dismod cgi
sudo a2dismod env
# Create a directory with secure permissions for SSL certificates
sudo mkdir -p /etc/apache2/ssl
sudo chmod 700 /etc/apache2/ssl
# Modify default file permissions
sudo chmod 750 /var/www/html
sudo chmod 640 /var/www/html/index.html
sudo chown -R root:www-data /var/www/html/
# Set secure umask for Apache
echo 'umask 027' | sudo tee -a /etc/apache2/envvars
# Start Apache service
sudo systemctl start apache2
# Enable Apache to start at boot
sudo systemctl enable apache2
# Check status to verify it's running
sudo systemctl status apache2
# Perform post-installation security audit
sudo apt install lynis
sudo lynis audit system --no-colors
On Red Hat/CentOS/Fedora Systems
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Update package lists
sudo dnf update
# Install Apache (httpd package)
sudo dnf install httpd
# Start Apache service
sudo systemctl start httpd
# Enable Apache to start at boot
sudo systemctl enable httpd
# Check status to verify it's running
sudo systemctl status httpd
On Windows
For Windows, the simplest approach is to use a package like XAMPP, WampServer, or MAMP which bundle Apache with PHP and MySQL.
Alternatively, you can download and install Apache directly from the Apache Lounge website (unofficial Windows builds): https://www.apachelounge.com/download/
Basic Configuration
Apache’s configuration files are typically found in:
/etc/apache2/
(Debian/Ubuntu)/etc/httpd/
(Red Hat/CentOS/Fedora)/usr/local/etc/httpd/
(macOS with Homebrew)
Main Configuration Files
- apache2.conf / httpd.conf: The main configuration file
- ports.conf: Defines which ports Apache listens on
- sites-available/: Directory containing site configurations
- sites-enabled/: Directory containing symbolic links to enabled sites
- mods-available/: Directory containing available modules
- mods-enabled/: Directory containing enabled modules
Essential Configuration Commands
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# Restart Apache (Debian/Ubuntu)
sudo systemctl restart apache2
# Reload configuration without restarting (Debian/Ubuntu)
sudo systemctl reload apache2
# Test configuration for syntax errors (Debian/Ubuntu)
sudo apache2ctl configtest
# Restart Apache (Red Hat/CentOS/Fedora)
sudo systemctl restart httpd
# Reload configuration without restarting (Red Hat/CentOS/Fedora)
sudo systemctl reload httpd
# Test configuration for syntax errors (Red Hat/CentOS/Fedora)
sudo apachectl configtest
Basic apache2.conf/httpd.conf Settings
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# Specify the location of content files
DocumentRoot "/var/www/html"
# Set global server options
ServerName example.com
ServerAdmin [email protected]
# Control Apache process settings
Timeout 300
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 5
# Set default directory permissions
<Directory "/var/www/html">
# Options for this directory
Options Indexes FollowSymLinks
# Access control configuration
AllowOverride All
Require all granted
</Directory>
Virtual Hosts
Virtual hosts allow you to serve multiple websites from a single Apache instance. This is one of Apache’s most powerful features.
Creating a Basic Virtual Host
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# /etc/apache2/sites-available/example.com.conf
<VirtualHost *:80>
# The domain name this virtual host should respond to
ServerName example.com
ServerAlias www.example.com
# Server admin email address for error messages
ServerAdmin [email protected]
# Root directory for this website's files
DocumentRoot /var/www/example.com
# Log file locations (crucial for debugging and monitoring)
ErrorLog ${APACHE_LOG_DIR}/example.com_error.log
CustomLog ${APACHE_LOG_DIR}/example.com_access.log combined
# Directory-specific settings
<Directory /var/www/example.com>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
Enabling a Virtual Host (Debian/Ubuntu)
1
2
3
4
5
# Create symlink in sites-enabled directory
sudo a2ensite example.com.conf
# Reload Apache to apply changes
sudo systemctl reload apache2
Name-based vs. IP-based Virtual Hosting
Apache supports two types of virtual hosting:
- Name-based Virtual Hosting: Multiple domains share the same IP address (most common)
- IP-based Virtual Hosting: Each domain has its own IP address
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# Name-based virtual hosting example
<VirtualHost *:80>
ServerName site1.example.com
DocumentRoot /var/www/site1
</VirtualHost>
<VirtualHost *:80>
ServerName site2.example.com
DocumentRoot /var/www/site2
</VirtualHost>
# IP-based virtual hosting example
<VirtualHost 192.168.1.10:80>
ServerName site1.example.com
DocumentRoot /var/www/site1
</VirtualHost>
<VirtualHost 192.168.1.11:80>
ServerName site2.example.com
DocumentRoot /var/www/site2
</VirtualHost>
Security Configurations
Implementing ModSecurity (Web Application Firewall)
ModSecurity is a powerful Web Application Firewall (WAF) for Apache that provides protection against various attacks including SQL injection, cross-site scripting, and other OWASP Top 10 vulnerabilities.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# Install ModSecurity (Debian/Ubuntu)
sudo apt install libapache2-mod-security2
# Enable the module
sudo a2enmod security2
# Copy the recommended configuration
sudo cp /etc/modsecurity/modsecurity.conf-recommended /etc/modsecurity/modsecurity.conf
# Enable ModSecurity in blocking mode (not just detection)
sudo sed -i 's/SecRuleEngine DetectionOnly/SecRuleEngine On/' /etc/modsecurity/modsecurity.conf
# Install the OWASP Core Rule Set (CRS) for comprehensive protection
sudo apt install modsecurity-crs
sudo ln -s /usr/share/modsecurity-crs/rules/ /etc/modsecurity/
# Configure to use the CRS
echo 'Include /etc/modsecurity/rules/*.conf' | sudo tee -a /etc/apache2/mods-enabled/security2.conf
# Set paranoia level to 3 (high protection, low false positives)
echo 'SecRuleEngine On' | sudo tee -a /etc/modsecurity/crs-setup.conf
echo 'SecAction "id:900000,phase:1,pass,t:none,nolog,setvar:tx.paranoia_level=3"' | sudo tee -a /etc/modsecurity/crs-setup.conf
# Restart Apache
sudo systemctl restart apache2
SSL/TLS Configuration with Let’s Encrypt
Always use TLS to encrypt all web traffic. Let’s Encrypt provides free, automated certificates.
1
2
3
4
5
6
7
8
9
10
11
# Install Certbot (Debian/Ubuntu)
sudo apt install certbot python3-certbot-apache
# Obtain and install certificate with secure parameters
sudo certbot --apache -d example.com -d www.example.com --rsa-key-size 4096
# Configure auto-renewal with a post-renewal hook to reload Apache
echo "0 0,12 * * * root python3 -c 'import random; import time; time.sleep(random.random() * 3600)' && certbot renew --quiet --post-hook 'systemctl reload apache2'" | sudo tee -a /etc/crontab > /dev/null
# Test automatic renewal
sudo certbot renew --dry-run
Hardened Apache SSL Configuration Example
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
<VirtualHost *:443>
ServerName example.com
DocumentRoot /var/www/example.com
# SSL Certificate Configuration
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
# Maximum security TLS settings - only TLS 1.3 and 1.2
SSLProtocol -all +TLSv1.3 +TLSv1.2
# Use secure ciphers only - Mozilla's "Modern" cipher list
SSLCipherSuite TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305
SSLHonorCipherOrder on
# Enable OCSP Stapling (faster and more private certificate validation)
#SSLUseStapling on
#SSLStaplingCache "shmcb:logs/ssl_stapling(32768)"
#SSLStaplingResponseMaxAge 86400
# HSTS (HTTP Strict Transport Security)
# Tell browsers to only connect via HTTPS for 2 years
Header always set Strict-Transport-Security "max-age=63072000; includeSubdomains; preload"
# Prevent clickjacking - only allow your site to be framed by itself
Header always set X-Frame-Options SAMEORIGIN
# Prevent MIME-type sniffing (browser guessing file types)
Header always set X-Content-Type-Options nosniff
# Enable Cross-Site Scripting filter in browsers
Header always set X-XSS-Protection "1; mode=block"
# Control information sent in referrer header
Header always set Referrer-Policy strict-origin-when-cross-origin
# Content Security Policy - restrict what resources can be loaded
# This is a basic example - customize based on your site's requirements
Header always set Content-Security-Policy "default-src 'self'; script-src 'self'; img-src 'self'; style-src 'self'; font-src 'self'; frame-ancestors 'self'; form-action 'self'"
# Enable Feature Policy/Permissions Policy
Header always set Permissions-Policy "geolocation=(), microphone=(), camera=(), payment=()"
# Disable caching for sensitive resources
<FilesMatch "\.(html|htm|php)$">
Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate"
Header set Pragma "no-cache"
Header set Expires "0"
</FilesMatch>
# Limit SSL session cache to enhance performance while maintaining security
SSLSessionCache shmcb:/var/lib/apache2/ssl_scache(512000)
SSLSessionCacheTimeout 300
</VirtualHost>
Comprehensive Directory and Server Hardening
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# Global server hardening - apply these in apache2.conf
ServerTokens Prod # Don't reveal Apache version in headers
ServerSignature Off # Don't show Apache info in error pages
TraceEnable Off # Disable TRACE method to prevent XST attacks
FileETag None # Disable ETag headers (privacy concern)
Timeout 30 # Reduce timeout to prevent DoS attacks
MaxKeepAliveRequests 100 # Limit connections per client
KeepAliveTimeout 2 # Shorter keepalive timeout
# Enable only required modules
# Run this to disable unused modules:
# a2dismod autoindex status info cgi alias env userdir negotiation
# Secure directory configurations
<Directory />
# Default deny for the entire filesystem
Options None
AllowOverride None
Require all denied
</Directory>
<Directory /var/www/example.com>
# Provide minimum required permissions
Options -Indexes -Includes -ExecCGI -FollowSymLinks
AllowOverride None
Require all granted
# Set secure default permissions
<FilesMatch "^\.">
Require all denied
</FilesMatch>
# Only allow specific file types
<FilesMatch "(?i)\.(gif|jpe?g|png|css|js|html?|xml|txt)$">
Require all granted
</FilesMatch>
# Block access to sensitive files
<FilesMatch "(?i)\.(bak|config|sql|tar|zip|gz|tgz|ini|log|sh|inc|sw[op]|ya?ml)$">
Require all denied
</FilesMatch>
# Disable execution of scripts in uploaded content
<Directory /var/www/example.com/uploads>
# Prohibit script execution
Options -ExecCGI
SetHandler none
# Disable PHP entirely in this directory
php_flag engine off
RemoveHandler .php .phtml .php3 .php4 .php5 .php7
RemoveType .php .phtml .php3 .php4 .php5 .php7
# Treat all files as plain text
AddType text/plain .php .phtml .php3 .php4 .php5 .php7 .html .htm
# Set very restrictive permissions
<FilesMatch ".+">
SetHandler default-handler
</FilesMatch>
</Directory>
# Protect configuration files
<Files ~ "^\.ht">
Require all denied
# Ensure proper MIME type handling
Header unset Content-Type
Header always set Content-Type "text/plain"
</Files>
# Implement rate limiting for sensitive areas
<Location "/login">
ErrorDocument 429 "Too many requests, please try again later."
# Limit to 15 requests per minute
LimitRequestRate 15
</Location>
</Directory>
# Mitigate clickjacking with CSP frame-ancestors (stronger than X-Frame-Options)
Header always append Content-Security-Policy "frame-ancestors 'self';"
# Set appropriate file permissions on disk
# Run these commands:
# find /var/www/example.com -type d -exec chmod 750 {} \;
# find /var/www/example.com -type f -exec chmod 640 {} \;
# chown -R root:www-data /var/www/example.com
Performance Tuning
Enable and Configure Caching
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# Load caching modules
LoadModule cache_module modules/mod_cache.so
LoadModule cache_disk_module modules/mod_cache_disk.so
# Configure disk cache
<IfModule mod_cache_disk.c>
CacheRoot /var/cache/apache2/mod_cache_disk
CacheEnable disk /
CacheDirLevels 2
CacheDirLength 1
# Cache files up to 100MB for up to 1 hour
CacheMaxFileSize 104857600
CacheMinFileSize 1
CacheDefaultExpire 3600
CacheMaxExpire 86400
CacheQuickHandler on
</IfModule>
# Set expiration headers for static content
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/jpg "access plus 1 year"
ExpiresByType image/jpeg "access plus 1 year"
ExpiresByType image/gif "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
ExpiresDefault "access plus 2 days"
</IfModule>
Configure MPM (Multi-Processing Module)
Apache can use different MPMs to handle connections. The most common are:
- prefork: Uses multiple child processes with one thread each (legacy)
- worker: Uses multiple child processes with multiple threads each
- event: Improved version of worker, recommended for high-traffic sites
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# Use the Event MPM (best for modern high-traffic sites)
<IfModule mpm_event_module>
# Number of child server processes created at startup
StartServers 3
# Desired minimum number of idle child server processes
MinSpareThreads 25
# Desired maximum number of idle child server processes
MaxSpareThreads 75
# Maximum number of connections that will be processed simultaneously
MaxRequestWorkers 400
# Maximum number of requests a child process serves before terminating
MaxConnectionsPerChild 0
</IfModule>
Optimize for High Traffic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# Increase timeouts for busy servers
Timeout 60
# Configure keep-alive settings
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 5
# Enable compression for text-based content
<IfModule mod_deflate.c>
# Compress HTML, CSS, JavaScript, Text, XML and fonts
AddOutputFilterByType DEFLATE application/javascript
AddOutputFilterByType DEFLATE application/rss+xml
AddOutputFilterByType DEFLATE application/vnd.ms-fontobject
AddOutputFilterByType DEFLATE application/x-font
AddOutputFilterByType DEFLATE application/x-font-opentype
AddOutputFilterByType DEFLATE application/x-font-otf
AddOutputFilterByType DEFLATE application/x-font-truetype
AddOutputFilterByType DEFLATE application/x-font-ttf
AddOutputFilterByType DEFLATE application/x-javascript
AddOutputFilterByType DEFLATE application/xhtml+xml
AddOutputFilterByType DEFLATE application/xml
AddOutputFilterByType DEFLATE font/opentype
AddOutputFilterByType DEFLATE font/otf
AddOutputFilterByType DEFLATE font/ttf
AddOutputFilterByType DEFLATE image/svg+xml
AddOutputFilterByType DEFLATE image/x-icon
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/javascript
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/xml
# Remove browser bugs
BrowserMatch ^Mozilla/4 gzip-only-text/html
BrowserMatch ^Mozilla/4\.0[678] no-gzip
BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
</IfModule>
Complex Issues and Solutions
Problem: Handling High Traffic Spikes
Issue: Server becomes unresponsive during traffic spikes.
Solution:
- Implement a proper MPM configuration
- Use rate limiting to prevent abuse
1
2
3
4
5
6
7
8
9
10
11
# Install and enable mod_ratelimit
sudo a2enmod ratelimit
# Configure rate limiting in your virtual host
<IfModule mod_ratelimit.c>
# Limit bandwidth to 400KB/s for specific content
<Location /downloads>
SetOutputFilter RATE_LIMIT
SetEnv rate-limit 400
</Location>
</IfModule>
Problem: Handling SSL Termination with High Traffic
Issue: SSL processing is CPU-intensive and can slow down your server.
Solution: Offload SSL processing using Apache’s mod_proxy with a reverse proxy setup.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# Enable required modules
sudo a2enmod proxy
sudo a2enmod proxy_http
sudo a2enmod proxy_balancer
sudo a2enmod lbmethod_byrequests
# Configure load balancing and proxy
<VirtualHost *:443>
ServerName example.com
# SSL Configuration
SSLEngine On
SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
# Define proxy backend servers
<Proxy "balancer://mycluster">
BalancerMember "http://backend1.example.com:8080"
BalancerMember "http://backend2.example.com:8080"
ProxySet lbmethod=byrequests
</Proxy>
# Proxy all requests to the backend
ProxyPreserveHost On
ProxyPass / balancer://mycluster/
ProxyPassReverse / balancer://mycluster/
</VirtualHost>
Problem: Handling Slow Application Responses
Issue: Long-running applications cause Apache to tie up worker processes.
Solution: Use asynchronous processing with mod_proxy and timeout controls.
1
2
3
4
5
6
7
8
9
# Set stricter timeouts for proxied connections
ProxyTimeout 60
TimeOut 60
# Configure specific timeouts for slow endpoints
<Location "/api/slow-endpoint">
ProxyPass http://backend.example.com/api/slow-endpoint timeout=180
ProxyPassReverse http://backend.example.com/api/slow-endpoint
</Location>
Advanced Functionality
Security-First Dynamic Content Negotiation
Content negotiation allows serving different versions of resources based on client preferences. Here’s a secure implementation:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# Enable content negotiation with security focus
<IfModule mod_negotiation.c>
# Define languages and map to file extensions
AddLanguage en .en
AddLanguage fr .fr
AddLanguage de .de
# Define which quality factor to assign to each language
LanguagePriority en fr de
# SECURITY: Avoid using MultiViews in security-sensitive contexts
# Instead use explicit type maps when possible
# Options +MultiViews
# Use explicit type maps for negotiation (more secure than MultiViews)
AddHandler type-map .var
# SECURITY: Prevent path traversal by implementing strict directory restrictions
<DirectoryMatch ".*">
# Disable potentially dangerous options
Options -Indexes -Includes -FollowSymLinks
# Only allow specific file types to be negotiated
<FilesMatch "(?i)\.var$">
Require all granted
</FilesMatch>
</DirectoryMatch>
# SECURITY: Implement content-type enforcement
# Prevent browsers from MIME-sniffing away from declared content-type
Header always set X-Content-Type-Options "nosniff"
</IfModule>
Secure Implementation of Rewrite Rules with mod_rewrite
The mod_rewrite module is powerful for URL manipulation and redirection, but requires careful security implementation:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# Enable rewrite module
LoadModule rewrite_module modules/mod_rewrite.so
<VirtualHost *:80>
ServerName example.com
DocumentRoot /var/www/example.com
# Enable rewrite engine for this virtual host
RewriteEngine On
RewriteOptions Inherit
# SECURITY: Force HTTPS with proper headers - redirect all HTTP traffic to HTTPS
# Add HSTS header in the HTTPS virtual host, not here
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301,NE]
# SECURITY: Block access to sensitive files and directories
# Block access to any hidden files and directories
RewriteRule "(^|/)\." - [F]
# Block access to backup and source files
RewriteRule ".(bak|config|dist|fla|inc|ini|log|orig|psd|sh|sql|swp|txt|tpl|xml|yml|md|lock|json)$" - [F,NC]
# SECURITY: Prevent access to wp-config.php and other sensitive files
RewriteRule ^wp-config.php$ - [F,L,NC]
RewriteRule ^xmlrpc.php$ - [F,L,NC]
# SECURITY: Prevent host header attacks
# Only allow your domains to be used in Host: header
RewriteCond %{HTTP_HOST} !^(example\.com|www\.example\.com)$ [NC]
RewriteRule .* - [F]
# SECURITY: Block bots/scanners/malicious traffic with extensive patterns
RewriteCond %{HTTP_USER_AGENT} (360Spider|acapbot|acoonbot|ahrefs|alexibot|asterias|attackbot|baiduspider|blackwidow|bot|bots|collector|cmd|curl|c99|dts|email|extract|exploit|ezooms|fhscan|floodgate|flybots|havij|harvest|httrack|indy|infotekies|libwww|majestic|masses|morfeus|nikto|nmap|nutch|petalbot|planetwork|pocketparser|pycurl|python|scan|scraper|security|seekerspider|semalt|urllib|webalta|webbandit|webcopier|webcopy|websleuth|webleacher|winhttp|xaldon) [NC]
RewriteRule .* - [F,L]
# Create clean URLs for a blog with input validation
# Changes /blog.php?id=123 to /blog/123
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# SECURITY: Strictly validate input parameters to prevent injection
RewriteRule ^blog/([0-9]+)$ /blog.php?id=$1 [L,QSA]
# SECURITY: Block SQL injection attempts
RewriteCond %{QUERY_STRING} [^a-z0-9._-]*(union|select|insert|drop|update|md5|benchmark|or|and|if)[^a-z0-9._-]* [NC]
RewriteRule .* - [F,L]
# SECURITY: Block PHP-injection attempts
RewriteCond %{QUERY_STRING} (base64_encode|eval\() [NC,OR]
RewriteCond %{QUERY_STRING} (\<|%3C).*script.*(\>|%3E) [NC]
RewriteRule .* - [F,L]
# SECURITY: Set X-Content-Type-Options header
Header always set X-Content-Type-Options nosniff
# Handle missing pages - redirect old site structure to new
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} ^/old-section/(.*)$
# SECURITY: Validate destination to prevent open redirect
RewriteRule ^old-section/([a-zA-Z0-9_-]+)$ /new-section/$1 [L,R=301]
# SECURITY: Implement rate limiting for important endpoints
# This requires mod_ratelimit and mod_env
<If "%{REQUEST_URI} =~ m#^/(login|admin|api)#">
SetEnv rate-limit 5
</If>
</VirtualHost>
WebSocket Proxying
WebSockets allow for real-time communication, and Apache can proxy these connections.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Enable required modules
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so
<VirtualHost *:80>
ServerName example.com
# Proxy WebSocket connections
RewriteEngine On
RewriteCond %{HTTP:Upgrade} =websocket [NC]
RewriteRule /(.*) ws://localhost:8080/$1 [P,L]
# Proxy regular HTTP traffic
ProxyPass /socket http://localhost:8080/socket
ProxyPassReverse /socket http://localhost:8080/socket
</VirtualHost>
Custom Logging and Analytics
Create custom log formats to capture specific information.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# Define a custom log format with additional fields
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %D %{X-Forwarded-For}i" combined_with_timing
# Use the custom format in a virtual host
<VirtualHost *:80>
ServerName example.com
CustomLog ${APACHE_LOG_DIR}/example.com_access.log combined_with_timing
# Log specific events to a separate file
# Log all 404 errors separately
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\"" notfound
CustomLog ${APACHE_LOG_DIR}/notfound.log notfound env=not_found
# Set an environment variable for 404 errors
<LocationMatch "/">
ErrorDocument 404 /404.php
SetEnvIf status 404 not_found=1
</LocationMatch>
</VirtualHost>
Troubleshooting and Security Auditing
Common Issues and Security Solutions
1. Apache Won’t Start After Security Configurations
Symptoms: Service fails to start after implementing security changes.
Secure Debugging Steps:
1
2
3
4
5
6
7
8
9
10
11
# Check for syntax errors in configuration (without revealing full paths in logs)
sudo apache2ctl configtest
# Look at Apache error logs in a secure manner
sudo grep -v "password\|key\|secret\|token" /var/log/apache2/error.log | tail -100
# Check for port conflicts securely
sudo ss -tulwn | grep -E ':80|:443'
# Check process status without exposing command line arguments
sudo systemctl status apache2 --no-pager
Security-Focused Solutions:
- Fix syntax errors while maintaining strict security configurations
- Resolve port conflicts and validate listening only on required interfaces
- Verify file permissions (SSL certificates should be 600, config files 640)
- Validate all custom security rules before deploying to production
2. 403 Forbidden Errors After Hardening
Symptoms: Browser shows “403 Forbidden” after implementing security measures.
Secure Debugging Steps:
1
2
3
4
5
6
7
8
9
# Check directory permissions (minimally required)
ls -la /var/www/html/ | grep -v "config\|password\|key"
# Check Apache configuration for the directory without exposing sensitive paths
grep -r --include="*.conf" "/var/www/html" /etc/apache2/ | grep -v "password\|key\|secret"
# Verify SELinux/AppArmor contexts if applicable
sudo sestatus
sudo aa-status
Security-Focused Solutions:
1
2
3
4
5
6
7
8
9
10
11
12
13
# Allow access to the directory with minimal permissions
<Directory /var/www/html/restricted>
# Disable all dangerous options
Options None
# Only allow specific overrides if needed
AllowOverride None
# Grant access with minimal exposure
Require all granted
# Enable logging of all access
LogLevel info
# Implement content security policy
Header always set Content-Security-Policy "default-src 'self';"
</Directory>
3. Security Scanning and Hardening Validation
Symptoms: Need to verify your security configuration is effective.
Secure Testing Steps:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# Install security scanning tools
sudo apt install nikto lynis
# Scan your own server (only in testing/staging environments)
nikto -h localhost
# Perform system security audit
sudo lynis audit system
# Check for vulnerable Apache modules and configurations
sudo apt install wapiti
wapiti -u http://localhost/ -v 2
# Test SSL/TLS security configuration
sudo apt install sslscan
sslscan --no-failed example.com:443
# Verify HTTP security headers
curl -I https://example.com/ | grep -E 'Strict-Transport-Security|Content-Security-Policy|X-Frame-Options'
Security Improvement Solutions:
- Document all findings and remediate vulnerabilities
- Implement regular security scanning in your maintenance routine
- Create a security incident response plan
- Implement file integrity monitoring ```bash
Install AIDE (Advanced Intrusion Detection Environment)
sudo apt install aide
Configure AIDE to monitor Apache configuration files
echo “/etc/apache2/ Rule=VarFile” | sudo tee -a /etc/aide/aide.conf
Initialize the AIDE database
sudo aideinit
Run regular checks
sudo aide –check
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#### 4. SSL/TLS Security Issues
**Symptoms**: Low scores on SSL/TLS testing sites or security warnings.
**Security Validation Steps**:
```bash
# Test SSL configuration thoroughly
sudo openssl s_client -connect example.com:443 -servername example.com -tls1_3
# Check for weak ciphers (none should be allowed)
sudo openssl ciphers -v 'LOW:EXP:!DH:!ADH:!kDH' | wc -l
# Validate certificate security
sudo openssl x509 -in /etc/letsencrypt/live/example.com/cert.pem -noout -text | grep "Signature Algorithm\|Public Key"
# Check certificate permissions (should be restricted)
sudo find /etc/letsencrypt/live -type f -name "*.pem" -exec ls -la {} \;
Advanced Security Solutions:
- Implement certificate transparency monitoring
- Configure OCSP Must-Staple for enhanced revocation checking
- Use DNS CAA records to restrict which CAs can issue certificates
- Implement encrypted SNI if your infrastructure supports it
- Set up automated security header testing with Mozilla Observatory CLI
1
2
# Fix permissions if certificates are overly accessible
sudo find /etc/letsencrypt/live -type f -name "*.pem" -exec chmod 600 {} \;
5. Security Incident Response
Symptoms: Unexpected behavior, unusual log entries, or compromise indicators.
Secure Incident Response Steps: ```bash
Check for unauthorized processes
sudo ps aux | grep -v whoami
| grep apache2
Look for unusual network connections
sudo netstat -tunap | grep httpd
Search for recently modified files
sudo find /var/www -type f -mtime -1 -ls
Check for unauthorized users/groups
sudo grep apache /etc/passwd /etc/group