From f629383a43db35590dabd847c8409983a66f1475 Mon Sep 17 00:00:00 2001 From: Simon Cornet Date: Tue, 14 Apr 2026 17:30:30 +0200 Subject: [PATCH] feat: add coraza as optional waf --- defaults/main.yaml | 1 + templates/traefik/config.yml.j2 | 56 +++++++++++++++++++++++++++++---- 2 files changed, 51 insertions(+), 6 deletions(-) diff --git a/defaults/main.yaml b/defaults/main.yaml index c325263..6a7e8e7 100644 --- a/defaults/main.yaml +++ b/defaults/main.yaml @@ -12,3 +12,4 @@ traefik_routes: host: "127.0.0.1" proto: "http" port: "80" + waf: false diff --git a/templates/traefik/config.yml.j2 b/templates/traefik/config.yml.j2 index 80a12e1..e9047cc 100644 --- a/templates/traefik/config.yml.j2 +++ b/templates/traefik/config.yml.j2 @@ -4,8 +4,8 @@ entryPoints: http: redirections: entryPoint: - to: websecure - scheme: https + to: "websecure" + scheme: "https" websecure: address: ":443" http: @@ -26,9 +26,17 @@ certificatesResolvers: storage: "/acme.json" caServer: "https://acme-v02.api.letsencrypt.org/directory" +{% if traefik_routes | selectattr('waf', 'equalto', true) | list | length > 0 %} +experimental: + plugins: + coraza: + moduleName: "github.com/jcchavezs/coraza-http-wasm-traefik" + version: "v0.3.0" +{% endif %} + providers: file: - filename: /traefik.yml + filename: "/traefik.yml" watch: true http: @@ -37,11 +45,47 @@ http: {{ item.service }}: rule: "Host(`{{ item.name }}`)" entryPoints: - - websecure - service: {{ item.service }}-svc + - "websecure" + service: "{{ item.service }}-svc" +{% if item.waf | default(false) %} + middlewares: + - "waf" +{% endif %} tls: - certResolver: transip + certResolver: "transip" {% endfor %} + +{% if traefik_routes | selectattr('waf', 'defined') | selectattr('waf') | list | length > 0 %} + middlewares: + waf: + plugin: + coraza: + directives: + - "SecRuleEngine On" + - "SecRequestBodyAccess Off" + - "SecResponseBodyAccess Off" + - "SecDefaultAction \"phase:1,log,auditlog,deny,status:403\"" + - "SecDefaultAction \"phase:2,log,auditlog,deny,status:403\"" + - "SecAction \"id:900000,phase:1,pass,nolog,setvar:tx.paranoia_level=1\"" + - "SecAction \"id:900110,phase:1,pass,nolog,setvar:tx.inbound_anomaly_score_threshold=5\"" + - "SecAction \"id:900200,phase:1,pass,nolog,setvar:tx.allowed_methods=GET POST PUT PATCH DELETE HEAD OPTIONS\"" + - "Include @owasp_crs/REQUEST-901-INITIALIZATION.conf" + - "Include @owasp_crs/REQUEST-905-COMMON-EXCEPTIONS.conf" + - "Include @owasp_crs/REQUEST-911-METHOD-ENFORCEMENT.conf" + - "Include @owasp_crs/REQUEST-913-SCANNER-DETECTION.conf" + - "Include @owasp_crs/REQUEST-920-PROTOCOL-ENFORCEMENT.conf" + - "Include @owasp_crs/REQUEST-921-PROTOCOL-ATTACK.conf" + - "Include @owasp_crs/REQUEST-930-APPLICATION-ATTACK-LFI.conf" + - "Include @owasp_crs/REQUEST-931-APPLICATION-ATTACK-RFI.conf" + - "Include @owasp_crs/REQUEST-932-APPLICATION-ATTACK-RCE.conf" + - "Include @owasp_crs/REQUEST-933-APPLICATION-ATTACK-PHP.conf" + - "Include @owasp_crs/REQUEST-941-APPLICATION-ATTACK-XSS.conf" + - "Include @owasp_crs/REQUEST-942-APPLICATION-ATTACK-SQLI.conf" + - "Include @owasp_crs/REQUEST-943-APPLICATION-ATTACK-SESSION-FIXATION.conf" + - "Include @owasp_crs/REQUEST-944-APPLICATION-ATTACK-JAVA.conf" + - "Include @owasp_crs/REQUEST-949-BLOCKING-EVALUATION.conf" + +{% endif %} services: {% for item in traefik_routes %} {{ item.service }}-svc: