Skip to content

Commit a4f9212

Browse files
brdelphusclaude
andcommitted
fix: correct SecRuleEngine ordering in Caddyfile WAF snippet; docs for per-Ingress WAF rules
- _helpers.tpl: move SecRuleEngine after all CRS Includes (was incorrectly placed between @coraza.conf-recommended and @crs-setup/@owasp_crs) - README: add caddy.ingress/waf-rules-configmap annotation reference and per-Ingress WAF rules section with migration guide from nginx-ingress - CHANGELOG: add 1.0.1 entry documenting both WAF bug fixes - Chart.yaml: bump to 0.9.1 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 41ff786 commit a4f9212

4 files changed

Lines changed: 39 additions & 2 deletions

File tree

CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,16 @@
11
# Changelog
22

3+
## [1.0.1] - 2026-03-31
4+
5+
### Bug Fixes
6+
7+
- **WAF: OWASP CRS rules were never loaded**`wafHandler()` in caddy-k8s was missing the three mandatory `Include` directives (`@coraza.conf-recommended`, `@crs-setup.conf.example`, `@owasp_crs/*.conf`). `load_owasp_crs: true` only makes the virtual paths available; without the Includes, zero CRS rules were evaluated on any Ingress with `caddy.ingress/waf: on`.
8+
- **WAF: `SecRuleEngine` ordering fixed** — In both caddy-k8s and the Helm Caddyfile snippet, `SecRuleEngine` was placed before the CRS Includes. Since `@coraza.conf-recommended` resets it to `DetectionOnly`, our `On` override must come *after* all Includes.
9+
10+
### Helm chart: 0.9.1
11+
12+
---
13+
314
Versions track the `ingress-caddy` image. The Helm chart version is independent
415
but its `appVersion` always matches the image version.
516

README.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,7 @@ Per-Ingress behaviour is controlled via `caddy.ingress/` annotations on individu
264264
| `caddy.ingress/cors-max-age` | Preflight cache duration in seconds |
265265
| `caddy.ingress/limit-rps` | Max requests/second per client IP |
266266
| `caddy.ingress/waf: "off"\|"on"\|"detection"` | Per-route WAF override |
267+
| `caddy.ingress/waf-rules-configmap` | ConfigMap name (same namespace) containing custom Coraza directives for this Ingress. Auto-created with a commented template when `waf: on/detection` is first set. |
267268
| `caddy.ingress/whitelist-source-range` | CIDRs to allow; all others 403 |
268269
| `caddy.ingress/blocklist-source-range` | CIDRs to deny; all others pass |
269270
| `caddy.ingress/basic-auth-secret` | Secret with `auth` htpasswd key |
@@ -349,6 +350,31 @@ metadata:
349350
caddy.ingress/waf: "on"
350351
```
351352

353+
**Per-Ingress WAF rules (auto-created ConfigMap):**
354+
355+
When an Ingress is created with `caddy.ingress/waf: "on"` or `"detection"`, caddy-k8s automatically creates a ConfigMap named `<ingress-name>-waf-rules` in the same namespace and sets the `caddy.ingress/waf-rules-configmap` annotation on the Ingress. The ConfigMap is owned by the Ingress and will be garbage-collected when the Ingress is deleted.
356+
357+
Edit the ConfigMap to add per-Ingress Coraza directives:
358+
359+
```yaml
360+
# kubectl edit configmap myapp-waf-rules -n mynamespace
361+
apiVersion: v1
362+
kind: ConfigMap
363+
metadata:
364+
name: myapp-waf-rules
365+
namespace: mynamespace
366+
data:
367+
directives: |
368+
# Disable a false-positive rule for this app
369+
SecRuleRemoveById 920350
370+
# Restrict a rule to specific args only
371+
SecRuleUpdateTargetById 942100 "!ARGS:search"
372+
# Add a custom block rule
373+
SecRule ARGS "@contains badword" "id:1001,phase:2,deny,status:400"
374+
```
375+
376+
Directives are injected after the OWASP CRS Includes so `SecRuleRemoveById` and `SecRuleUpdateTargetById` work against already-loaded rules. The `SecRuleEngine` mode is always controlled by the `caddy.ingress/waf` annotation and cannot be overridden in the ConfigMap.
377+
352378
### CrowdSec
353379

354380
```yaml

helm/Chart.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ apiVersion: v2
22
name: caddy
33
description: Caddy ingress with WAF, TCP/UDP, CertMagic ACME (HTTP/TLS-ALPN/DNS/On-Demand), cert-manager CSI, CrowdSec, GeoIP, authentication/SSO, rate limiting and caching
44
type: application
5-
version: 0.9.0
5+
version: 0.9.1
66
appVersion: "1.0.0"
77
icon: https://caddyserver.com/resources/images/caddy-circle-lock.svg
88

helm/templates/_helpers.tpl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -336,12 +336,12 @@ Generate the Caddyfile content
336336
load_owasp_crs
337337
directives `
338338
Include @coraza.conf-recommended
339-
SecRuleEngine {{ .Values.plugins.coraza.ruleEngine }}
340339
Include @crs-setup.conf.example
341340
Include @owasp_crs/*.conf
342341
{{- range .Values.plugins.coraza.customRules }}
343342
{{ . }}
344343
{{- end }}
344+
SecRuleEngine {{ .Values.plugins.coraza.ruleEngine }}
345345
`
346346
}
347347
{{- end }}

0 commit comments

Comments
 (0)