Files
haproxy-manager-base/templates/hap_coraza_spoe_engine.tpl

55 lines
2.5 KiB
Smarty
Raw Normal View History

PR 2/3: opt-in SPOE integration for Coraza WAF Adds the plumbing that lets haproxy-manager talk to the coraza-spoa sidecar added in PR 1, while keeping the default behavior bit-identical for any deployment that doesn't set the new env var (the home network / standalone use cases). Single gate: HAPROXY_CORAZA_SPOE_BACKEND env var on the haproxy-manager container. Unset (default) = generate_config() renders zero SPOE-related output. Set (e.g. "coraza-spoa:9000") = three things happen at config generation time: 1. hap_listener.tpl injects 5 lines at the end of the frontend block: filter spoe engine coraza config /etc/haproxy/coraza-spoe.cfg http-request send-spoe-group coraza coraza-check ...placed AFTER rate-limit and IP-block guards so we don't waste WAF calls on requests we were going to drop anyway. 2. A new TCP backend (hap_coraza_spoa_backend.tpl) is appended: backend coraza-spoa-backend mode tcp server coraza-spoa <env-var-target> check ... 3. The SPOE engine config (hap_coraza_spoe_engine.tpl) is rendered and written to /etc/haproxy/coraza-spoe.cfg, defining the spoe-agent "coraza" + spoe-message "coraza-check". This sets: - option set-on-error continue (FAIL-OPEN if SPOA is unreachable) - timeout processing 100ms (per-request inspection budget) - app=str(haproxy) (matches sidecar's application name) Verification (template render only, before staging deploy): - hap_listener.tpl with no env var: 55 lines, zero SPOE references - hap_listener.tpl with env var: 62 lines, filter + send-spoe-group present - Engine cfg + backend block render with correct agent_target substitution Next: PR 3 wires this into WHP (sidecar deploy via container-manager.sh extension, server-settings UI for on/off, AI Monitor source for the audit log). Staging verification of PR 1 + PR 2 together happens after PR 3. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 16:49:29 -07:00
# Coraza SPOE engine configuration.
#
# Written to /etc/haproxy/coraza-spoe.cfg by haproxy_manager.generate_config()
# when HAPROXY_CORAZA_SPOE_BACKEND env var is set. Referenced from haproxy.cfg
# via `filter spoe engine coraza config /etc/haproxy/coraza-spoe.cfg`.
#
# Engine name "coraza" must match the engine name in the filter line in the
# main config; group name "coraza-req" must match the send-spoe-group action.
# Application name "haproxy" must match the application block in coraza-spoa's
# config.yaml.
#
# Reference: this config follows the shape from coraza-spoa's upstream
# example/haproxy/coraza.cfg (v0.7.1). Arg names + ordering are required by
# Coraza-SPOA exactly as specified — DO NOT reorder or rename without
# coordinating with the agent.
PR 2/3: opt-in SPOE integration for Coraza WAF Adds the plumbing that lets haproxy-manager talk to the coraza-spoa sidecar added in PR 1, while keeping the default behavior bit-identical for any deployment that doesn't set the new env var (the home network / standalone use cases). Single gate: HAPROXY_CORAZA_SPOE_BACKEND env var on the haproxy-manager container. Unset (default) = generate_config() renders zero SPOE-related output. Set (e.g. "coraza-spoa:9000") = three things happen at config generation time: 1. hap_listener.tpl injects 5 lines at the end of the frontend block: filter spoe engine coraza config /etc/haproxy/coraza-spoe.cfg http-request send-spoe-group coraza coraza-check ...placed AFTER rate-limit and IP-block guards so we don't waste WAF calls on requests we were going to drop anyway. 2. A new TCP backend (hap_coraza_spoa_backend.tpl) is appended: backend coraza-spoa-backend mode tcp server coraza-spoa <env-var-target> check ... 3. The SPOE engine config (hap_coraza_spoe_engine.tpl) is rendered and written to /etc/haproxy/coraza-spoe.cfg, defining the spoe-agent "coraza" + spoe-message "coraza-check". This sets: - option set-on-error continue (FAIL-OPEN if SPOA is unreachable) - timeout processing 100ms (per-request inspection budget) - app=str(haproxy) (matches sidecar's application name) Verification (template render only, before staging deploy): - hap_listener.tpl with no env var: 55 lines, zero SPOE references - hap_listener.tpl with env var: 62 lines, filter + send-spoe-group present - Engine cfg + backend block render with correct agent_target substitution Next: PR 3 wires this into WHP (sidecar deploy via container-manager.sh extension, server-settings UI for on/off, AI Monitor source for the audit log). Staging verification of PR 1 + PR 2 together happens after PR 3. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 16:49:29 -07:00
[coraza]
spoe-agent coraza
# `groups` (not `messages`) lists the spoe-group names this engine offers
# via `send-spoe-group` actions. The same group name appears below in a
# spoe-group block, which in turn references the actual message.
groups coraza-req
PR 2/3: opt-in SPOE integration for Coraza WAF Adds the plumbing that lets haproxy-manager talk to the coraza-spoa sidecar added in PR 1, while keeping the default behavior bit-identical for any deployment that doesn't set the new env var (the home network / standalone use cases). Single gate: HAPROXY_CORAZA_SPOE_BACKEND env var on the haproxy-manager container. Unset (default) = generate_config() renders zero SPOE-related output. Set (e.g. "coraza-spoa:9000") = three things happen at config generation time: 1. hap_listener.tpl injects 5 lines at the end of the frontend block: filter spoe engine coraza config /etc/haproxy/coraza-spoe.cfg http-request send-spoe-group coraza coraza-check ...placed AFTER rate-limit and IP-block guards so we don't waste WAF calls on requests we were going to drop anyway. 2. A new TCP backend (hap_coraza_spoa_backend.tpl) is appended: backend coraza-spoa-backend mode tcp server coraza-spoa <env-var-target> check ... 3. The SPOE engine config (hap_coraza_spoe_engine.tpl) is rendered and written to /etc/haproxy/coraza-spoe.cfg, defining the spoe-agent "coraza" + spoe-message "coraza-check". This sets: - option set-on-error continue (FAIL-OPEN if SPOA is unreachable) - timeout processing 100ms (per-request inspection budget) - app=str(haproxy) (matches sidecar's application name) Verification (template render only, before staging deploy): - hap_listener.tpl with no env var: 55 lines, zero SPOE references - hap_listener.tpl with env var: 62 lines, filter + send-spoe-group present - Engine cfg + backend block render with correct agent_target substitution Next: PR 3 wires this into WHP (sidecar deploy via container-manager.sh extension, server-settings UI for on/off, AI Monitor source for the audit log). Staging verification of PR 1 + PR 2 together happens after PR 3. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 16:49:29 -07:00
# Prefix for variables the agent sets back on the request transaction —
# e.g. var(txn.coraza.error) when set-on-error triggers.
PR 2/3: opt-in SPOE integration for Coraza WAF Adds the plumbing that lets haproxy-manager talk to the coraza-spoa sidecar added in PR 1, while keeping the default behavior bit-identical for any deployment that doesn't set the new env var (the home network / standalone use cases). Single gate: HAPROXY_CORAZA_SPOE_BACKEND env var on the haproxy-manager container. Unset (default) = generate_config() renders zero SPOE-related output. Set (e.g. "coraza-spoa:9000") = three things happen at config generation time: 1. hap_listener.tpl injects 5 lines at the end of the frontend block: filter spoe engine coraza config /etc/haproxy/coraza-spoe.cfg http-request send-spoe-group coraza coraza-check ...placed AFTER rate-limit and IP-block guards so we don't waste WAF calls on requests we were going to drop anyway. 2. A new TCP backend (hap_coraza_spoa_backend.tpl) is appended: backend coraza-spoa-backend mode tcp server coraza-spoa <env-var-target> check ... 3. The SPOE engine config (hap_coraza_spoe_engine.tpl) is rendered and written to /etc/haproxy/coraza-spoe.cfg, defining the spoe-agent "coraza" + spoe-message "coraza-check". This sets: - option set-on-error continue (FAIL-OPEN if SPOA is unreachable) - timeout processing 100ms (per-request inspection budget) - app=str(haproxy) (matches sidecar's application name) Verification (template render only, before staging deploy): - hap_listener.tpl with no env var: 55 lines, zero SPOE references - hap_listener.tpl with env var: 62 lines, filter + send-spoe-group present - Engine cfg + backend block render with correct agent_target substitution Next: PR 3 wires this into WHP (sidecar deploy via container-manager.sh extension, server-settings UI for on/off, AI Monitor source for the audit log). Staging verification of PR 1 + PR 2 together happens after PR 3. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 16:49:29 -07:00
option var-prefix coraza
# On agent error/timeout, set var(txn.coraza.error). We DON'T add a
# corresponding `http-request deny if { var(txn.coraza.error) -m bool }`
# in the frontend, so the request continues uninspected. This is the
# fail-open posture: WAF outage shouldn't 503 customer traffic.
option set-on-error error
PR 2/3: opt-in SPOE integration for Coraza WAF Adds the plumbing that lets haproxy-manager talk to the coraza-spoa sidecar added in PR 1, while keeping the default behavior bit-identical for any deployment that doesn't set the new env var (the home network / standalone use cases). Single gate: HAPROXY_CORAZA_SPOE_BACKEND env var on the haproxy-manager container. Unset (default) = generate_config() renders zero SPOE-related output. Set (e.g. "coraza-spoa:9000") = three things happen at config generation time: 1. hap_listener.tpl injects 5 lines at the end of the frontend block: filter spoe engine coraza config /etc/haproxy/coraza-spoe.cfg http-request send-spoe-group coraza coraza-check ...placed AFTER rate-limit and IP-block guards so we don't waste WAF calls on requests we were going to drop anyway. 2. A new TCP backend (hap_coraza_spoa_backend.tpl) is appended: backend coraza-spoa-backend mode tcp server coraza-spoa <env-var-target> check ... 3. The SPOE engine config (hap_coraza_spoe_engine.tpl) is rendered and written to /etc/haproxy/coraza-spoe.cfg, defining the spoe-agent "coraza" + spoe-message "coraza-check". This sets: - option set-on-error continue (FAIL-OPEN if SPOA is unreachable) - timeout processing 100ms (per-request inspection budget) - app=str(haproxy) (matches sidecar's application name) Verification (template render only, before staging deploy): - hap_listener.tpl with no env var: 55 lines, zero SPOE references - hap_listener.tpl with env var: 62 lines, filter + send-spoe-group present - Engine cfg + backend block render with correct agent_target substitution Next: PR 3 wires this into WHP (sidecar deploy via container-manager.sh extension, server-settings UI for on/off, AI Monitor source for the audit log). Staging verification of PR 1 + PR 2 together happens after PR 3. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 16:49:29 -07:00
timeout hello 2s
timeout idle 2m
timeout processing 100ms
use-backend coraza-spoa-backend
log global
# Per-request inspection message. No `event` directive — fires only when
# explicitly invoked from haproxy.cfg via `http-request send-spoe-group`.
# Arg order/names are mandatory: Coraza-SPOA parses positionally and renames
# break the agent. `app=str(haproxy)` is the literal application name from
# coraza-spoa's config.yaml `applications:` block.
spoe-message coraza-req
args app=str(haproxy) src-ip=src src-port=src_port dst-ip=dst dst-port=dst_port method=method path=path query=query version=req.ver headers=req.hdrs body=req.body
# Group binding for send-spoe-group invocation in the frontend. One group,
# one message; could add more in the future (e.g. coraza-res for response
# inspection — currently disabled in coraza-spoa's config.yaml).
spoe-group coraza-req
messages coraza-req