Baike.dev
All toolsAI codingTrendingOpen sourceNewsSubmit
Log in
< Back to tools
C

caddy-waf

> 安全
Open source

Caddy WAF (Regex Rules, IP and DNS filtering, Rate Limiting, GeoIP, Tor, Anomaly Detection)

794 stars0 likes0 views
WebsiteGitHub

About

Caddy WAF (Regex Rules, IP and DNS filtering, Rate Limiting, GeoIP, Tor, Anomaly Detection)

Caddy WAF

A Web Application Firewall middleware for the Caddy web server, written in Go.

  • Module ID: http.handlers.waf — registered in Caddy's package registry, so the module is selectable on the download page
  • Go module path: github.com/fabriziosalmi/caddy-waf
  • Current version: v0.4.14 (see caddywaf.go — const wafVersion)
  • License: AGPL-3.0 — note this is a copyleft licence; check it suits your deployment before integrating

Overview

caddy-waf is an HTTP handler middleware that inspects requests and responses across four well-defined phases, applies a regular-expression rule set with anomaly scoring, enforces IP/DNS/ASN/country blacklists and whitelists, performs token-bucket-style rate limiting, and exposes a JSON metrics endpoint.

The middleware is implemented as a single Caddy module registered under the ID http.handlers.waf. It can be configured through the Caddyfile or directly via JSON.

Capabilities

Capability Implementation
Regex rule engine Go regexp package (RE2, linear-time guarantee). Compiled patterns are cached per rule ID.
Multi-phase inspection Phase 1 (request headers and pre-request checks), Phase 2 (request body), Phase 3 (response headers), Phase 4 (response body).
Anomaly scoring Each rule contributes its score to a per-request total; requests are blocked when the total reaches anomaly_threshold.
Explicit actions Rule mode of block or log. block short-circuits the request; log records the match and continues.
IP blacklist Plain IPs and CIDR ranges (IPv4 and IPv6) stored in a prefix trie (go-iptrie).
DNS blacklist Exact-match (case-insensitive) host lookup.
GeoIP country block / whitelist MaxMind GeoLite2 Country MMDB.
ASN block MaxMind GeoLite2 ASN MMDB.
Tor exit-node block Periodic fetch from https://check.torproject.org/torbulkexitlist.
Rate limiting Per-IP, sliding-window, optional per-path matching with regex patterns.
Custom block responses Per-status-code response with custom Content-Type, headers, and body (inline or from file).
Sensitive data redaction Optional redaction of sensitive query parameters and log fields.
Hot reload fsnotify watchers on rule files, IP blacklist, and DNS blacklist.
Metrics endpoint JSON document exposed at the configured metrics_endpoint path.
Asynchronous logging Buffered log channel with synchronous fallback when the buffer is full.

Engineering notes

  • Linear-time regex: rules are compiled by Go's regexp (RE2). No catastrophic backtracking.
  • Wait-free counters: per-rule hit counts use atomic.Int64 stored in a sync.Map.
  • Bounded body reads: request bodies are read through io.LimitReader (max_request_body_size, default 10 MiB) and restored with io.MultiReader so downstream handlers still see the full body.
  • Bounded response buffering: the response body is only held in memory when a Phase 4 rule exists to inspect it, and never past max_response_body_size (default 10 MiB). Beyond that — or as soon as the upstream flushes — the WAF releases what it holds and streams the rest, so memory never scales with the response size.
  • Zero-copy body string: the body is exposed to rule matching via unsafe.String to avoid an allocation per request.
  • Circuit breaker for GeoIP: geoip_fail_open controls whether a GeoIP lookup failure blocks the request or allows it through.
  • Panic recovery: ServeHTTP installs a deferred recovery that returns 500 Internal Server Error on panic.

Quick start

The fastest path to a working build:

curl -fsSL -H "Pragma: no-cache" \
  https://raw.githubusercontent.com/fabriziosalmi/caddy-waf/refs/heads/main/install.sh | bash

The script ensures Go and xcaddy are installed, clones the repository, downloads the GeoLite2 database, builds Caddy with the caddy-waf module, and starts the server.

A representative provisioning log:

…

Installation

Requirements

  • Go 1.25.1 or newer (go.mod declares go 1.25.1, propagated from caddy/v2 which requires it)
  • Caddy v2.11.x or newer (current build uses github.com/caddyserver/caddy/v2 v2.11.4)
  • xcaddy for building Caddy with plugins

Method 1 — Build with xcaddy (recommended)

go install github.com/caddyserver/xcaddy/cmd/xcaddy@latest
xcaddy build --with github.com/fabriziosalmi/caddy-waf
./caddy list-modules | grep waf   # expect: http.handlers.waf

Method 2 — Quick script

curl -fsSL -H "Pragma: no-cache" \
  https://raw.githubusercontent.com/fabriziosalmi/caddy-waf/refs/heads/main/install.sh | bash

Method 3 — Build from source

git clone https://github.com/fabriziosalmi/caddy-waf.git
cd caddy-waf
go mod tidy
wget https://git.io/GeoLite2-Country.mmdb           # optional, only for GeoIP
xcaddy build --with github.com/fabriziosalmi/caddy-waf=./
./caddy fmt --overwrite
./caddy run

