feat(firewall-log): Phase 2 — HTTP-Tail + WebSocket-Live-Stream

Backend für /firewall-Live-Tail und historische Recherche der
ulogd2-JSONL aus Phase 1.

internal/services/firewalllog/
  reader.go  — JSONL parser + Filter (since/until/rule_id/src/dst/
               proto/action/limit). Proto-Mapping aus IP-Protocol-Number
               (1=icmp, 6=tcp, 17=udp, 58=icmpv6). RuleID wird aus
               oob.prefix "edgeguard:<id>" extrahiert.
  tailer.go  — fsnotify-Watcher auf /var/log/edgeguard/, In-Memory
               Ring-Buffer 1000 Events, fan-out an Subscribe()-Channel.
               Robust gegen logrotate copytruncate (truncate-detection
               via stat.Size() < offset → seek(0)). Safety-Net 2s-poll
               falls fsnotify einen Write verschluckt. Non-blocking send
               an Subscriber — langsame Clients droppen Events statt
               die Pipeline zu blockieren.

internal/handlers/firewall_log.go:
  GET /api/v1/firewall/log     — typed JSON list, Filter via Query
  WS  /api/v1/firewall/log/live — Snapshot + live broadcast
                                  (gorilla/websocket, 30s-ping)

main.go: Tailer beim Startup gestartet (context.Background) — UI
landet in Phase 3.

deps: gorilla/websocket v1.5.3, fsnotify v1.10.1

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Debian
2026-05-12 21:05:39 +02:00
parent 3c817b7080
commit a798d1b796
10 changed files with 684 additions and 5 deletions

View File

@@ -36,6 +36,7 @@ import (
dnssvc "git.netcell-it.de/projekte/edgeguard-native/internal/services/dns"
"git.netcell-it.de/projekte/edgeguard-native/internal/services/domains"
"git.netcell-it.de/projekte/edgeguard-native/internal/services/firewall"
"git.netcell-it.de/projekte/edgeguard-native/internal/services/firewalllog"
"git.netcell-it.de/projekte/edgeguard-native/internal/services/forwardproxy"
"git.netcell-it.de/projekte/edgeguard-native/internal/services/ipaddresses"
"git.netcell-it.de/projekte/edgeguard-native/internal/services/networkifs"
@@ -48,7 +49,7 @@ import (
wgsvc "git.netcell-it.de/projekte/edgeguard-native/internal/services/wireguard"
)
var version = "1.0.59"
var version = "1.0.60"
func main() {
addr := os.Getenv("EDGEGUARD_API_ADDR")
@@ -183,6 +184,12 @@ func main() {
handlers.NewClusterHandler(clusterStore, nodeID).Register(authed)
handlers.NewAuditHandler(auditRepo).Register(authed)
handlers.NewHAProxyStatsHandler().Register(authed)
// Firewall-Log (Phase 2): Tailer für /var/log/edgeguard/
// firewall.jsonl + HTTP-Tail + WebSocket-Live-Stream.
fwLogTailer := firewalllog.NewTailer(firewalllog.DefaultLogPath, 1000)
handlers.StartFirewallLogTailer(context.Background(), fwLogTailer)
handlers.NewFirewallLogHandler(fwLogTailer, firewalllog.DefaultLogPath).Register(authed)
handlers.NewTLSCertsHandler(tlsRepo, auditRepo, nodeID, acmeService).Register(authed)
// Firewall reload: nach jeder Mutation den Renderer neu fahren
// (writes ruleset.nft + sudo nft -f). Errors loggen, nicht failen.

View File

@@ -9,7 +9,7 @@ import (
"os"
)
var version = "1.0.59"
var version = "1.0.60"
const usage = `edgeguard-ctl — EdgeGuard CLI

View File

@@ -24,7 +24,7 @@ import (
"git.netcell-it.de/projekte/edgeguard-native/internal/services/tlscerts"
)
var version = "1.0.59"
var version = "1.0.60"
const (
// renewTickInterval — how often we re-evaluate expiring certs.