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.