Apache as a Secure Reverse Proxy

Apache as a Secure Reverse Proxy

Configure Apache for secure reverse proxy operations:

# Enable required modules
sudo a2enmod proxy proxy_http proxy_balancer lbmethod_byrequests headers rewrite ssl

# /etc/apache2/sites-available/secure-reverse-proxy.conf
<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
    
    # Security headers
    Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
    Header always set X-Frame-Options "SAMEORIGIN"
    Header always set X-Content-Type-Options "nosniff"
    Header always set X-XSS-Protection "1; mode=block"
    Header always set Referrer-Policy "strict-origin-when-cross-origin"
    
    # Hide backend information
    Header unset X-Powered-By
    Header unset Server
    
    # Request filtering
    <Location />
        # Method restrictions
        <LimitExcept GET POST PUT DELETE HEAD OPTIONS>
            Require all denied
        </LimitExcept>
        
        # IP-based access control
        <RequireAll>
            Require all granted
            # Block specific IPs
            Require not ip 10.0.0.0/8
            Require not ip 192.168.0.0/16
        </RequireAll>
    </Location>
    
    # Proxy configuration
    ProxyRequests Off
    ProxyPreserveHost On
    ProxyTimeout 10
    
    # Backend server configuration with load balancing
    <Proxy "balancer://backend_cluster">
        BalancerMember http://backend1.internal:8080 route=backend1 connectiontimeout=5 timeout=30
        BalancerMember http://backend2.internal:8080 route=backend2 connectiontimeout=5 timeout=30
        BalancerMember http://backend3.internal:8080 route=backend3 status=+H
        
        ProxySet stickysession=JSESSIONID|jsessionid
        ProxySet lbmethod=byrequests
        ProxySet failontimeout=On
    </Proxy>
    
    # Security filters for proxy
    <Proxy *>
        Require all granted
        
        # Add security headers to proxied requests
        RequestHeader set X-Forwarded-Proto "https"
        RequestHeader set X-Real-IP "%{REMOTE_ADDR}s"
        RequestHeader set X-Forwarded-For "%{X-Forwarded-For}e, %{REMOTE_ADDR}s"
    </Proxy>
    
    # Main proxy rules
    ProxyPass / balancer://backend_cluster/
    ProxyPassReverse / balancer://backend_cluster/
    
    # WebSocket support
    RewriteEngine On
    RewriteCond %{HTTP:Upgrade} websocket [NC]
    RewriteCond %{HTTP:Connection} upgrade [NC]
    RewriteRule ^/?(.*) "ws://backend_cluster/$1" [P,L]
    
    # Security rules for specific paths
    <LocationMatch "^/admin">
        Require ip 10.0.1.0/24
        
        # Additional authentication
        AuthType Basic
        AuthName "Admin Access"
        AuthUserFile /etc/apache2/.htpasswd_admin
        Require valid-user
    </LocationMatch>
    
    # Rate limiting for login
    <Location "/login">
        SetEnvIf Request_URI "^/login" login_request
        
        # Use mod_evasive for rate limiting
        DOSHashTableSize 3097
        DOSPageCount 5
        DOSSiteCount 50
        DOSPageInterval 1
        DOSSiteInterval 1
        DOSBlockingPeriod 300
    </Location>
    
    # Mod_security rules
    <IfModule mod_security2.c>
        SecRuleEngine On
        SecRequestBodyAccess On
        SecResponseBodyAccess On
        SecRequestBodyLimit 10485760
        SecRequestBodyNoFilesLimit 131072
        
        # Custom rules for reverse proxy
        SecRule REQUEST_HEADERS:Content-Type "!^(application/x-www-form-urlencoded|multipart/form-data|application/json|text/xml|application/xml)" \
            "id:1001,phase:1,deny,status:415,msg:'Unsupported Media Type'"
        
        SecRule REQUEST_URI "@contains .." \
            "id:1002,phase:1,deny,status:400,msg:'Path Traversal Attack'"
    </IfModule>
    
    # Logging
    ErrorLog ${APACHE_LOG_DIR}/reverse-proxy-error.log
    CustomLog ${APACHE_LOG_DIR}/reverse-proxy-access.log combined
    
    # Additional security directives
    ServerSignature Off
    ServerTokens Prod
    TraceEnable Off
</VirtualHost>

# HTTP to HTTPS redirect
<VirtualHost *:80>
    ServerName example.com
    Redirect permanent / https://example.com/
</VirtualHost>