From 05ac3344faa691b862b9aeca703f1b05eeddd6a3 Mon Sep 17 00:00:00 2001 From: Debian Date: Tue, 2 Jun 2026 22:10:55 +0200 Subject: [PATCH] =?UTF-8?q?fix(waf):=20HAProxy-Reload=20nach=20WAF-Config?= =?UTF-8?q?=20+=20cfg-file=20=E2=86=92=20config=20=E2=80=94=20v1.2.72?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - handlers/waf.go: Reloader-Func; nach Upsert wird HAProxy async neu gerendert (SPOE-Filter erscheint/verschwindet je nach enabled-Stand) - main.go: haproxyReloader an NewWafHandler übergeben - haproxy.cfg.tpl: cfg-file → config (HAProxy 3.0 kennt cfg-file nicht) Co-Authored-By: Claude Sonnet 4.6 --- VERSION | 2 +- cmd/edgeguard-api/main.go | 2 +- internal/handlers/waf.go | 22 +++++++++++++++++----- internal/haproxy/haproxy.cfg.tpl | 2 +- 4 files changed, 20 insertions(+), 8 deletions(-) diff --git a/VERSION b/VERSION index 7468c0e..258bf89 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.2.71 +1.2.72 diff --git a/cmd/edgeguard-api/main.go b/cmd/edgeguard-api/main.go index d0a907b..61f85d1 100644 --- a/cmd/edgeguard-api/main.go +++ b/cmd/edgeguard-api/main.go @@ -384,7 +384,7 @@ func main() { } handlers.NewFirewallHandler(fwZones, fwAddrObj, fwAddrGrp, fwSvc, fwSvcGrp, fwRules, fwNAT, auditRepo, nodeID, fwReloader, pool).Register(authed) handlers.NewCrowdSecHandler(auditRepo, nodeID).Register(authed) - handlers.NewWafHandler(wafsvc.New(pool), auditRepo, nodeID).Register(authed) + handlers.NewWafHandler(wafsvc.New(pool), auditRepo, nodeID, haproxyReloader).Register(authed) // withFW wraps a service-reloader so that AFTER the service is // reloaded, the firewall is also re-rendered. Necessary for diff --git a/internal/handlers/waf.go b/internal/handlers/waf.go index 8cdb5b2..f4e5a29 100644 --- a/internal/handlers/waf.go +++ b/internal/handlers/waf.go @@ -1,7 +1,9 @@ package handlers import ( + "context" "errors" + "log/slog" "net/http" "strconv" @@ -19,13 +21,14 @@ import ( // GET /waf/configs/:domain_id — get config for a domain // PUT /waf/configs/:domain_id — upsert config for a domain type WafHandler struct { - Repo *wafsvc.Repo - Audit *audit.Repo - NodeID string + Repo *wafsvc.Repo + Audit *audit.Repo + NodeID string + Reloader func(ctx context.Context) error } -func NewWafHandler(repo *wafsvc.Repo, a *audit.Repo, nodeID string) *WafHandler { - return &WafHandler{Repo: repo, Audit: a, NodeID: nodeID} +func NewWafHandler(repo *wafsvc.Repo, a *audit.Repo, nodeID string, reloader func(context.Context) error) *WafHandler { + return &WafHandler{Repo: repo, Audit: a, NodeID: nodeID, Reloader: reloader} } func (h *WafHandler) Register(rg *gin.RouterGroup) { @@ -119,6 +122,15 @@ func (h *WafHandler) Upsert(c *gin.Context) { strconv.FormatInt(domainID, 10), gin.H{"enabled": body.Enabled, "mode": body.Mode, "paranoia_level": body.ParanoiaLevel}, h.NodeID) + // Reload HAProxy so the SPOE filter is added/removed based on + // whether any domain now has WAF enabled. + if h.Reloader != nil { + go func() { + if err := h.Reloader(context.Background()); err != nil { + slog.Warn("waf: haproxy reload after config change failed", "error", err) + } + }() + } c.JSON(http.StatusOK, gin.H{"config": result}) } diff --git a/internal/haproxy/haproxy.cfg.tpl b/internal/haproxy/haproxy.cfg.tpl index f0b2e6e..7ff1599 100644 --- a/internal/haproxy/haproxy.cfg.tpl +++ b/internal/haproxy/haproxy.cfg.tpl @@ -83,7 +83,7 @@ frontend public_https {{- if .WAFEnabled}} # WAF: SPOE-Filter — edgeguard-waf inspiziert jeden Request. # filter muss vor allen http-request/http-response-Direktiven stehen. - filter spoe engine edgeguard-waf cfg-file /etc/edgeguard/haproxy/coraza-spoe.cfg + filter spoe engine edgeguard-waf config /etc/edgeguard/haproxy/coraza-spoe.cfg {{- end}} # Alt-Svc: signalisiert dass h3 auf demselben Port verfügbar ist.