### Run Example Deployment Locally Source: https://github.com/corazawaf/coraza-caddy/blob/main/README.md Steps to run the example deployment locally, involving starting a go-httpbin server, building the Caddy binary with the plugin, and running Caddy. ```shell # in terminal 1 go run github.com/mccutchen/go-httpbin/v2/cmd/go-httpbin@v2.9.0 -port 8081 # in terminal 2 go run mage.go buildCaddy ./build/caddy run --config example/Caddyfile --adapter caddyfile # in terminal 3 curl -i localhost:8080/ ``` -------------------------------- ### Run Example Deployment with Docker Source: https://github.com/corazawaf/coraza-caddy/blob/main/README.md Commands to build and run the example deployment using Docker, followed by a curl request to test. ```bash go run mage.go buildExample runExample curl -i localhost:8080/ ``` -------------------------------- ### Build Caddy with Coraza WAF using xcaddy Source: https://context7.com/corazawaf/coraza-caddy/llms.txt Installs `xcaddy` and then builds a Caddy binary that includes the Coraza WAF module. This is the standard method for creating a custom Caddy executable with WAF capabilities. ```bash # Install xcaddy go install github.com/caddyserver/xcaddy/cmd/xcaddy@latest # Build a Caddy binary with Coraza WAF xcaddy build --with github.com/corazawaf/coraza-caddy/v2 # Run with a Caddyfile ./caddy run --config /etc/caddy/Caddyfile --adapter caddyfile # Force reload after modifying external rule files (bypass config diffing) ./caddy reload --force ``` -------------------------------- ### Advanced Coraza WAF Caddyfile Configuration with Directives Source: https://github.com/corazawaf/coraza-caddy/blob/main/README.md Example Caddyfile configuration for Coraza WAF, including multiple directives and rule inclusions. Ensure 'order coraza_waf first' is present. ```caddy { order coraza_waf first } http://127.0.0.1:8080 { coraza_waf { directives ` SecAction "id:1,pass,log" SecRule REQUEST_URI "/test5" "id:2, deny, log, phase:1" SecRule REQUEST_URI "/test6" "id:4, deny, log, phase:3" Include file1.conf Include file2.conf Include /some/path/*.conf ` } reverse_proxy http://192.168.1.15:8080 } ``` -------------------------------- ### Docker Compose Commands for FTW Environment Source: https://context7.com/corazawaf/coraza-caddy/llms.txt Provides Docker Compose commands to build and start the FTW environment for running OWASP CRS regression tests. It also includes commands to execute all CRS tests or a specific test ID using `go-ftw`. ```bash # Build and start the FTW environment docker compose -f ftw/docker-compose.yml up --build -d # Run all CRS tests docker compose -f ftw/docker-compose.yml exec ftw \ go-ftw run --include ".*" --exclude "" # Run a specific CRS test ID docker compose -f ftw/docker-compose.yml exec ftw \ go-ftw run --include "941100" ``` -------------------------------- ### Mage Build Targets for Developer Workflow Source: https://context7.com/corazawaf/coraza-caddy/llms.txt Provides a list of common Mage build targets for the Coraza Caddy project, including building the Caddy binary, running tests, setting up the example environment, and executing end-to-end or regression tests. ```bash # List all available targets go run mage.go -l # Build Caddy binary with Coraza plugin into ./build/caddy go run mage.go buildCaddy # Run unit tests go run mage.go test # Run tests with coverage and race detector go run mage.go coverage # Spin up Docker example environment (access at http://localhost:8080) go run mage.go buildExample runExample # Run end-to-end tests against the running example go run mage.go e2e # Run OWASP CRS regression tests (go-ftw) go run mage.go ftw # Lint go run mage.go lint ``` -------------------------------- ### WAF Instance Pooling with corazaModule Source: https://context7.com/corazawaf/coraza-caddy/llms.txt Demonstrates how identical Coraza WAF configurations result in shared WAF instances, improving performance by avoiding redundant rule compilation. Different configurations generate unique keys, leading to new WAF instances. ```go // Two modules with the same config share a single WAF: m1 := &corazaModule{Directives: "SecRuleEngine On"} m2 := &corazaModule{Directives: "SecRuleEngine On"} // m1.computePoolKey() == m2.computePoolKey() → WAF reused // Different config produces a different key: m3 := &corazaModule{Directives: "SecRuleEngine On", LoadOWASPCRS: true} // m1.computePoolKey() != m3.computePoolKey() → new WAF built ``` -------------------------------- ### Build Caddy Plugin with Coraza WAF Source: https://github.com/corazawaf/coraza-caddy/blob/main/README.md Command to build the Caddy binary with the Coraza WAF plugin integrated. This command uses xcaddy. ```shell xcaddy build --with github.com/corazawaf/coraza-caddy/v2 ``` -------------------------------- ### Enable OWASP Core Rule Set with load_owasp_crs Source: https://context7.com/corazawaf/coraza-caddy/llms.txt Use the `load_owasp_crs` sub-directive to mount the bundled `coraza-coreruleset` filesystem, making CRS virtual paths resolvable. Combine with `Include` directives for rule loading and configure response body access and MIME types. ```caddyfile { order coraza_waf first } :8080 { coraza_waf { load_owasp_crs directives ` Include @coraza.conf-recommended Include @crs-setup.conf.example Include @owasp_crs/*.conf SecRuleEngine On SecRequestBodyAccess On SecResponseBodyAccess On SecResponseBodyMimeType text/html application/json SecDefaultAction "phase:3,log,auditlog,pass" SecDefaultAction "phase:4,log,auditlog,pass" ` } reverse_proxy httpbin:8081 } ``` -------------------------------- ### List Available Mage Commands Source: https://github.com/corazawaf/coraza-caddy/blob/main/README.md Lists all available commands for the mage build tool. Use this to see available development and testing tasks. ```bash ▶ go run mage.go -l Targets: buildCaddy builds the plugin. buildCaddyLinux builds the plugin with GOOS=linux. buildExample builds the example deployment. check runs lint and tests. coverage runs tests with coverage and race detector enabled. doc runs godoc, access at http://localhost:6060 e2e runs e2e tests with a built plugin against the example deployment. format formats code in this repository. ftw runs CRS regressions tests. lint verifies code quality. precommit installs a git hook to run check when committing reloadExample reload the test environment. runExample spins up the test environment, access at http://localhost:8080. teardownExample tears down the test environment. test runs all tests. ``` -------------------------------- ### Basic Inline Rules with coraza_waf Caddyfile Directive Source: https://context7.com/corazawaf/coraza-caddy/llms.txt Use the `coraza_waf` directive for basic inline SecLang rules. Ensure it is ordered first in the global options block. Rules are provided as a backtick-delimited multiline string to the `directives` sub-directive. ```caddyfile { order coraza_waf first } http://127.0.0.1:8080 { coraza_waf { directives ` SecRuleEngine On SecAction "id:1,pass,log,msg:'Coraza is active'" SecRule REQUEST_URI "/admin" "id:2,phase:1,deny,status:403,log,msg:'Admin access blocked'" SecRule REQUEST_URI "/test5" "id:3,phase:1,deny,status:403,log" SecRule REQUEST_URI "/test6" "id:4,phase:3,deny,status:403,log" SecRule REMOTE_ADDR "@ipMatch 192.168.1.100" "id:5,phase:1,deny,status:403,log,msg:'Blocked IP'" ` } reverse_proxy http://backend:8080 } ``` -------------------------------- ### Basic Coraza WAF Caddyfile Configuration Source: https://github.com/corazawaf/coraza-caddy/blob/main/README.md Basic configuration for the Coraza WAF module in a Caddyfile. Requires 'order coraza_waf first' to be set globally. ```caddy coraza_waf { directives ` Include /path/to/config.conf SecAction "id:1,pass,log" ` } ``` -------------------------------- ### Include External Rule Files with `Include` Directive Source: https://context7.com/corazawaf/coraza-caddy/llms.txt Manage large rule sets by splitting them into `.conf` files and loading them using the `Include` directive within `directives`. Glob patterns are supported for flexible file selection. ```caddyfile { order coraza_waf first } :8080 { coraza_waf { directives ` SecRuleEngine On Include /etc/coraza/rules/base.conf Include /etc/coraza/rules/custom/*.conf ` } reverse_proxy http://app:3000 } ``` ```bash # /etc/coraza/rules/custom/block-scanners.conf SecRule REQUEST_HEADERS:User-Agent "@pm grabber masscan nikto" \ "id:9131,phase:1,t:none,log,deny,status:403,msg:'Scanner detected'" # /etc/coraza/rules/custom/block-sqli.conf SecRule ARGS_NAMES|ARGS "@detectSQLi" \ "id:9421,phase:2,t:none,t:utf8toUnicode,t:urlDecodeUni,t:removeNulls,multiMatch,log,deny,status:403" ``` -------------------------------- ### Run Coraza WAF Test Suite Source: https://github.com/corazawaf/coraza-caddy/blob/main/README.md Executes the test suite for the Coraza WAF Caddy module using the mage build tool. ```shell go run mage.go test ``` -------------------------------- ### Load OWASP Core Ruleset with Coraza WAF Source: https://github.com/corazawaf/coraza-caddy/blob/main/README.md Caddyfile configuration to load the OWASP Core Ruleset (CRS) with the Coraza WAF module. Includes recommended CRS configurations. ```caddy :8080 { coraza_waf { load_owasp_crs directives ` Include @coraza.conf-recommended Include @crs-setup.conf.example Include @owasp_crs/*.conf SecRuleEngine On ` } reverse_proxy httpbin:8081 } ``` -------------------------------- ### Shared WAF Instance Across Virtual Hosts in Caddyfile Source: https://context7.com/corazawaf/coraza-caddy/llms.txt Configures two virtual hosts on different ports to use the same Coraza WAF instance by applying the `coraza_waf` directive within their respective blocks. This ensures that the WAF rules are compiled only once for both sites. ```caddy { order coraza_waf first } :8080 { coraza_waf { directives `SecRuleEngine On` } respond "site-a" } :8081 { coraza_waf { directives `SecRuleEngine On` } respond "site-b" } ``` -------------------------------- ### Handle Specific Error Codes with HTML Pages Source: https://github.com/corazawaf/coraza-caddy/blob/main/README.md Uses 'handle_errors' with a matcher to serve specific HTML error pages based on the blocked status code. Requires corresponding HTML files in the root directory. ```caddy handle_errors { @block_codes `{err.status_code} in [403]` handle @block_codes { root * /path/to/html/dir rewrite * /{err.status_code}.html file_server } } ``` -------------------------------- ### Include WAF Directives in Caddyfile Source: https://github.com/corazawaf/coraza-caddy/blob/main/TROUBLESHOOTING.md Use this syntax to include external WAF configuration files within your Caddyfile. Modifying the content of the included file will not trigger a Caddy reload. ```caddy coraza_waf { directives ` Include /path/to/config.conf ` } ``` -------------------------------- ### HTTP Middleware Handler with corazaModule.ServeHTTP Source: https://context7.com/corazawaf/coraza-caddy/llms.txt The `corazaModule.ServeHTTP` function acts as the core middleware. It processes requests through all phases, wraps the response writer for inspection, and handles interruptions by returning `caddyhttp.HandlerError`. The WAF transaction ID is exposed as `{http.transaction_id}`. ```caddyfile { order coraza_waf first } :8080 { coraza_waf { directives ` SecRuleEngine On SecRule REQUEST_URI "/test5" "id:2,phase:1,deny,status:403,log" ` } # Expose the WAF transaction ID as a response header header * X-Request-ID "{http.transaction_id}" respond "OK" } ``` ```bash # Normal request — passes through curl -i http://localhost:8080/hello # HTTP/1.1 200 OK # X-Request-ID: aBcDeFgHiJkLmNoP # Blocked request — rule id:2 triggers curl -i http://localhost:8080/test5 # HTTP/1.1 403 Forbidden # X-Request-ID: qRsTuVwXyZaBcDeF ``` -------------------------------- ### Custom Error Pages with `handle_errors` Source: https://context7.com/corazawaf/coraza-caddy/llms.txt Demonstrates how to use Caddy's `handle_errors` directive to serve custom responses when the WAF triggers an error. It intercepts `caddyhttp.HandlerError` and allows for dynamic responses using placeholders like `{http.transaction_id}`. ```caddy { order coraza_waf first } :8080 { coraza_waf { directives ` SecRuleEngine On SecRule REQUEST_URI "/admin" "id:10,phase:1,deny,status:403,log" ` } handle_errors 403 { header X-Blocked "true" respond "Access denied. Reference: {http.transaction_id}" 403 } # Or serve a static HTML page: # handle_errors { # @block `{err.status_code} in [403]` # handle @block { # root * /var/www/errors # rewrite * /{err.status_code}.html # file_server # } # } reverse_proxy http://app:3000 } ``` ```bash curl -i http://localhost:8080/admin # HTTP/1.1 403 Forbidden # X-Blocked: true # # Access denied. Reference: aBcDeFgHiJkLmNoP ``` -------------------------------- ### FTW Configuration for OWASP CRS Regression Tests Source: https://context7.com/corazawaf/coraza-caddy/llms.txt Defines the `ftw.yml` configuration for the Framework for Testing WAFs (FTW) to run OWASP Core Rule Set (CRS) regression tests against the Coraza-Caddy integration. It specifies log file paths, log markers, and the log format for Caddy. ```yaml # ftw/ftw.yml --- logfile: /home/caddy/logs/ftw.log logmarkerheadername: X-CRS-Test logtype: name: "caddy" timeformat: "02/Jan/2006:15:04:05 Z0700" # Caddy console log pattern: # 2006/01/02 15:04:05.000 [severity] [module] message ``` -------------------------------- ### Response Body Inspection with `SecResponseBodyAccess` Source: https://context7.com/corazawaf/coraza-caddy/llms.txt Configures Caddy to inspect response bodies for sensitive information using `SecResponseBodyAccess`. It buffers response bytes up to `SecResponseBodyLimit` and runs `ProcessResponseBody` (phase 4) before flushing. `SecResponseBodyLimitAction` can be set to `Reject` or `ProcessPartial`. ```caddy { order coraza_waf first auto_https off } :8080 { coraza_waf { directives ` SecRuleEngine On SecResponseBodyAccess On SecResponseBodyMimeType text/plain application/json SecResponseBodyLimit 524288 SecResponseBodyLimitAction ProcessPartial SecRule RESPONSE_BODY "@rx SQL Error|stack trace|password" "id:100,phase:4,deny,status:403,log,msg:'Data leak detected in response'" ` } reverse_proxy http://backend:8080 } ``` ```bash # Response containing "SQL Error" will be blocked: curl -i http://localhost:8080/api/data # HTTP/1.1 403 Forbidden # Clean response passes through: curl -i http://localhost:8080/api/health # HTTP/1.1 200 OK # {"status":"ok"} ``` -------------------------------- ### Mapping Rule Severity to Zap Log Levels in Caddyfile Source: https://context7.com/corazawaf/coraza-caddy/llms.txt Registers a Coraza error callback to map ModSecurity rule severities to Zap log levels. This configuration ensures that different rule severities are logged appropriately within the Caddy console output. Rules without explicit severity fall back to `zap.Warn`. ```caddy { order coraza_waf first log { output stdout format console level warn include "http.handlers.waf" } } :8080 { coraza_waf { directives ` SecRuleEngine On # severity:2 (Critical) → logged at ERROR level SecRule REQUEST_URI "/critical-path" \ "id:201,phase:1,pass,log,severity:2,msg:'Critical path accessed'" # severity:4 (Warning) → logged at WARN level SecRule ARGS "@rx