Method 4 — caddy add-package

[!IMPORTANT] Prefer xcaddy or the container image. Caddy's maintainers have proposed moving add-package, remove-package and upgrade out of Caddy's core to discourage their use (caddyserver/caddy#7010): the commands call Caddy's shared build server, and using them in CI/CD is an anti-pattern. Raised for this project in #138 by a Caddy maintainer.

The command works today and the module remains registered, so this section stays accurate. Treat it as a convenience for one-off, hand-operated installs — not as the way to build or deploy caddy-waf.

The module is registered in Caddy's package registry, so an existing Caddy v2.7+ binary can pull it in without a Go toolchain:

caddy add-package github.com/fabriziosalmi/caddy-waf
caddy list-modules | grep waf   # expect: http.handlers.waf

It is also selectable on caddyserver.com/download. See docs/add-package-guide.md for version pinning, removal, and when to prefer xcaddy instead.

Method 5 — Docker

Images are published to GitHub Container Registry on every release tag, for linux/amd64 and linux/arm64:

docker pull ghcr.io/fabriziosalmi/caddy-waf:0.4.14
docker run --rm -p 8080:8080 ghcr.io/fabriziosalmi/caddy-waf:0.4.14

Tags are 0.4.14, 0.4 and latest — note there is no v prefix, unlike the Go module version. Pin an exact version in anything you deploy. See docs/docker.md for volumes, Compose, and hot reload.


Minimal Caddyfile

…

A fully annotated example is provided in Caddyfile and caddyfile.example.


Documentation

fabriziosalmi.github.io/caddy-waf — the same pages as below, with full-text search and cross-linking. The Markdown under docs/ remains the source and stays readable on GitHub.

Document Topic
docs/introduction.md What the middleware does and where it sits in the request pipeline.
docs/installation.md All installation methods.
docs/configuration.md Caddyfile and JSON directives, request lifecycle, blocking precedence.
docs/rules.md rules.json schema, target identifiers, regex semantics.
docs/blacklists.md IP and DNS blacklist file formats.
docs/ratelimit.md Rate-limit block, path matching, behavior.
docs/geoblocking.md Country block / whitelist, ASN block, fallback behavior.
docs/attacks.md Attack categories addressed by the bundled rule sets.
docs/dynamicupdates.md File watchers, reload semantics, scope of each reload.
docs/metrics.md /waf_metrics JSON schema.
docs/prometheus.md Bridging the JSON metrics to Prometheus and Grafana.
docs/caddy-waf-elk.md Shipping logs to an ELK stack with Filebeat.
docs/scripts.md Helper Python scripts for rule and blacklist generation.
docs/testing.md Running the bundled test.py suite.
docs/docker.md Building and running with Docker / Docker Compose.
docs/add-package-guide.md Installing with caddy add-package.
docs/caddytest.md The caddytest.py traffic-generation tool.

Project layout

…

Testing

make test            # go test -v ./...
make it              # go test -v ./... -tags=it (integration)
make lint            # golangci-lint run
make test-integration # runs test.py inside a python:3.9-slim container

The repository also ships Python suites covering offensive payloads (test.py), traffic generation (caddytest.py), and benchmarking (benchmark.py). See docs/testing.md and docs/caddytest.md.


Commercial support & consulting

Running caddy-waf in production? I offer paid support, custom rule development, and security consulting — WAF tuning, hardening, TLS automation, and cloud detection & alerting. Reach out: [email protected].

Contributing

Pull requests are welcome. The project values:

  1. Tests that exercise the change.
  2. Rule contributions placed under rules/ using the documented JSON schema.
  3. Documentation kept in sync with code (every directive change must be reflected in docs/configuration.md and the relevant topic page).

See CONTRIBUTING.md for the workflow and CODE_OF_CONDUCT.md.

Security

Please do not open a public issue for a vulnerability. Use private vulnerability reporting — it is enabled on this repository, so it works for anyone without special permissions — or email [email protected]. Full policy in SECURITY.md.

Only the latest release receives security fixes; there are no backport branches. Published advisories are listed under Security → Advisories.

Upgrade note: v0.3.3 and earlier are affected by GHSA-gfj3-cmff-q8wh, a high-severity unauthenticated denial of service (unbounded response buffering, CVSS 7.5). Fixed in v0.3.4.

License

AGPL-3.0. See LICENSE.

Issues· 5 open

View all issuesOpen on GitHub

No open issues yet, or sync has not completed.

> Tags

Gocaddycaddy-modulecaddy-plugincaddy-security

No comments yet. Be the first to share.

> Details

PublishedAug 1, 2026
UpdatedSep 17, 2026
Category安全
PricingOpen source

> Related tools

O
OWASP ZAP
开源 Web 应用安全扫描器
O
owasp-wstg-tracker
Simple web app to track OWASP WSTG security testing progress
H
homebridge-mi-gateway-security
XiaoMi Gateway Security plugin for HomeBridge.