feat(firewall-log): ulogd2 + NFLOG group 0 → JSON-Lines
Foundation für Live-Log + Firewall-History (Logsystem Phase 1): - nft-Renderer: `log prefix "edgeguard:<rule-id>" group 0` für Rules mit log=true. Ohne `group` schrieb nft in kernel-log (dmesg), nie in netlink → ulogd2 sah nichts. - ulogd2 + ulogd2-json als Depends, postinst legt /etc/ulogd.conf (NFLOG group 0 → /var/log/edgeguard/firewall.jsonl) + logrotate- Profil (14d, daily, copytruncate) + enable/restart ulogd2.service. - /var/log/edgeguard/ ist root:edgeguard 0640 — ulogd2 schreibt (root), edgeguard-api liest (UI-Endpoints kommen in Phase 2). End-to-End smoke-test bestätigt: ICMP echo → JSON-Line mit allen Feldern (src_ip, dest_ip, oob.prefix, oob.in, icmp.*) in ~30ms. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -48,7 +48,7 @@ import (
|
||||
wgsvc "git.netcell-it.de/projekte/edgeguard-native/internal/services/wireguard"
|
||||
)
|
||||
|
||||
var version = "1.0.57"
|
||||
var version = "1.0.59"
|
||||
|
||||
func main() {
|
||||
addr := os.Getenv("EDGEGUARD_API_ADDR")
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
"os"
|
||||
)
|
||||
|
||||
var version = "1.0.57"
|
||||
var version = "1.0.59"
|
||||
|
||||
const usage = `edgeguard-ctl — EdgeGuard CLI
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ import (
|
||||
"git.netcell-it.de/projekte/edgeguard-native/internal/services/tlscerts"
|
||||
)
|
||||
|
||||
var version = "1.0.57"
|
||||
var version = "1.0.59"
|
||||
|
||||
const (
|
||||
// renewTickInterval — how often we re-evaluate expiring certs.
|
||||
|
||||
@@ -62,7 +62,7 @@ table inet edgeguard {
|
||||
die Comment-Zeile angehängt — sonst frisst nft die rule
|
||||
als Teil des # Kommentars). */ -}}
|
||||
{{""}}
|
||||
{{if .SrcIfaces}}iifname { {{join .SrcIfaces ", "}} } {{end}}{{if .DstIfaces}}oifname { {{join .DstIfaces ", "}} } {{end}}{{if .SrcAddrs}}ip saddr { {{join .SrcAddrs ", "}} } {{end}}{{if .DstAddrs}}ip daddr { {{join .DstAddrs ", "}} } {{end}}{{with .Service}}{{if and (or (eq .Proto "tcp") (eq .Proto "udp")) .PortStart}}{{.Proto}} dport {{.PortStart}}{{if and .PortEnd (ne .PortEnd .PortStart)}}-{{.PortEnd}}{{end}} {{else if eq .Proto "icmp"}}ip protocol icmp {{else if eq .Proto "icmpv6"}}ip6 nexthdr icmpv6 {{end}}{{end}}{{if .Log}}log prefix "edgeguard:{{.RuleID}} " {{end}}{{.Action}}
|
||||
{{if .SrcIfaces}}iifname { {{join .SrcIfaces ", "}} } {{end}}{{if .DstIfaces}}oifname { {{join .DstIfaces ", "}} } {{end}}{{if .SrcAddrs}}ip saddr { {{join .SrcAddrs ", "}} } {{end}}{{if .DstAddrs}}ip daddr { {{join .DstAddrs ", "}} } {{end}}{{with .Service}}{{if and (or (eq .Proto "tcp") (eq .Proto "udp")) .PortStart}}{{.Proto}} dport {{.PortStart}}{{if and .PortEnd (ne .PortEnd .PortStart)}}-{{.PortEnd}}{{end}} {{else if eq .Proto "icmp"}}ip protocol icmp {{else if eq .Proto "icmpv6"}}ip6 nexthdr icmpv6 {{end}}{{end}}{{if .Log}}log prefix "edgeguard:{{.RuleID}} " group 0 {{end}}{{.Action}}
|
||||
{{end}}
|
||||
}
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@ const NAV: NavSection[] = [
|
||||
},
|
||||
]
|
||||
|
||||
const VERSION = '1.0.57'
|
||||
const VERSION = '1.0.59'
|
||||
|
||||
// Sidebar-Pattern 1:1 aus netcell-webpanel (enconf) übernommen:
|
||||
// - <nav> als root, dunkler Gradient + Teal/Blue-Accent
|
||||
|
||||
@@ -12,7 +12,7 @@ Description: EdgeGuard — native Reverse-Proxy / LB / Forward-Proxy / VPN / Fir
|
||||
PG Streaming Replication + provider Floating-IP for HTTP ingress).
|
||||
.
|
||||
This package ships the management API, scheduler and CLI.
|
||||
Depends: postgresql-16 | postgresql-17, haproxy (>= 2.8), squid, wireguard-tools, unbound, chrony, nftables, certbot, openssl, sudo, adduser, systemd, ca-certificates
|
||||
Depends: postgresql-16 | postgresql-17, haproxy (>= 2.8), squid, wireguard-tools, unbound, chrony, nftables, certbot, openssl, sudo, adduser, systemd, ca-certificates, ulogd2, ulogd2-json
|
||||
Recommends: edgeguard-keydb (>= 6.3.4-edgeguard1), apparmor, fail2ban
|
||||
Section: admin
|
||||
Priority: optional
|
||||
|
||||
@@ -199,6 +199,77 @@ vm.dirty_background_ratio = 5
|
||||
SYSCTL
|
||||
sysctl --system >/dev/null 2>&1 || true
|
||||
|
||||
# ── Firewall-Logging via ulogd2 (NFLOG group 0) ──────────────
|
||||
# nft-Renderer emittiert `log prefix "edgeguard:<rule-id>" group 0`
|
||||
# für jede Rule mit log=true. ulogd2 subscribed auf netlink-group
|
||||
# 0 und schreibt JSON-Lines nach /var/log/edgeguard/firewall.jsonl.
|
||||
# Das UI tailt das File für Live-Log + Historie.
|
||||
install -d -m 0755 /var/log/edgeguard
|
||||
install -d -m 0755 -o "$EG_USER" -g "$EG_USER" /var/log/edgeguard
|
||||
if [ ! -f /var/log/edgeguard/firewall.jsonl ]; then
|
||||
: > /var/log/edgeguard/firewall.jsonl
|
||||
fi
|
||||
# ulogd2 läuft als root (eigener Daemon); File muss von ihm
|
||||
# schreibbar UND von edgeguard-API lesbar sein.
|
||||
chown root:"$EG_USER" /var/log/edgeguard/firewall.jsonl
|
||||
chmod 0640 /var/log/edgeguard/firewall.jsonl
|
||||
|
||||
cat > /etc/ulogd.conf <<'ULOGD'
|
||||
# Managed by edgeguard — re-installation overwrites this file.
|
||||
# NFLOG group 0 → JSON-Lines pro Paket nach /var/log/edgeguard/firewall.jsonl
|
||||
# Format-Felder: oob.time.sec, oob.prefix (rule-id), src_ip, dst_ip,
|
||||
# src_port, dst_port, ip.protocol, raw.pktlen, oob.in/oob.out (iface).
|
||||
[global]
|
||||
logfile="/var/log/ulogd.log"
|
||||
loglevel=5
|
||||
|
||||
plugin="/usr/lib/x86_64-linux-gnu/ulogd/ulogd_inppkt_NFLOG.so"
|
||||
plugin="/usr/lib/x86_64-linux-gnu/ulogd/ulogd_filter_IFINDEX.so"
|
||||
plugin="/usr/lib/x86_64-linux-gnu/ulogd/ulogd_filter_IP2STR.so"
|
||||
plugin="/usr/lib/x86_64-linux-gnu/ulogd/ulogd_filter_HWHDR.so"
|
||||
plugin="/usr/lib/x86_64-linux-gnu/ulogd/ulogd_raw2packet_BASE.so"
|
||||
plugin="/usr/lib/x86_64-linux-gnu/ulogd/ulogd_output_JSON.so"
|
||||
|
||||
stack=fw1:NFLOG,base1:BASE,ifi1:IFINDEX,ip2str1:IP2STR,mac2str1:HWHDR,json1:JSON
|
||||
|
||||
[fw1]
|
||||
group=0
|
||||
|
||||
[json1]
|
||||
sync=1
|
||||
file="/var/log/edgeguard/firewall.jsonl"
|
||||
timestamp=1
|
||||
boolean_label=1
|
||||
ULOGD
|
||||
chmod 0644 /etc/ulogd.conf
|
||||
|
||||
# Logrotate-Profil für firewall.jsonl — Default: daily, 14 days
|
||||
# comprimiert, copytruncate damit ulogd kein Reopen-Signal braucht.
|
||||
cat > /etc/logrotate.d/edgeguard-firewall <<'LOGROTATE'
|
||||
/var/log/edgeguard/firewall.jsonl {
|
||||
daily
|
||||
rotate 14
|
||||
missingok
|
||||
notifempty
|
||||
compress
|
||||
delaycompress
|
||||
copytruncate
|
||||
create 0640 root edgeguard
|
||||
}
|
||||
LOGROTATE
|
||||
chmod 0644 /etc/logrotate.d/edgeguard-firewall
|
||||
|
||||
# ulogd2 enablen + restarten (idempotent). Wenn das Paket nicht
|
||||
# da ist (Dependency-Konflikt o.ä.), nur warnen — die Firewall
|
||||
# läuft auch ohne Logger.
|
||||
if systemctl list-unit-files ulogd2.service >/dev/null 2>&1; then
|
||||
systemctl enable ulogd2.service >/dev/null 2>&1 || true
|
||||
systemctl restart ulogd2.service || \
|
||||
echo "postinst: ulogd2.service restart failed (firewall logs disabled until fixed)" >&2
|
||||
else
|
||||
echo "postinst: ulogd2.service not installed — install ulogd2 to enable firewall log" >&2
|
||||
fi
|
||||
|
||||
# ── Self-signed default cert so HAProxy starts cleanly ───────
|
||||
# HAProxy `bind :443 ssl crt /etc/edgeguard/tls/` needs at least
|
||||
# one PEM in the directory to come up. Operator runs certbot
|
||||
|
||||
Reference in New Issue
Block a user