Skip to content

Caddy WAF:基于OWASP规则的Web应用防火墙,中间件

Published:

原文链接


🛡️ Caddy WAF Middleware

A simple Web Application Firewall (WAF) middleware for the Caddy server, designed to provide comprehensive protection against web attacks. This middleware integrates seamlessly with Caddy and offers a wide range of security features to safeguard your applications.


📑 Table of Contents

  1. 🌟 Key Features

  2. 🚀 Installation

  3. 🛠️ Configuration

  4. ⚙️ Configuration Options

  5. 📜 Rules Format (rules.json)

  6. 🛡️ Protected Attack Types

  7. 🚫 Blacklist Formats

  8. ⏱️ Rate Limiting

  9. 🌍 Country Blocking

  10. 🔄 Dynamic Updates

  11. 🧪 Testing

  1. 🐳 Docker Support

  2. 🐍 Rule/Blacklist Population Scripts

  3. 📜 License

  4. 🙏 Contributing


🌟 Key Features

🚀 Installation

# Step 1: Clone the caddy-waf repository from GitHub
# This downloads the source code for the caddy-waf module to your local machine.
git clone https://github.com/fabriziosalmi/caddy-waf.git

# Step 2: Navigate into the caddy-waf directory
# This changes your current working directory to the caddy-waf project folder.
cd caddy-waf

# Step 3: Clean up and update the go.mod file
# This ensures that your project's dependencies are up-to-date and consistent.
go mod tidy

# Step 4: Fetch and install the required Go modules
# This downloads and installs the caddy-waf module, Caddy v2, and the maxminddb-golang library.
go get -v github.com/fabriziosalmi/caddy-waf github.com/caddyserver/caddy/v2 github.com/oschwald/maxminddb-golang

# Step 5: Download the GeoLite2 Country database
# This downloads the GeoLite2 Country database, which is required for IP-based country filtering.
wget https://git.io/GeoLite2-Country.mmdb

# Step 6: Clean up previous build artifacts
# This removes any temporary build directories from previous builds to ensure a clean build environment.
rm -rf buildenv_*

# Step 7: Build Caddy with the caddy-waf module
# This compiles Caddy and includes the caddy-waf module as a custom plugin.
xcaddy build --with github.com/fabriziosalmi/caddy-waf=./

# Step 8: Run the compiled Caddy server
# This starts the Caddy server with the caddy-waf module enabled.
./caddy run

Final Notes

🛠️ Configuration

Basic Caddyfile Setup

{
    auto_https off
    admin off
    debug
}

:8080 {
    log {
        output stdout
        format console
        level DEBUG
    }

    route {
        waf {
            # Anomaly threshold will block request if the score is => the threshold
            anomaly_threshold 5

            # Rate limiting: 1000 requests per 1 minute
            rate_limit 1000 1m

            # Rules and blacklists
            rule_file rules.json
            ip_blacklist_file ip_blacklist.txt
            dns_blacklist_file dns_blacklist.txt

            # Country blocking (requires MaxMind GeoIP2 database)
            block_countries GeoLite2-Country.mmdb RU CN KP

            # Whitelist countries (requires MaxMind GeoIP2 database)
            # whitelist_countries GeoLite2-Country.mmdb US

             # Define actions based on severity
            severity critical block
            severity high block
            severity medium log
            severity low log

             # Set Log Severity
            log_severity debug

            #Set Log JSON output
            log_json
        }
        respond "Hello, world!" 200
    }
}

⚙️ Configuration Options

OptionDescriptionExample
anomaly_thresholdSets the anomaly score threshold.anomaly_threshold 20
rule_fileJSON file containing WAF rulesrule_file rules.json
ip_blacklist_fileFile with blocked IPs/CIDR rangesip_blacklist_file blacklist.txt
dns_blacklist_fileFile with blocked domainsdns_blacklist_file domains.txt
rate_limitRate limiting configrate_limit 100 1m
block_countriesCountry blocking configblock_countries GeoLite2-Country.mmdb RU CN NK
whitelist_countriesCountry whitelisting configwhitelist_countries GeoLite2-Country.mmdb US GB CA
severityDefine actions based on severity levelsseverity critical block
log_severitySets the minimum logging severity level for this module.log_severity debug
log_jsonEnables JSON log outputlog_json

📜 Rules Format (rules.json)

Rules are defined in a JSON file. Each rule specifies a pattern to match, targets to inspect, and actions to take.

[
    {
        "id": "wordpress-brute-force",
        "phase": 2,
        "pattern": "(?i)(?:wp-login\\.php|xmlrpc\\.php).*?(?:username=|pwd=)",
        "targets": ["URI", "ARGS"],
        "severity": "HIGH",
        "action": "block",
        "score": 8,
        "description": "Block brute force attempts targeting WordPress login and XML-RPC endpoints."
    }
]

Rule Fields

