๐ก๏ธ AlmaLinux Web Application Firewall Complete Setup Guide
Ready to transform your AlmaLinux server into an impenetrable fortress? ๐ A Web Application Firewall (WAF) is your first line of defense against sophisticated cyber attacks, protecting your applications from SQL injection, XSS, DDoS attacks, and countless other threats! This comprehensive guide will help you build enterprise-grade security that keeps attackers at bay! โจ
Think of a WAF as an elite security guard for your web applications - it inspects every request, blocks malicious traffic, and ensures only legitimate users reach your servers! ๐ก๏ธ
๐ค Why Deploy a Web Application Firewall?
A WAF provides critical protection that traditional firewalls simply canโt match! ๐
Essential Benefits:
- ๐ก๏ธ Application-Layer Protection - Stops attacks targeting your web apps
- ๐ซ SQL Injection Prevention - Blocks database manipulation attempts
- ๐ XSS Attack Mitigation - Prevents cross-site scripting attacks
- ๐ DDoS Protection - Rate limiting and traffic filtering
- ๐ฏ Zero-Day Protection - Virtual patching for unknown vulnerabilities
- ๐ Detailed Logging - Complete visibility into attack patterns
- โก Performance Optimization - Caching and compression features
- ๐ง Custom Rule Creation - Tailored protection for your applications
- ๐ Compliance Support - Meet PCI DSS and other security standards
- ๐ Multi-Application Support - Protect multiple sites simultaneously
๐ฏ What You Need Before Starting
Letโs ensure youโre ready for this advanced security implementation! โ
System Requirements:
- โ AlmaLinux 8 or 9 (fresh installation recommended)
- โ Minimum 4GB RAM (8GB+ for high-traffic sites)
- โ 20GB+ free disk space for logs and rules
- โ Web server (Apache or Nginx) already installed
- โ SSL certificates configured (recommended)
- โ Root/sudo access for system configuration
- โ Basic understanding of web server configuration
Prerequisites:
- โ Working web server with test applications
- โ Domain name and DNS configuration
- โ Basic knowledge of HTTP/HTTPS protocols
- โ Understanding of common web vulnerabilities
What Weโll Install:
- โ ModSecurity 3.x - Advanced WAF engine
- โ OWASP Core Rule Set (CRS) - Comprehensive attack signatures
- โ Fail2Ban integration for persistent attackers
- โ Custom rule development environment
- โ Comprehensive monitoring and alerting
- โ Performance optimization tools
๐ Step 1: System Preparation and Security Hardening
Letโs start by preparing our AlmaLinux system for WAF deployment!
# Update system packages
sudo dnf update -y
# Install essential development tools
sudo dnf groupinstall "Development Tools" -y
sudo dnf install -y \
git \
curl \
wget \
unzip \
cmake \
autoconf \
automake \
libtool \
pkgconfig \
pcre-devel \
libxml2-devel \
curl-devel \
httpd-devel \
apr-devel \
apr-util-devel \
yajl-devel \
ssdeep-devel \
lua-devel \
GeoIP-devel \
doxygen
Enable Additional Repositories:
# Enable EPEL and PowerTools repositories
sudo dnf install -y epel-release
sudo dnf config-manager --set-enabled powertools
# Install additional security tools
sudo dnf install -y \
fail2ban \
logrotate \
rsyslog \
clamav \
clamav-update \
htop \
iotop \
tcpdump \
wireshark-cli
Create WAF Directory Structure:
# Create organized directory structure for WAF
sudo mkdir -p /etc/modsecurity/{rules,custom-rules,conf.d}
sudo mkdir -p /var/log/modsecurity
sudo mkdir -p /opt/waf/{scripts,backups,tools}
# Set proper permissions
sudo chmod 755 /etc/modsecurity
sudo chmod 755 /var/log/modsecurity
sudo chmod 755 /opt/waf
๐ง Step 2: ModSecurity 3.x Installation and Configuration
ModSecurity is the industry-standard WAF engine. Letโs install and configure it properly!
# Clone and build ModSecurity from source for latest features
cd /opt/waf/tools
sudo git clone --depth 1 -b v3/master --single-branch https://github.com/SpiderLabs/ModSecurity.git
cd ModSecurity
# Build ModSecurity
sudo git submodule init
sudo git submodule update
sudo ./build.sh
sudo ./configure --enable-pcre-study --enable-lua --enable-geoip
sudo make -j$(nproc)
sudo make install
Install ModSecurity Connector for Apache:
# Install Apache connector
cd /opt/waf/tools
sudo git clone --depth 1 https://github.com/SpiderLabs/ModSecurity-apache.git
cd ModSecurity-apache
sudo ./autogen.sh
sudo ./configure --with-libmodsecurity=/usr/local/modsecurity/
sudo make -j$(nproc)
sudo make install
# Enable ModSecurity module in Apache
echo "LoadModule security3_module modules/mod_security3.so" | sudo tee /etc/httpd/conf.modules.d/00-modsecurity.conf
Basic ModSecurity Configuration:
# Create main ModSecurity configuration
sudo tee /etc/modsecurity/modsecurity.conf << 'EOF'
# ModSecurity Core Configuration
# Basic Engine Settings
SecRuleEngine On
SecRequestBodyAccess On
SecResponseBodyAccess On
SecResponseBodyMimeType text/plain text/html text/xml application/json
SecRequestBodyLimit 13107200
SecRequestBodyNoFilesLimit 131072
SecRequestBodyInMemoryLimit 131072
SecRequestBodyLimitAction Reject
# Response Body Settings
SecResponseBodyLimit 524288
SecResponseBodyLimitAction ProcessPartial
# File Upload Settings
SecTmpDir /tmp/
SecDataDir /tmp/
SecUploadDir /tmp/
SecUploadFileLimit 10
SecUploadKeepFiles RelevantOnly
# Debug and Logging
SecDebugLog /var/log/modsecurity/debug.log
SecDebugLogLevel 0
SecAuditEngine RelevantOnly
SecAuditLogRelevantStatus "^(?:5|4(?!04))"
SecAuditLogParts ABDEFHIJZ
SecAuditLogType Serial
SecAuditLog /var/log/modsecurity/audit.log
# Argument Separator
SecArgumentSeparator &
# Cookie Format
SecCookieFormat 0
# Rule Engine Settings
SecMarker INITIALIZATION
SecAction "id:900001,phase:1,nolog,pass,t:none,setvar:tx.paranoia_level=1"
SecAction "id:900002,phase:1,nolog,pass,t:none,setvar:tx.executing_paranoia_level=1"
SecAction "id:900003,phase:1,nolog,pass,t:none,setvar:tx.anomaly_score_threshold=5"
SecAction "id:900004,phase:1,nolog,pass,t:none,setvar:tx.inbound_anomaly_score_threshold=5"
SecAction "id:900005,phase:1,nolog,pass,t:none,setvar:tx.outbound_anomaly_score_threshold=4"
# Application-specific settings
SecAction "id:900010,phase:1,nolog,pass,t:none,setvar:tx.crs_setup_version=400"
SecAction "id:900011,phase:1,nolog,pass,t:none,setvar:tx.allowed_methods=GET HEAD POST OPTIONS"
SecAction "id:900012,phase:1,nolog,pass,t:none,setvar:tx.allowed_request_content_type=|application/x-www-form-urlencoded| |multipart/form-data| |multipart/related| |text/xml| |application/xml| |application/soap+xml| |application/json| |application/cloudevents+json| |application/cloudevents-batch+json|"
SecAction "id:900013,phase:1,nolog,pass,t:none,setvar:tx.allowed_request_content_type_charset=|utf-8| |iso-8859-1| |iso-8859-15| |windows-1252|"
SecAction "id:900014,phase:1,nolog,pass,t:none,setvar:tx.allowed_http_versions=HTTP/1.0 HTTP/1.1 HTTP/2 HTTP/2.0"
SecAction "id:900015,phase:1,nolog,pass,t:none,setvar:tx.restricted_extensions=.asa/ .asax/ .ascx/ .axd/ .backup/ .bak/ .bat/ .cdx/ .cer/ .cfg/ .cmd/ .com/ .config/ .conf/ .cs/ .csproj/ .csr/ .dat/ .db/ .dbf/ .dll/ .dos/ .htr/ .htw/ .ida/ .idc/ .idq/ .inc/ .ini/ .key/ .licx/ .lnk/ .log/ .mdb/ .old/ .pass/ .pdb/ .pol/ .printer/ .pwd/ .rdb/ .resources/ .resx/ .sql/ .swp/ .sys/ .vb/ .vbs/ .vbproj/ .vsdisco/ .webinfo/ .xsd/ .xsx/"
SecAction "id:900016,phase:1,nolog,pass,t:none,setvar:tx.restricted_headers=/proxy/ /lock-token/ /content-range/ /if/ /x-forwarded-for/"
# IP Reputation and GeoIP
SecGeoLookupDb /usr/share/GeoIP/GeoIP.dat
EOF
๐ Step 3: OWASP Core Rule Set (CRS) Installation
The OWASP Core Rule Set provides comprehensive protection against common attacks!
# Download and install OWASP CRS
cd /opt/waf/tools
sudo git clone https://github.com/coreruleset/coreruleset.git
cd coreruleset
# Copy rules to ModSecurity directory
sudo cp -r rules/* /etc/modsecurity/rules/
sudo cp crs-setup.conf.example /etc/modsecurity/crs-setup.conf
# Create custom CRS configuration
sudo tee /etc/modsecurity/crs-setup.conf << 'EOF'
# OWASP Core Rule Set Configuration
# Paranoia Level (1-4, higher = more strict)
SecAction \
"id:900000,\
phase:1,\
nolog,\
pass,\
t:none,\
setvar:tx.paranoia_level=2"
# Executing Paranoia Level
SecAction \
"id:900001,\
phase:1,\
nolog,\
pass,\
t:none,\
setvar:tx.executing_paranoia_level=2"
# Anomaly Scoring Thresholds
SecAction \
"id:900110,\
phase:1,\
nolog,\
pass,\
t:none,\
setvar:tx.inbound_anomaly_score_threshold=5,\
setvar:tx.outbound_anomaly_score_threshold=4"
# Application-specific settings
SecAction \
"id:900200,\
phase:1,\
nolog,\
pass,\
t:none,\
setvar:tx.allowed_methods=GET HEAD POST OPTIONS PUT PATCH DELETE"
# Blocking Settings
SecAction \
"id:900300,\
phase:1,\
nolog,\
pass,\
t:none,\
setvar:tx.do_reput_block=1,\
setvar:tx.reput_block_duration=300"
# Custom Application Settings
SecAction \
"id:900400,\
phase:1,\
nolog,\
pass,\
t:none,\
setvar:tx.max_num_args=255,\
setvar:tx.arg_name_length=100,\
setvar:tx.arg_length=400,\
setvar:tx.total_arg_length=64000,\
setvar:tx.max_file_size=1048576,\
setvar:tx.combined_file_sizes=1048576"
# SQL Injection Detection
SecAction \
"id:900500,\
phase:1,\
nolog,\
pass,\
t:none,\
setvar:tx.sql_error_match=1"
# XSS Detection
SecAction \
"id:900600,\
phase:1,\
nolog,\
pass,\
t:none,\
setvar:tx.xss_score_threshold=60"
# Session Fixation Protection
SecAction \
"id:900700,\
phase:1,\
nolog,\
pass,\
t:none,\
setvar:tx.session_fixation_score_threshold=60"
# HTTP Violation Detection
SecAction \
"id:900800,\
phase:1,\
nolog,\
pass,\
t:none,\
setvar:tx.http_violation_score_threshold=5"
# Trojan and Backdoor Detection
SecAction \
"id:900900,\
phase:1,\
nolog,\
pass,\
t:none,\
setvar:tx.trojan_score_threshold=5"
EOF
Create Rule Inclusion File:
# Create main rules inclusion file
sudo tee /etc/modsecurity/main.conf << 'EOF'
# ModSecurity Main Configuration
# Include base configuration
Include /etc/modsecurity/modsecurity.conf
# Include CRS setup
Include /etc/modsecurity/crs-setup.conf
# Include OWASP CRS rules in correct order
Include /etc/modsecurity/rules/REQUEST-901-INITIALIZATION.conf
Include /etc/modsecurity/rules/REQUEST-903-IP-REPUTATION.conf
Include /etc/modsecurity/rules/REQUEST-905-COMMON-EXCEPTIONS.conf
Include /etc/modsecurity/rules/REQUEST-910-IP-REPUTATION.conf
Include /etc/modsecurity/rules/REQUEST-911-METHOD-ENFORCEMENT.conf
Include /etc/modsecurity/rules/REQUEST-912-DOS-PROTECTION.conf
Include /etc/modsecurity/rules/REQUEST-913-SCANNER-DETECTION.conf
Include /etc/modsecurity/rules/REQUEST-920-PROTOCOL-ENFORCEMENT.conf
Include /etc/modsecurity/rules/REQUEST-921-PROTOCOL-ATTACK.conf
Include /etc/modsecurity/rules/REQUEST-930-APPLICATION-ATTACK-LFI.conf
Include /etc/modsecurity/rules/REQUEST-931-APPLICATION-ATTACK-RFI.conf
Include /etc/modsecurity/rules/REQUEST-932-APPLICATION-ATTACK-RCE.conf
Include /etc/modsecurity/rules/REQUEST-933-APPLICATION-ATTACK-PHP.conf
Include /etc/modsecurity/rules/REQUEST-934-APPLICATION-ATTACK-NODEJS.conf
Include /etc/modsecurity/rules/REQUEST-941-APPLICATION-ATTACK-XSS.conf
Include /etc/modsecurity/rules/REQUEST-942-APPLICATION-ATTACK-SQLI.conf
Include /etc/modsecurity/rules/REQUEST-943-APPLICATION-ATTACK-SESSION-FIXATION.conf
Include /etc/modsecurity/rules/REQUEST-944-APPLICATION-ATTACK-JAVA.conf
Include /etc/modsecurity/rules/REQUEST-949-BLOCKING-EVALUATION.conf
Include /etc/modsecurity/rules/RESPONSE-950-DATA-LEAKAGES.conf
Include /etc/modsecurity/rules/RESPONSE-951-DATA-LEAKAGES-SQL.conf
Include /etc/modsecurity/rules/RESPONSE-952-DATA-LEAKAGES-JAVA.conf
Include /etc/modsecurity/rules/RESPONSE-953-DATA-LEAKAGES-PHP.conf
Include /etc/modsecurity/rules/RESPONSE-954-DATA-LEAKAGES-IIS.conf
Include /etc/modsecurity/rules/RESPONSE-959-BLOCKING-EVALUATION.conf
Include /etc/modsecurity/rules/RESPONSE-980-CORRELATION.conf
# Include custom rules
Include /etc/modsecurity/custom-rules/*.conf
EOF
โ Step 4: Apache Integration and Virtual Host Configuration
Letโs integrate ModSecurity with Apache and configure protection for your websites!
# Create Apache ModSecurity configuration
sudo tee /etc/httpd/conf.d/security.conf << 'EOF'
# ModSecurity Configuration for Apache
# Load ModSecurity configuration
<IfModule mod_security3.c>
# Main configuration file
modsecurity on
modsecurity_rules_file /etc/modsecurity/main.conf
# Request timeout settings
modsecurity_transaction_id "%{UNIQUE_ID}"
# Collection settings
SecCollectionTimeout 600
SecTmpSaveUploadedFiles On
</IfModule>
# Security headers for all sites
Header always set X-Content-Type-Options nosniff
Header always set X-Frame-Options DENY
Header always set X-XSS-Protection "1; mode=block"
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Header always set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' https:; connect-src 'self'; frame-ancestors 'none';"
# Hide server information
ServerTokens Prod
ServerSignature Off
# Disable trace method
TraceEnable Off
EOF
# Enable required Apache modules
sudo dnf install -y mod_ssl mod_headers
echo "LoadModule headers_module modules/mod_headers.so" | sudo tee -a /etc/httpd/conf.modules.d/00-base.conf
Create Protected Virtual Host Example:
# Create example protected virtual host
sudo tee /etc/httpd/conf.d/protected-site.conf << 'EOF'
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
DocumentRoot /var/www/html/example.com
# Redirect HTTP to HTTPS
Redirect permanent / https://example.com/
</VirtualHost>
<VirtualHost *:443>
ServerName example.com
ServerAlias www.example.com
DocumentRoot /var/www/html/example.com
# SSL Configuration
SSLEngine on
SSLCertificateFile /etc/ssl/certs/example.com.crt
SSLCertificateKeyFile /etc/ssl/private/example.com.key
# ModSecurity for this site
<IfModule mod_security3.c>
SecRuleEngine On
SecAuditEngine On
SecAuditLog /var/log/modsecurity/example.com_audit.log
# Custom rules for this application
SecRule REQUEST_FILENAME "@detectSQLi" \
"id:1001,\
phase:2,\
block,\
msg:'SQL Injection Attack Detected',\
logdata:'Matched Data: %{MATCHED_VAR} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\
tag:'application-multi',\
tag:'language-multi',\
tag:'platform-multi',\
tag:'attack-sqli',\
severity:'CRITICAL'"
# Rate limiting for login endpoints
SecAction \
"id:1002,\
phase:1,\
nolog,\
pass,\
initcol:ip=%{REMOTE_ADDR},\
setvar:ip.login_attempts=+1,\
expirevar:ip.login_attempts=300"
SecRule IP:LOGIN_ATTEMPTS "@gt 5" \
"id:1003,\
phase:1,\
deny,\
status:429,\
msg:'Rate limit exceeded for login attempts',\
tag:'rate-limiting'"
</IfModule>
# Logging
ErrorLog /var/log/httpd/example.com_error.log
CustomLog /var/log/httpd/example.com_access.log combined
# Document security
<Directory "/var/www/html/example.com">
Options -Indexes -ExecCGI
AllowOverride None
Require all granted
# Prevent access to sensitive files
<Files "*.inc">
Require all denied
</Files>
<Files "*.conf">
Require all denied
</Files>
<Files "*.sql">
Require all denied
</Files>
<Files ".ht*">
Require all denied
</Files>
</Directory>
</VirtualHost>
EOF
# Create document root
sudo mkdir -p /var/www/html/example.com
sudo chown apache:apache /var/www/html/example.com
๐ก๏ธ Step 5: Custom Security Rules Development
Letโs create powerful custom rules for advanced protection!
# Create custom anti-automation rules
sudo tee /etc/modsecurity/custom-rules/anti-automation.conf << 'EOF'
# Custom Anti-Automation Rules
# Detect rapid requests from single IP
SecAction \
"id:2001,\
phase:1,\
nolog,\
pass,\
initcol:ip=%{REMOTE_ADDR},\
setvar:ip.requests_per_minute=+1,\
expirevar:ip.requests_per_minute=60"
SecRule IP:REQUESTS_PER_MINUTE "@gt 60" \
"id:2002,\
phase:1,\
deny,\
status:429,\
msg:'Too many requests per minute',\
logdata:'IP: %{REMOTE_ADDR}, Requests: %{IP.REQUESTS_PER_MINUTE}',\
tag:'rate-limiting',\
severity:'WARNING'"
# Detect bot-like behavior patterns
SecRule REQUEST_HEADERS:User-Agent "@detectXSS" \
"id:2003,\
phase:1,\
deny,\
msg:'Malicious User-Agent detected',\
logdata:'User-Agent: %{REQUEST_HEADERS.User-Agent}',\
tag:'bot-detection',\
severity:'WARNING'"
# Block requests without User-Agent
SecRule &REQUEST_HEADERS:User-Agent "@eq 0" \
"id:2004,\
phase:1,\
deny,\
msg:'Request without User-Agent header',\
tag:'bot-detection',\
severity:'NOTICE'"
# Detect scrapers by request patterns
SecRule REQUEST_URI "@pmFromFile /etc/modsecurity/custom-rules/scraper-patterns.txt" \
"id:2005,\
phase:1,\
deny,\
msg:'Scraper pattern detected',\
logdata:'URI: %{REQUEST_URI}',\
tag:'scraper-detection',\
severity:'WARNING'"
EOF
# Create scraper patterns file
sudo tee /etc/modsecurity/custom-rules/scraper-patterns.txt << 'EOF'
# Common scraper patterns
/admin/config.php
/wp-admin/admin-ajax.php
/xmlrpc.php
/.env
/config.inc.php
/configuration.php
/config.php
/settings.php
/database.php
/db_config.php
EOF
Advanced Application-Specific Rules:
# Create application-specific protection rules
sudo tee /etc/modsecurity/custom-rules/application-protection.conf << 'EOF'
# Advanced Application Protection Rules
# Protect against path traversal
SecRule ARGS "@detectPathTraversal" \
"id:3001,\
phase:2,\
deny,\
msg:'Path Traversal Attack Detected',\
logdata:'Matched Data: %{MATCHED_VAR} found within %{MATCHED_VAR_NAME}',\
tag:'attack-path-traversal',\
severity:'CRITICAL'"
# Advanced SQL injection detection
SecRule ARGS "@detectSQLi" \
"id:3002,\
phase:2,\
deny,\
msg:'Advanced SQL Injection Attack',\
logdata:'Matched Data: %{MATCHED_VAR} found within %{MATCHED_VAR_NAME}',\
tag:'attack-sqli',\
severity:'CRITICAL'"
# XSS protection with custom patterns
SecRule ARGS "@rx (?i)<script[^>]*>.*?</script>" \
"id:3003,\
phase:2,\
deny,\
msg:'XSS Attack - Script Tag Detected',\
logdata:'Matched Data: %{MATCHED_VAR}',\
tag:'attack-xss',\
severity:'HIGH'"
# Command injection protection
SecRule ARGS "@rx (?i)(;|\||`|&|\$\(|\${|<\()" \
"id:3004,\
phase:2,\
deny,\
msg:'Command Injection Attempt',\
logdata:'Matched Data: %{MATCHED_VAR} in %{MATCHED_VAR_NAME}',\
tag:'attack-command-injection',\
severity:'CRITICAL'"
# File upload restrictions
SecRule FILES_TMPNAMES "@detectFileUpload" \
"id:3005,\
phase:2,\
deny,\
msg:'Malicious File Upload Detected',\
logdata:'File: %{FILES_TMPNAMES}',\
tag:'attack-file-upload',\
severity:'HIGH'"
# API endpoint protection
SecRule REQUEST_URI "@beginsWith /api/" \
"id:3006,\
phase:1,\
pass,\
nolog,\
setvar:tx.api_request=1"
SecRule TX:API_REQUEST "@eq 1" \
"id:3007,\
phase:2,\
chain,\
deny,\
msg:'API Abuse Detected'"
SecRule REQUEST_METHOD "!@within GET POST PUT DELETE PATCH" \
"setvar:tx.anomaly_score=+5"
# Protect sensitive admin areas
SecRule REQUEST_URI "@beginsWith /admin" \
"id:3008,\
phase:1,\
pass,\
log,\
msg:'Admin area access attempt',\
logdata:'IP: %{REMOTE_ADDR}, URI: %{REQUEST_URI}',\
tag:'admin-access'"
# Geographic restrictions (example: block specific countries)
SecRule GEO:COUNTRY_CODE "@within CN RU KP" \
"id:3009,\
phase:1,\
deny,\
msg:'Request from restricted country',\
logdata:'Country: %{GEO.COUNTRY_CODE}, IP: %{REMOTE_ADDR}',\
tag:'geo-blocking',\
severity:'NOTICE'"
EOF
๐ Step 6: DDoS Protection and Rate Limiting
Implement sophisticated DDoS protection and rate limiting mechanisms!
# Create advanced DDoS protection rules
sudo tee /etc/modsecurity/custom-rules/ddos-protection.conf << 'EOF'
# Advanced DDoS Protection and Rate Limiting
# Global request rate limiting
SecAction \
"id:4001,\
phase:1,\
nolog,\
pass,\
initcol:global=global_counter,\
setvar:global.requests_per_second=+1,\
expirevar:global.requests_per_second=1"
SecRule GLOBAL:REQUESTS_PER_SECOND "@gt 1000" \
"id:4002,\
phase:1,\
deny,\
status:503,\
msg:'Global rate limit exceeded',\
logdata:'Global RPS: %{GLOBAL.REQUESTS_PER_SECOND}',\
tag:'ddos-protection',\
severity:'ERROR'"
# Per-IP rate limiting with progressive penalties
SecAction \
"id:4003,\
phase:1,\
nolog,\
pass,\
initcol:ip=%{REMOTE_ADDR},\
setvar:ip.requests_per_second=+1,\
expirevar:ip.requests_per_second=1"
# First threshold: 30 requests per second
SecRule IP:REQUESTS_PER_SECOND "@gt 30" \
"id:4004,\
phase:1,\
pass,\
log,\
msg:'High request rate from IP',\
logdata:'IP: %{REMOTE_ADDR}, RPS: %{IP.REQUESTS_PER_SECOND}',\
setvar:ip.high_rate_count=+1,\
tag:'rate-monitoring'"
# Second threshold: 50 requests per second - start blocking
SecRule IP:REQUESTS_PER_SECOND "@gt 50" \
"id:4005,\
phase:1,\
deny,\
status:429,\
msg:'Rate limit exceeded',\
logdata:'IP: %{REMOTE_ADDR}, RPS: %{IP.REQUESTS_PER_SECOND}',\
setvar:ip.blocked_until=%{TIME_EPOCH},\
expirevar:ip.blocked_until=300,\
tag:'rate-limiting',\
severity:'WARNING'"
# Concurrent connection limiting
SecAction \
"id:4006,\
phase:1,\
nolog,\
pass,\
initcol:ip=%{REMOTE_ADDR},\
setvar:ip.concurrent_connections=+1,\
expirevar:ip.concurrent_connections=30"
SecRule IP:CONCURRENT_CONNECTIONS "@gt 20" \
"id:4007,\
phase:1,\
deny,\
status:429,\
msg:'Too many concurrent connections',\
logdata:'IP: %{REMOTE_ADDR}, Connections: %{IP.CONCURRENT_CONNECTIONS}',\
tag:'connection-limiting',\
severity:'WARNING'"
# Slow loris protection
SecRule REQUEST_HEADERS:Content-Length "@gt 1000000" \
"id:4008,\
phase:1,\
deny,\
msg:'Request body too large',\
logdata:'Content-Length: %{REQUEST_HEADERS.Content-Length}',\
tag:'slow-loris-protection',\
severity:'WARNING'"
# Detect HTTP flood attacks
SecAction \
"id:4009,\
phase:1,\
nolog,\
pass,\
initcol:ip=%{REMOTE_ADDR},\
setvar:ip.requests_per_minute=+1,\
expirevar:ip.requests_per_minute=60"
SecRule IP:REQUESTS_PER_MINUTE "@gt 300" \
"id:4010,\
phase:1,\
deny,\
status:429,\
msg:'HTTP flood detected',\
logdata:'IP: %{REMOTE_ADDR}, RPM: %{IP.REQUESTS_PER_MINUTE}',\
setvar:ip.flood_block=1,\
expirevar:ip.flood_block=1800,\
tag:'http-flood',\
severity:'ERROR'"
# Bandwidth limiting simulation
SecRule REQUEST_METHOD "@streq POST" \
"id:4011,\
phase:1,\
pass,\
nolog,\
initcol:ip=%{REMOTE_ADDR},\
setvar:ip.post_size=+%{REQUEST_HEADERS.Content-Length},\
expirevar:ip.post_size=60"
SecRule IP:POST_SIZE "@gt 10485760" \
"id:4012,\
phase:1,\
deny,\
msg:'Bandwidth limit exceeded for POST requests',\
logdata:'IP: %{REMOTE_ADDR}, Total POST size: %{IP.POST_SIZE}',\
tag:'bandwidth-limiting',\
severity:'WARNING'"
EOF
๐ฎ Quick Examples - WAF Testing and Validation
Letโs create some practical examples for testing and validating your WAF! ๐
Example 1: WAF Attack Testing Suite
# Create comprehensive WAF testing script
cat > /opt/waf/scripts/test-waf.sh << 'EOF'
#!/bin/bash
# WAF Attack Testing Suite
TARGET_URL="https://example.com"
LOG_FILE="/tmp/waf-test-results.log"
echo "๐ก๏ธ WAF Testing Suite" | tee $LOG_FILE
echo "====================" | tee -a $LOG_FILE
echo "Target: $TARGET_URL" | tee -a $LOG_FILE
echo "Started: $(date)" | tee -a $LOG_FILE
echo "" | tee -a $LOG_FILE
test_sql_injection() {
echo "๐๏ธ Testing SQL Injection Protection..." | tee -a $LOG_FILE
# Basic SQL injection attempts
payloads=(
"' OR '1'='1"
"'; DROP TABLE users; --"
"1' UNION SELECT * FROM users --"
"' OR 1=1 #"
"admin'--"
"' OR 'a'='a"
)
for payload in "${payloads[@]}"; do
echo " Testing payload: $payload" | tee -a $LOG_FILE
response=$(curl -s -o /dev/null -w "%{http_code}" \
--data "username=$payload&password=test" \
"$TARGET_URL/login")
if [ "$response" -eq 403 ] || [ "$response" -eq 406 ]; then
echo " โ
BLOCKED (HTTP $response)" | tee -a $LOG_FILE
else
echo " โ NOT BLOCKED (HTTP $response)" | tee -a $LOG_FILE
fi
done
echo "" | tee -a $LOG_FILE
}
test_xss_protection() {
echo "๐ Testing XSS Protection..." | tee -a $LOG_FILE
# XSS payloads
payloads=(
"<script>alert('XSS')</script>"
"<img src=x onerror=alert('XSS')>"
"javascript:alert('XSS')"
"<svg onload=alert('XSS')>"
"'>alert('XSS')</script>"
)
for payload in "${payloads[@]}"; do
echo " Testing payload: $payload" | tee -a $LOG_FILE
response=$(curl -s -o /dev/null -w "%{http_code}" \
--data "comment=$payload" \
"$TARGET_URL/comment")
if [ "$response" -eq 403 ] || [ "$response" -eq 406 ]; then
echo " โ
BLOCKED (HTTP $response)" | tee -a $LOG_FILE
else
echo " โ NOT BLOCKED (HTTP $response)" | tee -a $LOG_FILE
fi
done
echo "" | tee -a $LOG_FILE
}
test_path_traversal() {
echo "๐ Testing Path Traversal Protection..." | tee -a $LOG_FILE
# Path traversal payloads
payloads=(
"../../../etc/passwd"
"..\\..\\..\\windows\\system32\\drivers\\etc\\hosts"
"....//....//....//etc/passwd"
"%2e%2e%2f%2e%2e%2f%2e%2e%2fetc%2fpasswd"
"..%252f..%252f..%252fetc%252fpasswd"
)
for payload in "${payloads[@]}"; do
echo " Testing payload: $payload" | tee -a $LOG_FILE
response=$(curl -s -o /dev/null -w "%{http_code}" \
"$TARGET_URL/view?file=$payload")
if [ "$response" -eq 403 ] || [ "$response" -eq 406 ]; then
echo " โ
BLOCKED (HTTP $response)" | tee -a $LOG_FILE
else
echo " โ NOT BLOCKED (HTTP $response)" | tee -a $LOG_FILE
fi
done
echo "" | tee -a $LOG_FILE
}
test_rate_limiting() {
echo "โก Testing Rate Limiting..." | tee -a $LOG_FILE
echo " Sending 60 requests in 10 seconds..." | tee -a $LOG_FILE
blocked_count=0
for i in {1..60}; do
response=$(curl -s -o /dev/null -w "%{http_code}" "$TARGET_URL/")
if [ "$response" -eq 429 ]; then
((blocked_count++))
fi
sleep 0.1
done
echo " Requests blocked: $blocked_count/60" | tee -a $LOG_FILE
if [ $blocked_count -gt 0 ]; then
echo " โ
Rate limiting is working" | tee -a $LOG_FILE
else
echo " โ ๏ธ Rate limiting may not be configured" | tee -a $LOG_FILE
fi
echo "" | tee -a $LOG_FILE
}
test_command_injection() {
echo "๐ป Testing Command Injection Protection..." | tee -a $LOG_FILE
# Command injection payloads
payloads=(
"; ls -la"
"| cat /etc/passwd"
"\$(whoami)"
"`id`"
"&& ping -c 3 127.0.0.1"
)
for payload in "${payloads[@]}"; do
echo " Testing payload: $payload" | tee -a $LOG_FILE
response=$(curl -s -o /dev/null -w "%{http_code}" \
--data "command=ping $payload" \
"$TARGET_URL/ping")
if [ "$response" -eq 403 ] || [ "$response" -eq 406 ]; then
echo " โ
BLOCKED (HTTP $response)" | tee -a $LOG_FILE
else
echo " โ NOT BLOCKED (HTTP $response)" | tee -a $LOG_FILE
fi
done
echo "" | tee -a $LOG_FILE
}
# Run all tests
test_sql_injection
test_xss_protection
test_path_traversal
test_rate_limiting
test_command_injection
echo "๐ WAF testing completed!" | tee -a $LOG_FILE
echo "Results saved to: $LOG_FILE" | tee -a $LOG_FILE
echo "Completed: $(date)" | tee -a $LOG_FILE
EOF
chmod +x /opt/waf/scripts/test-waf.sh
Example 2: Real-time WAF Monitoring Dashboard
# Create real-time monitoring script
cat > /opt/waf/scripts/waf-monitor.sh << 'EOF'
#!/bin/bash
# Real-time WAF Monitoring Dashboard
AUDIT_LOG="/var/log/modsecurity/audit.log"
ACCESS_LOG="/var/log/httpd/access_log"
monitor_attacks() {
clear
echo "๐ก๏ธ WAF Real-time Monitoring Dashboard"
echo "======================================"
echo "Monitoring started: $(date)"
echo ""
# Attack statistics from last hour
echo "๐ Attack Statistics (Last Hour):"
echo "=================================="
# SQL Injection attempts
sql_attacks=$(grep -c "attack-sqli" $AUDIT_LOG | tail -1000 | grep "$(date -d '1 hour ago' '+%d/%b/%Y:%H')" | wc -l)
echo "SQL Injection attempts: $sql_attacks"
# XSS attempts
xss_attacks=$(grep -c "attack-xss" $AUDIT_LOG | tail -1000 | grep "$(date -d '1 hour ago' '+%d/%b/%Y:%H')" | wc -l)
echo "XSS attempts: $xss_attacks"
# Path traversal attempts
path_attacks=$(grep -c "attack-path-traversal" $AUDIT_LOG | tail -1000 | grep "$(date -d '1 hour ago' '+%d/%b/%Y:%H')" | wc -l)
echo "Path traversal attempts: $path_attacks"
# Rate limiting triggers
rate_blocks=$(grep -c "rate-limiting" $AUDIT_LOG | tail -1000 | grep "$(date -d '1 hour ago' '+%d/%b/%Y:%H')" | wc -l)
echo "Rate limit blocks: $rate_blocks"
echo ""
echo "๐ Current Connection Statistics:"
echo "================================="
# Current connections
current_connections=$(ss -tn | grep ":80\|:443" | wc -l)
echo "Active connections: $current_connections"
# Top attacking IPs
echo ""
echo "๐ฏ Top Attacking IPs (Last Hour):"
echo "=================================="
if [ -f "$AUDIT_LOG" ]; then
grep "$(date -d '1 hour ago' '+%d/%b/%Y:%H')" $AUDIT_LOG 2>/dev/null | \
grep -oP 'client: \K[0-9.]+' | \
sort | uniq -c | sort -nr | head -5 | \
while read count ip; do
echo "$ip: $count attacks"
done
else
echo "No recent attack data available"
fi
echo ""
echo "๐ Response Code Distribution (Last 100 requests):"
echo "================================================="
if [ -f "$ACCESS_LOG" ]; then
tail -100 $ACCESS_LOG | awk '{print $9}' | sort | uniq -c | sort -nr | \
while read count code; do
case $code in
200) echo "โ
$code (OK): $count" ;;
403) echo "๐ซ $code (Forbidden): $count" ;;
404) echo "โ $code (Not Found): $count" ;;
429) echo "โก $code (Rate Limited): $count" ;;
500) echo "โ $code (Server Error): $count" ;;
*) echo "๐ $code: $count" ;;
esac
done
else
echo "No access log data available"
fi
echo ""
echo "๐ Live Attack Feed (Last 10):"
echo "==============================="
if [ -f "$AUDIT_LOG" ]; then
tail -n 100 $AUDIT_LOG | grep -E "(msg:|client:)" | tail -10 | \
while IFS= read -r line; do
if [[ $line =~ client:\ ([0-9.]+) ]]; then
echo "๐ฏ IP: ${BASH_REMATCH[1]}"
elif [[ $line =~ msg:\'([^\']+) ]]; then
echo " Attack: ${BASH_REMATCH[1]}"
echo ""
fi
done
else
echo "No recent attack data available"
fi
}
# Continuous monitoring
while true; do
monitor_attacks
echo ""
echo "๐ Refreshing in 10 seconds... (Ctrl+C to exit)"
sleep 10
done
EOF
chmod +x /opt/waf/scripts/waf-monitor.sh
Example 3: Automated WAF Maintenance System
# Create automated maintenance system
cat > /opt/waf/scripts/waf-maintenance.sh << 'EOF'
#!/bin/bash
# Automated WAF Maintenance System
MAINTENANCE_LOG="/var/log/modsecurity/maintenance.log"
BACKUP_DIR="/opt/waf/backups"
RULES_DIR="/etc/modsecurity/rules"
CUSTOM_RULES_DIR="/etc/modsecurity/custom-rules"
log_message() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a $MAINTENANCE_LOG
}
update_owasp_rules() {
log_message "๐ Updating OWASP Core Rule Set..."
# Backup current rules
backup_date=$(date +%Y%m%d_%H%M%S)
mkdir -p "$BACKUP_DIR/rules_$backup_date"
cp -r $RULES_DIR/* "$BACKUP_DIR/rules_$backup_date/"
# Update CRS
cd /opt/waf/tools/coreruleset
git pull origin main
# Copy new rules
cp -r rules/* $RULES_DIR/
# Test configuration
if httpd -t; then
log_message "โ
OWASP rules updated successfully"
systemctl reload httpd
else
log_message "โ Configuration test failed, rolling back"
cp -r "$BACKUP_DIR/rules_$backup_date"/* $RULES_DIR/
systemctl reload httpd
fi
}
rotate_logs() {
log_message "๐๏ธ Rotating WAF logs..."
# Compress old audit logs
find /var/log/modsecurity -name "audit.log.*" -mtime +7 -exec gzip {} \;
# Remove very old compressed logs
find /var/log/modsecurity -name "audit.log.*.gz" -mtime +30 -delete
# Rotate current audit log
if [ -f "/var/log/modsecurity/audit.log" ]; then
mv /var/log/modsecurity/audit.log /var/log/modsecurity/audit.log.$(date +%Y%m%d)
touch /var/log/modsecurity/audit.log
chown apache:apache /var/log/modsecurity/audit.log
chmod 644 /var/log/modsecurity/audit.log
fi
log_message "โ
Log rotation completed"
}
analyze_attacks() {
log_message "๐ Analyzing recent attacks..."
REPORT_FILE="/opt/waf/reports/weekly_report_$(date +%Y%m%d).txt"
mkdir -p "$(dirname $REPORT_FILE)"
echo "WAF Weekly Security Report" > $REPORT_FILE
echo "=========================" >> $REPORT_FILE
echo "Report Date: $(date)" >> $REPORT_FILE
echo "" >> $REPORT_FILE
# Attack statistics
echo "Attack Statistics (Last 7 Days):" >> $REPORT_FILE
echo "================================" >> $REPORT_FILE
# Count different attack types
grep -c "attack-sqli" /var/log/modsecurity/audit.log* 2>/dev/null | \
awk -F: '{sum += $2} END {print "SQL Injection attempts: " sum}' >> $REPORT_FILE
grep -c "attack-xss" /var/log/modsecurity/audit.log* 2>/dev/null | \
awk -F: '{sum += $2} END {print "XSS attempts: " sum}' >> $REPORT_FILE
grep -c "rate-limiting" /var/log/modsecurity/audit.log* 2>/dev/null | \
awk -F: '{sum += $2} END {print "Rate limit violations: " sum}' >> $REPORT_FILE
echo "" >> $REPORT_FILE
# Top attacking IPs
echo "Top 10 Attacking IPs:" >> $REPORT_FILE
echo "===================" >> $REPORT_FILE
grep -h "client:" /var/log/modsecurity/audit.log* 2>/dev/null | \
grep -oP 'client: \K[0-9.]+' | \
sort | uniq -c | sort -nr | head -10 >> $REPORT_FILE
log_message "โ
Attack analysis completed: $REPORT_FILE"
}
optimize_performance() {
log_message "โก Optimizing WAF performance..."
# Clear expired collections
find /tmp -name "modsec_*" -mtime +1 -delete 2>/dev/null
# Optimize Apache configuration based on load
CURRENT_LOAD=$(uptime | awk -F'load average:' '{print $2}' | awk '{print $1}' | sed 's/,//')
LOAD_THRESHOLD="2.0"
if (( $(echo "$CURRENT_LOAD > $LOAD_THRESHOLD" | bc -l) )); then
log_message "โ ๏ธ High load detected ($CURRENT_LOAD), implementing optimizations"
# Temporarily reduce paranoia level
sed -i 's/setvar:tx.paranoia_level=2/setvar:tx.paranoia_level=1/' /etc/modsecurity/crs-setup.conf
systemctl reload httpd
# Schedule return to normal paranoia level
echo "sed -i 's/setvar:tx.paranoia_level=1/setvar:tx.paranoia_level=2/' /etc/modsecurity/crs-setup.conf && systemctl reload httpd" | at now + 1 hour
fi
log_message "โ
Performance optimization completed"
}
backup_configuration() {
log_message "๐พ Backing up WAF configuration..."
backup_date=$(date +%Y%m%d_%H%M%S)
backup_path="$BACKUP_DIR/config_$backup_date"
mkdir -p "$backup_path"
# Backup ModSecurity configuration
cp -r /etc/modsecurity "$backup_path/"
# Backup Apache configuration
cp -r /etc/httpd/conf.d "$backup_path/"
# Create configuration manifest
cat > "$backup_path/manifest.txt" << MANIFEST_EOF
WAF Configuration Backup
========================
Backup Date: $(date)
ModSecurity Version: $(modsecurity -v 2>/dev/null || echo "Unknown")
Apache Version: $(httpd -v | head -1)
OWASP CRS Version: $(grep -r "CRS_VERSION" /etc/modsecurity/rules/ | head -1 | cut -d'"' -f2)
Files Backed Up:
- ModSecurity configuration (/etc/modsecurity/)
- Apache WAF configuration (/etc/httpd/conf.d/)
- Custom rules and configurations
Restore Instructions:
1. Stop Apache: systemctl stop httpd
2. Restore configs: cp -r backup/* /etc/
3. Test config: httpd -t
4. Start Apache: systemctl start httpd
MANIFEST_EOF
# Compress backup
tar -czf "$backup_path.tar.gz" -C "$BACKUP_DIR" "config_$backup_date"
rm -rf "$backup_path"
# Keep only last 10 backups
ls -t $BACKUP_DIR/config_*.tar.gz | tail -n +11 | xargs rm -f
log_message "โ
Configuration backup completed: $backup_path.tar.gz"
}
# Main maintenance routine
case "$1" in
daily)
log_message "๐
Starting daily WAF maintenance..."
rotate_logs
optimize_performance
log_message "โ
Daily maintenance completed"
;;
weekly)
log_message "๐
Starting weekly WAF maintenance..."
update_owasp_rules
analyze_attacks
backup_configuration
rotate_logs
optimize_performance
log_message "โ
Weekly maintenance completed"
;;
*)
echo "Usage: $0 {daily|weekly}"
echo " daily - Run daily maintenance tasks"
echo " weekly - Run weekly maintenance tasks"
exit 1
;;
esac
EOF
chmod +x /opt/waf/scripts/waf-maintenance.sh
# Set up automated maintenance schedule
(crontab -l 2>/dev/null; echo "0 2 * * * /opt/waf/scripts/waf-maintenance.sh daily") | crontab -
(crontab -l 2>/dev/null; echo "0 3 * * 0 /opt/waf/scripts/waf-maintenance.sh weekly") | crontab -
๐จ Fix Common WAF Problems
Even security experts face challenges! Here are solutions to common WAF issues: ๐ช
Problem 1: High False Positive Rate
# Symptoms: Legitimate traffic being blocked incorrectly
# Solution: Tune WAF rules and implement whitelist exceptions
# Create false positive analysis script
cat > /opt/waf/scripts/analyze-false-positives.sh << 'EOF'
#!/bin/bash
# False Positive Analysis Tool
AUDIT_LOG="/var/log/modsecurity/audit.log"
WHITELIST_FILE="/etc/modsecurity/custom-rules/whitelist.conf"
echo "๐ Analyzing potential false positives..."
# Find most triggered rules
echo "Most frequently triggered rules (last 1000 entries):"
tail -1000 $AUDIT_LOG | grep -oP 'id "\K[0-9]+' | sort | uniq -c | sort -nr | head -10
echo ""
echo "Recent blocks that might be false positives:"
# Look for blocks from legitimate sources
tail -100 $AUDIT_LOG | grep -B5 -A5 "action: \"blocked\"" | \
grep -E "(client|msg|request)" | head -20
# Create whitelist template
cat > $WHITELIST_FILE << 'WHITELIST_EOF'
# Whitelist Rules for False Positive Mitigation
# Example: Allow specific IPs from false positive blocking
# SecRule REMOTE_ADDR "@ipMatch 192.168.1.100" \
# "id:9001,\
# phase:1,\
# pass,\
# nolog,\
# ctl:ruleEngine=Off"
# Example: Exclude specific endpoints from SQL injection checks
# SecRule REQUEST_URI "@beginsWith /api/search" \
# "id:9002,\
# phase:1,\
# pass,\
# nolog,\
# ctl:ruleRemoveById=942100"
# Example: Allow legitimate admin tool access
# SecRule REQUEST_HEADERS:User-Agent "@contains AdminTool/1.0" \
# "id:9003,\
# phase:1,\
# pass,\
# nolog,\
# ctl:ruleRemoveByTag=attack-sqli"
WHITELIST_EOF
echo "โ
Whitelist template created at: $WHITELIST_FILE"
echo "๐ Review the analysis above and add appropriate whitelist rules"
EOF
chmod +x /opt/waf/scripts/analyze-false-positives.sh
# Reduce paranoia level temporarily
sudo sed -i 's/setvar:tx.paranoia_level=2/setvar:tx.paranoia_level=1/' /etc/modsecurity/crs-setup.conf
sudo systemctl reload httpd
echo "โ ๏ธ Reduced paranoia level to 1 for testing"
echo "๐ Run /opt/waf/scripts/analyze-false-positives.sh to identify issues"
Problem 2: WAF Performance Impact
# Symptoms: Slow response times after WAF deployment
# Solution: Optimize WAF configuration and Apache settings
# Performance optimization script
cat > /opt/waf/scripts/optimize-waf-performance.sh << 'EOF'
#!/bin/bash
echo "โก Optimizing WAF performance..."
# Optimize ModSecurity settings for performance
sudo tee -a /etc/modsecurity/modsecurity.conf << 'PERF_EOF'
# Performance optimizations
SecRequestBodyInMemoryLimit 131072
SecRequestBodyLimit 13107200
SecRequestBodyNoFilesLimit 131072
SecResponseBodyLimit 524288
SecTmpDir /dev/shm/modsecurity
SecDataDir /dev/shm/modsecurity
# Reduce logging overhead
SecAuditEngine RelevantOnly
SecAuditLogRelevantStatus "^(?:5|4(?!04))"
SecDebugLogLevel 0
# Collection timeout optimization
SecCollectionTimeout 600
PERF_EOF
# Create RAM-based temp directories
sudo mkdir -p /dev/shm/modsecurity
sudo chown apache:apache /dev/shm/modsecurity
sudo chmod 755 /dev/shm/modsecurity
# Optimize Apache for WAF
sudo tee /etc/httpd/conf.d/waf-performance.conf << 'APACHE_EOF'
# WAF Performance Optimizations
# Worker MPM tuning for WAF
<IfModule mod_mpm_worker.c>
StartServers 3
MinSpareThreads 75
MaxSpareThreads 250
ThreadsPerChild 25
MaxRequestWorkers 400
MaxConnectionsPerChild 0
</IfModule>
# Enable compression to reduce bandwidth
<IfModule mod_deflate.c>
SetOutputFilter DEFLATE
SetEnvIfNoCase Request_URI \
\.(?:gif|jpe?g|png)$ no-gzip dont-vary
SetEnvIfNoCase Request_URI \
\.(?:exe|t?gz|zip|bz2|sit|rar)$ no-gzip dont-vary
</IfModule>
# Cache static content
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
ExpiresByType image/jpg "access plus 1 month"
ExpiresByType image/jpeg "access plus 1 month"
ExpiresByType image/gif "access plus 1 month"
</IfModule>
APACHE_EOF
# Optimize system for WAF workload
echo "
# WAF Performance Tuning
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
net.core.netdev_max_backlog = 5000
vm.swappiness = 10" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
# Test configuration and restart
if sudo httpd -t; then
sudo systemctl restart httpd
echo "โ
Performance optimizations applied successfully"
else
echo "โ Configuration error detected, please check Apache configuration"
fi
EOF
chmod +x /opt/waf/scripts/optimize-waf-performance.sh
Problem 3: WAF Rules Not Loading
# Symptoms: ModSecurity not blocking attacks, rules not active
# Solution: Debug rule loading and configuration issues
# Rule debugging script
cat > /opt/waf/scripts/debug-waf-rules.sh << 'EOF'
#!/bin/bash
echo "๐ง Debugging WAF rule loading..."
# Check ModSecurity module loading
echo "1. Checking ModSecurity module status:"
if httpd -M 2>/dev/null | grep -q security; then
echo " โ
ModSecurity module is loaded"
else
echo " โ ModSecurity module not loaded"
echo " Fix: Add 'LoadModule security3_module modules/mod_security3.so' to Apache config"
fi
echo ""
echo "2. Checking rule engine status:"
if grep -q "SecRuleEngine On" /etc/modsecurity/modsecurity.conf; then
echo " โ
Rule engine is enabled"
else
echo " โ Rule engine is disabled"
echo " Fix: Set 'SecRuleEngine On' in modsecurity.conf"
fi
echo ""
echo "3. Testing configuration syntax:"
if httpd -t 2>/dev/null; then
echo " โ
Apache configuration is valid"
else
echo " โ Apache configuration has errors:"
httpd -t
fi
echo ""
echo "4. Checking rule file permissions:"
find /etc/modsecurity -name "*.conf" -exec ls -la {} \; | while read line; do
if [[ $line =~ ^-.*r.*apache ]]; then
echo " โ
$(echo $line | awk '{print $9}')"
else
echo " โ ๏ธ $(echo $line | awk '{print $9}') - Check permissions"
fi
done
echo ""
echo "5. Checking for rule syntax errors:"
# Test individual rule files
for rule_file in /etc/modsecurity/rules/*.conf; do
if [ -f "$rule_file" ]; then
if grep -q "SecRule" "$rule_file"; then
echo " ๐ $(basename $rule_file): Contains rules"
else
echo " โ ๏ธ $(basename $rule_file): No rules found"
fi
fi
done
echo ""
echo "6. Checking include statements:"
if grep -q "Include.*main.conf" /etc/httpd/conf.d/security.conf; then
echo " โ
Main configuration included"
else
echo " โ Main configuration not included"
echo " Fix: Add 'modsecurity_rules_file /etc/modsecurity/main.conf' to Apache config"
fi
echo ""
echo "7. Testing with simple rule:"
cat > /tmp/test-rule.conf << 'TESTRULE'
SecRule ARGS "@contains test123" \
"id:999999,\
phase:2,\
deny,\
msg:'Test rule triggered',\
log"
TESTRULE
echo " Created test rule: /tmp/test-rule.conf"
echo " Add 'Include /tmp/test-rule.conf' to main.conf and test with: curl 'http://yoursite/?param=test123'"
EOF
chmod +x /opt/waf/scripts/debug-waf-rules.sh
Problem 4: WAF Logs Not Generating
# Symptoms: No audit logs or debug information
# Solution: Fix logging configuration and permissions
# Logging diagnostics script
cat > /opt/waf/scripts/fix-waf-logging.sh << 'EOF'
#!/bin/bash
echo "๐ Fixing WAF logging issues..."
# Check log directory permissions
echo "1. Checking log directory permissions:"
if [ -d "/var/log/modsecurity" ]; then
ls -la /var/log/modsecurity
echo " Setting correct permissions..."
sudo chown -R apache:apache /var/log/modsecurity
sudo chmod 755 /var/log/modsecurity
sudo chmod 644 /var/log/modsecurity/*.log 2>/dev/null || true
echo " โ
Permissions corrected"
else
echo " Creating log directory..."
sudo mkdir -p /var/log/modsecurity
sudo chown apache:apache /var/log/modsecurity
sudo chmod 755 /var/log/modsecurity
echo " โ
Log directory created"
fi
echo ""
echo "2. Checking logging configuration:"
# Enable debug logging temporarily
sudo tee /etc/modsecurity/debug-logging.conf << 'DEBUG_EOF'
# Debug logging configuration
SecDebugLog /var/log/modsecurity/debug.log
SecDebugLogLevel 9
SecAuditEngine On
SecAuditLogType Serial
SecAuditLog /var/log/modsecurity/audit.log
SecAuditLogParts ABDEFHIJZ
DEBUG_EOF
# Create log files if they don't exist
sudo touch /var/log/modsecurity/debug.log
sudo touch /var/log/modsecurity/audit.log
sudo chown apache:apache /var/log/modsecurity/*.log
sudo chmod 644 /var/log/modsecurity/*.log
echo " โ
Debug logging enabled"
echo ""
echo "3. Testing log generation:"
echo " Making test request to trigger logging..."
# Make a test request that should generate logs
curl -s "http://localhost/?test=modsecurity_log_test" > /dev/null
sleep 2
# Check if logs were generated
if [ -s "/var/log/modsecurity/audit.log" ] || [ -s "/var/log/modsecurity/debug.log" ]; then
echo " โ
Logs are being generated"
echo " Recent log entries:"
tail -5 /var/log/modsecurity/audit.log 2>/dev/null || echo " No audit log entries yet"
tail -5 /var/log/modsecurity/debug.log 2>/dev/null || echo " No debug log entries yet"
else
echo " โ No logs generated"
echo " Check if ModSecurity is properly loaded and configured"
fi
echo ""
echo "4. Setting up log rotation:"
sudo tee /etc/logrotate.d/modsecurity << 'LOGROTATE_EOF'
/var/log/modsecurity/*.log {
daily
rotate 30
compress
delaycompress
missingok
notifempty
copytruncate
postrotate
systemctl reload httpd
endscript
}
LOGROTATE_EOF
echo " โ
Log rotation configured"
echo ""
echo "5. Restarting Apache to apply changes:"
if sudo systemctl restart httpd; then
echo " โ
Apache restarted successfully"
else
echo " โ Apache restart failed"
sudo systemctl status httpd
fi
echo ""
echo "๐ก To disable debug logging later, set SecDebugLogLevel to 0"
EOF
chmod +x /opt/waf/scripts/fix-waf-logging.sh
Problem 5: WAF Blocking Legitimate API Calls
# Symptoms: API clients unable to connect, JSON requests blocked
# Solution: Create API-specific rules and exceptions
# API protection configuration
cat > /etc/modsecurity/custom-rules/api-protection.conf << 'EOF'
# API-Specific Protection Rules
# Allow JSON content types for API endpoints
SecRule REQUEST_URI "@beginsWith /api/" \
"id:5001,\
phase:1,\
pass,\
nolog,\
ctl:requestBodyProcessor=JSON"
# Relax some rules for API endpoints
SecRule REQUEST_URI "@beginsWith /api/" \
"id:5002,\
phase:1,\
pass,\
nolog,\
ctl:ruleRemoveById=920230,\
ctl:ruleRemoveById=920300,\
ctl:ruleRemoveById=920320"
# Allow larger request bodies for API uploads
SecRule REQUEST_URI "@beginsWith /api/upload" \
"id:5003,\
phase:1,\
pass,\
nolog,\
ctl:requestBodyLimit=52428800"
# Rate limiting specific to API endpoints
SecAction \
"id:5004,\
phase:1,\
nolog,\
pass,\
initcol:ip=%{REMOTE_ADDR}_api,\
setvar:ip.api_requests=+1,\
expirevar:ip.api_requests=60"
SecRule IP:API_REQUESTS "@gt 300" \
"id:5005,\
phase:1,\
deny,\
status:429,\
msg:'API rate limit exceeded',\
logdata:'IP: %{REMOTE_ADDR}, Requests: %{IP.API_REQUESTS}'"
# Allow specific HTTP methods for RESTful APIs
SecRule REQUEST_URI "@beginsWith /api/" \
"id:5006,\
phase:1,\
pass,\
nolog,\
setvar:tx.allowed_methods=GET HEAD POST PUT DELETE PATCH OPTIONS"
# API authentication bypass for certain checks
SecRule REQUEST_HEADERS:Authorization "@rx ^Bearer " \
"id:5007,\
phase:1,\
pass,\
nolog,\
setvar:tx.authenticated_api=1"
# Whitelist known API clients by User-Agent
SecRule REQUEST_HEADERS:User-Agent "@rx (curl|wget|python-requests|okhttp|axios)" \
"id:5008,\
phase:1,\
pass,\
log,\
msg:'Known API client detected',\
setvar:tx.api_client=1"
# CORS preflight request handling
SecRule REQUEST_METHOD "@streq OPTIONS" \
"id:5009,\
phase:1,\
pass,\
nolog,\
ctl:ruleEngine=Off"
EOF
# Test API configuration
echo "๐งช Testing API configuration..."
echo "Use these commands to test API access:"
echo ""
echo "# Test basic API call:"
echo "curl -X GET http://localhost/api/test"
echo ""
echo "# Test with JSON payload:"
echo "curl -X POST -H 'Content-Type: application/json' -d '{\"test\":\"data\"}' http://localhost/api/test"
echo ""
echo "# Test with authentication:"
echo "curl -X GET -H 'Authorization: Bearer token123' http://localhost/api/secure"
echo ""
echo "โ
API protection rules created"
๐ WAF Commands Summary
Hereโs your quick reference for WAF operations! โก
Task | Command | Description |
---|---|---|
Test WAF | /opt/waf/scripts/test-waf.sh | Run comprehensive attack tests |
Monitor WAF | /opt/waf/scripts/waf-monitor.sh | Real-time attack monitoring |
Check Rules | grep SecRule /etc/modsecurity/rules/*.conf | List all active rules |
View Attacks | tail -f /var/log/modsecurity/audit.log | Monitor live attacks |
Test Config | httpd -t | Validate Apache configuration |
Reload Rules | systemctl reload httpd | Apply rule changes |
Debug Mode | SecDebugLogLevel 9 | Enable detailed debugging |
Rule Stats | /opt/waf/scripts/analyze-false-positives.sh | Analyze rule triggers |
Performance | /opt/waf/scripts/optimize-waf-performance.sh | Optimize WAF performance |
Maintenance | /opt/waf/scripts/waf-maintenance.sh weekly | Run maintenance tasks |
Fix Logging | /opt/waf/scripts/fix-waf-logging.sh | Resolve logging issues |
Whitelist IP | Add SecRule REMOTE_ADDR "@ipMatch IP" | Whitelist specific IPs |
๐ก Pro Tips for WAF Mastery
Want to become a WAF security ninja? Here are expert secrets! ๐ฅท
Tip 1: Dynamic Threat Intelligence Integration
# Create threat intelligence integration
cat > /opt/waf/scripts/threat-intelligence.sh << 'EOF'
#!/bin/bash
# Dynamic Threat Intelligence Integration
THREAT_FEED_URL="https://rules.emergingthreats.net/open/suricata/rules/emerging-malware.rules"
CUSTOM_RULES_DIR="/etc/modsecurity/custom-rules"
THREAT_RULES_FILE="$CUSTOM_RULES_DIR/threat-intelligence.conf"
update_threat_rules() {
echo "๐ Updating threat intelligence rules..."
# Download latest threat intelligence
curl -s "$THREAT_FEED_URL" > /tmp/threat_rules.tmp
# Convert to ModSecurity format (simplified example)
cat > "$THREAT_RULES_FILE" << 'THREAT_EOF'
# Dynamic Threat Intelligence Rules
# Updated: $(date)
# Block known malicious IPs (example)
SecRule REMOTE_ADDR "@ipMatchFromFile /opt/waf/threat-intel/malicious-ips.txt" \
"id:6001,\
phase:1,\
deny,\
msg:'IP blocked by threat intelligence',\
logdata:'Malicious IP: %{REMOTE_ADDR}',\
tag:'threat-intel',\
severity:'ERROR'"
# Block known malicious domains in requests
SecRule REQUEST_HEADERS:Host "@pmFromFile /opt/waf/threat-intel/malicious-domains.txt" \
"id:6002,\
phase:1,\
deny,\
msg:'Malicious domain detected',\
logdata:'Domain: %{REQUEST_HEADERS.Host}',\
tag:'threat-intel',\
severity:'ERROR'"
THREAT_EOF
echo "โ
Threat intelligence rules updated"
}
# Create threat intelligence directories
mkdir -p /opt/waf/threat-intel
# Sample malicious IP list (replace with real threat feed)
cat > /opt/waf/threat-intel/malicious-ips.txt << 'IPS_EOF'
# Malicious IP addresses
192.0.2.1
198.51.100.1
203.0.113.1
IPS_EOF
# Schedule regular updates
update_threat_rules
echo "0 4 * * * /opt/waf/scripts/threat-intelligence.sh" | crontab -
EOF
chmod +x /opt/waf/scripts/threat-intelligence.sh
Tip 2: Machine Learning Anomaly Detection
# Create ML-based anomaly detection
cat > /opt/waf/scripts/ml-anomaly-detection.py << 'EOF'
#!/usr/bin/env python3
"""
Machine Learning Anomaly Detection for WAF
Analyzes request patterns to detect anomalies
"""
import re
import json
import datetime
from collections import defaultdict, Counter
import logging
class WAFAnomalyDetector:
def __init__(self):
self.baseline_patterns = defaultdict(int)
self.current_patterns = defaultdict(int)
self.anomaly_threshold = 3.0 # Standard deviations
def parse_log_line(self, line):
"""Parse ModSecurity audit log line"""
patterns = {
'ip': r'client: ([\d.]+)',
'method': r'METHOD: (\w+)',
'uri': r'URI: ([^\s]+)',
'user_agent': r'User-Agent: ([^\n]+)',
'content_length': r'Content-Length: (\d+)'
}
extracted = {}
for key, pattern in patterns.items():
match = re.search(pattern, line)
if match:
extracted[key] = match.group(1)
return extracted
def analyze_request_patterns(self, log_file):
"""Analyze request patterns for anomalies"""
print("๐ Analyzing request patterns for anomalies...")
current_hour = datetime.datetime.now().hour
hourly_stats = defaultdict(lambda: defaultdict(int))
try:
with open(log_file, 'r') as f:
for line in f:
if 'client:' in line:
data = self.parse_log_line(line)
if 'ip' in data:
# Track requests per IP per hour
hourly_stats[current_hour]['ip_requests'][data['ip']] += 1
if 'uri' in data:
# Track URI patterns
uri_pattern = re.sub(r'\d+', 'N', data['uri']) # Normalize numbers
hourly_stats[current_hour]['uri_patterns'][uri_pattern] += 1
if 'user_agent' in data:
# Track User-Agent patterns
hourly_stats[current_hour]['user_agents'][data['user_agent']] += 1
except FileNotFoundError:
print(f"โ Log file not found: {log_file}")
return
# Detect anomalies
self.detect_anomalies(hourly_stats[current_hour])
def detect_anomalies(self, stats):
"""Detect statistical anomalies in request patterns"""
anomalies = []
# Detect IP-based anomalies
if 'ip_requests' in stats:
ip_counts = list(stats['ip_requests'].values())
if ip_counts:
avg_requests = sum(ip_counts) / len(ip_counts)
for ip, count in stats['ip_requests'].items():
if count > avg_requests * self.anomaly_threshold:
anomalies.append({
'type': 'high_request_volume',
'ip': ip,
'count': count,
'threshold': avg_requests * self.anomaly_threshold
})
# Detect URI anomalies
if 'uri_patterns' in stats:
unusual_uris = []
for uri, count in stats['uri_patterns'].items():
# Flag URIs with suspicious patterns
if re.search(r'(\.\./|admin|config|sql|union|select)', uri.lower()):
unusual_uris.append({'uri': uri, 'count': count})
if unusual_uris:
anomalies.append({
'type': 'suspicious_uri_patterns',
'uris': unusual_uris
})
# Report anomalies
if anomalies:
self.report_anomalies(anomalies)
else:
print("โ
No significant anomalies detected")
def report_anomalies(self, anomalies):
"""Report detected anomalies"""
print("๐จ ANOMALIES DETECTED:")
print("=" * 50)
for anomaly in anomalies:
if anomaly['type'] == 'high_request_volume':
print(f"โ ๏ธ High request volume from IP: {anomaly['ip']}")
print(f" Requests: {anomaly['count']}")
print(f" Threshold: {anomaly['threshold']:.1f}")
# Generate ModSecurity rule
rule_id = 7000 + hash(anomaly['ip']) % 1000
print(f" Suggested rule:")
print(f' SecRule REMOTE_ADDR "@streq {anomaly['ip']}" \\')
print(f' "id:{rule_id},\\')
print(f' phase:1,\\')
print(f' deny,\\')
print(f' msg:\'High volume anomaly detected\',\\')
print(f' tag:\'anomaly-detection\'"')
print()
elif anomaly['type'] == 'suspicious_uri_patterns':
print("โ ๏ธ Suspicious URI patterns detected:")
for uri_data in anomaly['uris']:
print(f" URI: {uri_data['uri']} (Count: {uri_data['count']})")
print()
if __name__ == "__main__":
detector = WAFAnomalyDetector()
detector.analyze_request_patterns('/var/log/modsecurity/audit.log')
EOF
chmod +x /opt/waf/scripts/ml-anomaly-detection.py
# Schedule anomaly detection
(crontab -l 2>/dev/null; echo "0 */6 * * * /opt/waf/scripts/ml-anomaly-detection.py") | crontab -
Tip 3: Advanced Geo-Location Based Protection
# Create advanced geo-location protection
cat > /etc/modsecurity/custom-rules/geo-protection.conf << 'EOF'
# Advanced Geo-Location Based Protection
# Allow specific countries for normal traffic
SecRule GEO:COUNTRY_CODE "!@within US CA GB DE FR AU JP" \
"id:8001,\
phase:1,\
pass,\
log,\
msg:'Request from non-whitelisted country',\
logdata:'Country: %{GEO.COUNTRY_CODE}, IP: %{REMOTE_ADDR}',\
setvar:tx.geo_risk_score=+2,\
tag:'geo-monitoring'"
# Higher scrutiny for high-risk countries
SecRule GEO:COUNTRY_CODE "@within CN RU KP IR" \
"id:8002,\
phase:1,\
pass,\
log,\
msg:'Request from high-risk country',\
logdata:'Country: %{GEO.COUNTRY_CODE}, IP: %{REMOTE_ADDR}',\
setvar:tx.geo_risk_score=+5,\
setvar:tx.enhanced_monitoring=1,\
tag:'geo-high-risk'"
# Block admin access from non-authorized countries
SecRule REQUEST_URI "@beginsWith /admin" \
"id:8003,\
phase:1,\
chain,\
deny,\
msg:'Admin access blocked from unauthorized country'"
SecRule GEO:COUNTRY_CODE "!@within US CA" \
"logdata:'Admin access attempt from %{GEO.COUNTRY_CODE}'"
# Enhanced monitoring for high geo-risk requests
SecRule TX:ENHANCED_MONITORING "@eq 1" \
"id:8004,\
phase:2,\
pass,\
log,\
msg:'Enhanced monitoring active',\
setvar:tx.anomaly_score_threshold=3"
# Time-based geo restrictions (example: block certain countries during off-hours)
SecRule TIME_HOUR "@ge 22" \
"id:8005,\
phase:1,\
chain,\
deny,\
msg:'Access blocked during maintenance hours'"
SecRule GEO:COUNTRY_CODE "!@within US CA GB" \
"logdata:'Off-hours access blocked from %{GEO.COUNTRY_CODE}'"
# Geo-based rate limiting
SecAction \
"id:8006,\
phase:1,\
nolog,\
pass,\
initcol:geo=%{GEO.COUNTRY_CODE},\
setvar:geo.requests_per_hour=+1,\
expirevar:geo.requests_per_hour=3600"
# Stricter rate limits for non-whitelisted countries
SecRule GEO:COUNTRY_CODE "!@within US CA GB DE FR AU JP" \
"id:8007,\
phase:1,\
chain,\
deny,\
msg:'Geo-based rate limit exceeded'"
SecRule GEO:REQUESTS_PER_HOUR "@gt 100" \
"logdata:'Rate limit exceeded for country %{GEO.COUNTRY_CODE}'"
EOF
echo "๐ Advanced geo-location protection configured"
echo "๐ Update country codes in the rules based on your requirements"
๐ What Youโve Accomplished - WAF Security Mastery!
Congratulations! Youโve built an enterprise-grade Web Application Firewall on AlmaLinux! ๐ Letโs celebrate your incredible security achievements:
๐ก๏ธ Complete WAF Security Infrastructure:
- โ ModSecurity 3.x with advanced configuration and optimization
- โ OWASP Core Rule Set with comprehensive attack protection
- โ Custom rule development for application-specific threats
- โ Advanced DDoS protection and rate limiting mechanisms
- โ Real-time attack monitoring and alerting systems
- โ Machine learning anomaly detection capabilities
- โ Geo-location based access controls and restrictions
- โ Automated maintenance and rule updates
- โ Performance optimization and false positive mitigation
๐ช Professional Security Skills Gained:
- โ Web Application Firewall architecture and deployment
- โ Advanced attack pattern recognition and mitigation
- โ Custom security rule development and testing
- โ Performance optimization for high-traffic environments
- โ False positive analysis and whitelist management
- โ Threat intelligence integration and automation
- โ Security monitoring and incident response
- โ Compliance implementation (PCI DSS, OWASP Top 10)
- โ Advanced logging and forensic analysis
- โ Security automation and DevSecOps practices
๐ฏ Enterprise-Grade Security Features:
- โ Protection against OWASP Top 10 vulnerabilities
- โ Real-time threat detection and response
- โ Advanced bot detection and anti-automation
- โ API-specific protection and rate limiting
- โ Geographic access controls and restrictions
- โ Machine learning powered anomaly detection
- โ Comprehensive audit logging and compliance reporting
- โ Automated threat intelligence updates
- โ Performance-optimized rule processing
๐ฏ Why This WAF Setup Matters
Your AlmaLinux Web Application Firewall is now a production-ready, enterprise-grade security platform! ๐
Real-World Impact:
- ๐ก๏ธ Advanced Threat Protection - Block sophisticated attacks before they reach applications
- ๐ฐ Reduced Security Costs - Prevent costly data breaches and downtime
- ๐ Compliance Achievement - Meet PCI DSS, HIPAA, and other regulatory requirements
- ๐ Business Continuity - Ensure applications remain available under attack
- ๐ Threat Visibility - Complete insight into attack patterns and trends
- โก Zero-Day Protection - Virtual patching for unknown vulnerabilities
- ๐ฏ Risk Mitigation - Reduce attack surface and security exposure
- ๐ก Security Intelligence - Learn from attacks to improve defenses
- ๐ Global Protection - Defend against worldwide threat actors
- ๐ Professional Growth - Master enterprise security technologies
Youโre not just running a firewall - youโre operating a sophisticated security intelligence platform! Whether youโre protecting e-commerce sites, financial applications, or enterprise systems, your AlmaLinux WAF provides military-grade protection against the most advanced cyber threats! ๐
Your applications are now fortress-secure and ready to withstand any attack! โญ Stay vigilant and keep securing! ๐