FieldDescriptionExample
idUnique rule identifiersql_injection
phaseProcessing phase (1-2)1
patternRegular expression pattern`(?i)(?:select
targetsAreas to inspect["ARGS", "BODY"]
severityRule severity (CRITICAL, HIGH, MEDIUM, LOW)CRITICAL
actionAction to take (block, log, allow, detect)block
scoreScore for anomaly detection10
descriptionRule descriptionBlock SQL injection attempts.

🛡️ Protected Attack Types

  1. SQL Injection

    • Basic SELECT/UNION injections
    • Time-based injection attacks
    • Boolean-based injections
  2. Cross-Site Scripting (XSS)

    • Script tag injection
    • Event handler injection
    • SVG-based XSS
  3. Path Traversal

    • Directory traversal attempts
    • Encoded path traversal
    • Double-encoded traversal
  4. Remote Code Execution (RCE)

    • Command injection
    • Shell command execution
    • System command execution
  5. Log4j Exploits

    • JNDI lookup attempts
    • Nested expressions
  6. Protocol Attacks

    • Git repository access
    • Environment file access
    • Configuration file access
  7. Scanner Detection

    • Common vulnerability scanners
    • Web application scanners
    • Network scanning tools

🚫 Blacklist Formats

IP Blacklist (ip_blacklist.txt)

192.168.1.1
10.0.0.0/8
2001:db8::/32

DNS Blacklist (dns_blacklist.txt)

malicious.com
evil.example.org

⏱️ Rate Limiting

Configure rate limits using requests count and time window:

# 100 requests per minute
rate_limit 100 1m

# 10 requests per second
rate_limit 10 1s

# 1000 requests per hour
rate_limit 1000 1h

🌍 Country Blocking

Block traffic from specific countries using ISO country codes:

# Block requests from Russia, China, and North Korea
block_countries /path/to/GeoLite2-Country.mmdb RU CN KP

🔄 Dynamic Updates

Rules and blacklists can be updated without server restart:

  1. Modify rules.json or blacklist files.
  2. Reload Caddy: caddy reload.

🧪 Testing

Basic Testing

# Test rate limiting
for i in {1..10}; do curl -i http://localhost:8080/; done

# Test country blocking
curl -H "X-Real-IP: 1.2.3.4" http://localhost:8080/

# Test SQL injection protection
curl "http://localhost:8080/?id=1+UNION+SELECT+*+FROM+users"

# Test XSS protection
curl "http://localhost:8080/?input=<script>alert(1)</script>"

Load Testing

ab -n 1000 -c 100 http://localhost:8080/

Security Testing Suite

A test.sh script is included in this repository to perform a comprehensive security test suite. This script sends a series of forged curl requests, each designed to simulate a different type of attack.

Below is an example of how to run the script and a sample output:

caddy-waf % ./test.sh
WAF Security Test Suite
Target: http://localhost:8080
Date: Dom  5 Gen 2025 16:00:37 CET
----------------------------------------
[✗] SQL Injection - SQL Server Version                           [200]
[✗] SQL Injection - SQL Server Time Delay                        [200]
[✓] SQL Injection - Oracle Time Delay                            [403]
[✗] SQL Injection - Error Based 1                                [200]
[✗] SQL Injection - Error Based 2                                [200]
[✗] SQL Injection - Error Based 3                                [200]
[✗] SQL Injection - MySQL user                                   [200]
[✗] SQL Injection - PostgreSQL user                              [200]
[✗] SQL Injection - Case Variation                               [200]
[✗] SQL Injection - Whitespace Variation                         [200]
[✗] SQL Injection - Obfuscation Variation                        [200]
[✗] SQL Injection - Unicode Variation                            [200]
[✗] SQL Injection - Triple URL Encoded Variation                 [200]
[✗] SQL Injection - OOB DNS Lookup                               [200]
[✗] SQL Injection - Oracle OOB DNS Lookup                        [200]
[✓] SQL Injection - Header - Basic Select                        [403]
[✓] SQL Injection - Cookie - Basic Select                        [403]
[✗] SQL Injection - Header - Basic Select                        [200]
[✗] SQL Injection - JSON body                                    [200]
[✓] XSS - Basic Script Tag                                       [403]
[✓] XSS - IMG Onerror                                            [403]
[✓] XSS - JavaScript Protocol                                    [403]
[✓] XSS - SVG Onload                                             [403]
[✓] XSS - Anchor Tag JavaScript                                  [403]
[✓] XSS - URL Encoded Script                                     [403]
[✓] XSS - Double URL Encoded                                     [403]
[✓] XSS - URL Encoded IMG                                        [403]
[✓] XSS - Body Onload                                            [403]
[✓] XSS - Input Onfocus Autofocus                                [403]
[✓] XSS - Breaking Out of Attribute                              [403]
[✓] XSS - HTML Encoded                                           [403]
[✓] XSS - IFRAME srcdoc                                          [403]
[✓] XSS - Details Tag                                            [403]
[✓] XSS - HTML Comment Breakout                                  [403]
[✓] Path Traversal - Basic                                       [403]
[✓] Path Traversal - Double Dot                                  [403]
[✓] Path Traversal - Triple Dot                                  [403]
[✓] Path Traversal - URL Encoded                                 [403]
[✗] Path Traversal - Double URL Encoded                          [200]
[✓] Path Traversal - Mixed Slashes                               [403]
[✗] Path Traversal - UTF-8 Encoded                               [200]
[✓] Path Traversal - Encoded and Literal                         [403]
[✓] Path Traversal - Mixed Encoding                              [403]
[✗] Path Traversal - Multiple Slashes                            [200]
[✓] RCE - Basic Command                                          [403]
[✓] RCE - Base64 Command                                         [403]
[✓] RCE - Backticks                                              [403]
[✓] RCE - List Files                                             [403]
[✓] RCE - Uname                                                  [403]
[✓] RCE - ID                                                     [403]
[✓] RCE - whoami Command                                         [403]
[✓] RCE - Echo Test                                              [403]
[✓] RCE - Hex Encoded Command                                    [403]
[✓] RCE - Curl Request                                           [403]
[✓] RCE - Wget Request                                           [403]
[✓] RCE - Ping                                                   [403]
[✓] RCE - PowerShell Command                                     [403]
[✗] Log4j - JNDI LDAP                                            [200]
[✗] Log4j - Environment                                          [200]
[✗] Log4j - JNDI RMI                                             [200]
[✗] Log4j - System Property                                      [200]
[✗] Log4j - Lowercase                                            [200]
[✗] Log4j - Uppercase                                            [200]
[✗] Log4j - Date                                                 [200]
[✓] Log4j - Base64                                               [403]
[✗] Log4j - Partial Lookup                                       [200]
[✗] Log4j - URL Encoded                                          [200]
[✓] Header - SQL Injection                                       [403]
[✓] Header - XSS Cookie                                          [403]
[✓] Header - Path Traversal                                      [403]
[✓] Header - Custom X-Attack                                     [403]
[✗] Header -  X-Forwarded-Host                                   [200]
[✓] Header - User-Agent SQL                                      [403]
[✗] Header -  Host Spoof                                         [200]
[✓] Header -  Accept-Language                                    [403]
[✓] Protocol - Git Access                                        [403]
[✓] Protocol - Env File                                          [403]
[✓] Protocol - htaccess                                          [403]
[✗] Protocol - Web.config Access                                 [200]
[✓] Protocol - Java Web Descriptor                               [403]
[✓] Protocol - SVN Access                                        [403]
[✗] Protocol - Robots.txt                                        [200]
[✗] Protocol - VS Code Settings                                  [200]
[✗] Protocol - config.php Access                                 [200]
[✗] Protocol - Apache Server Status                              [200]
[✓] Valid - Homepage                                             [200]
[✓] Valid - API Endpoint                                         [200]
[✓] Scanner - SQLMap                                             [403]
[✓] Scanner - Acunetix                                           [403]
[✓] Scanner - Nikto                                              [403]
[✓] Scanner - Nmap                                               [403]
[✓] Scanner - Dirbuster                                          [403]
[✓] Valid - Health Check                                         [200]
[✓] Valid - Chrome Browser                                       [200]
[✗] Scanner -  Burp Suite                                        [200]
[✓] Scanner - OWASP ZAP                                          [403]
[✓] Scanner - Nessus                                             [403]
[✓] Scanner - Qualys                                             [403]
[✗] Scanner -  Wfuzz                                             [200]
[✓] Scanner -  OpenVAS                                           [403]
----------------------------------------
Results Summary
Total Tests: 100
Passed: 63
Failed: 37
Pass Percentage: 63%

The script performs 100 tests for different attack vectors, and shows the result for each test.

🐳 Docker Support

A Dockerfile is included to simplify building a Docker image with the Caddy server and WAF middleware. Here’s how to use it:

# Build the Docker image
docker build -t caddy-waf .

# Run the Docker container
docker run -p 8080:8080 caddy-waf

The Dockerfile sets up the required environment, builds the Caddy server with the WAF middleware, and exposes port 8080.

🐍 Rule/Blacklist Population Scripts

Three Python scripts are provided in this repository to help automate the population of your rules and blacklists:

get_owasp_rules.py

This script fetches the OWASP core rules and converts them into the JSON format required for the WAF rules. You can use this script to automatically download and update your rules with the latest OWASP configurations.

python3 get_owasp_rules.py

get_blacklisted_ip.py

This script downloads the blacklisted IPs from several external sources. It consolidates the IPs into a single ip_blacklist.txt file, which can be used for blocking IPs.

python3 get_blacklisted_ip.py

get_blacklisted_dns.py

This script downloads blacklisted domains from various sources and consolidates them into the dns_blacklist.txt file.

python3 get_blacklisted_dns.py

These scripts provide a quick start and enable users to dynamically update their rules and blacklists using third-party sources.

📜 License

This project is licensed under the AGPLv3 License.

🙏 Contributing

Contributions are welcome! Please open an issue or submit a pull request.


Previous Post
Paperless-ngx: 社区支持的文档管理系统,扫描、索引并归档您的实体文档
Next Post
NewsNow: 优雅阅读实时热门新闻的平台