fix(firewall): WireGuard peer-to-peer forward-Chain-Auto-Rule

Die forward-chain hatte policy=drop ohne Ausnahme für WireGuard-
Peer-to-Peer-Traffic. Pakete von Peer A nach Peer B (beide am
selben wg-Interface) müssen durch die Box forwarded werden — das
war bisher stiller Drop.

Lösung: loadView liest alle aktiven server-mode WG-Interfaces und
trägt sie in View.WGServerIfaces ein. Das Template emittiert pro
Interface iifname "<wg>" accept in der forward-chain. Return-Pakete
gehen bereits via ct state established durch.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Debian
2026-05-21 11:34:48 +02:00
parent e7fc6b989b
commit a0403b8d00
3 changed files with 31 additions and 1 deletions

View File

@@ -103,6 +103,14 @@ type View struct {
// Operator never edits these — they belong to the service. If
// the service is removed/disabled, the rule is gone next render.
AutoRules []AutoFWRule
// WGServerIfaces holds the interface names of all active
// WireGuard server-mode interfaces. The forward chain emits
// iifname "<iface>" accept for each — required so that peer-to-
// peer traffic (Peer A → Peer B both connected to the same wg
// interface) can be forwarded by the box. Without this, the
// forward policy=drop silently kills all inter-peer packets.
WGServerIfaces []string
}
// AutoFWRule is one auto-emitted inbound rule. Proto is "tcp" or
@@ -278,6 +286,19 @@ func (g *Generator) loadView(ctx context.Context) (*View, error) {
// ── Auto-Rules aus laufender Service-Config ──
view.AutoRules = g.loadAutoRules(ctx)
// ── WireGuard server-iface names (für forward-chain) ──
wgRows, err := g.Pool.Query(ctx,
`SELECT name FROM wireguard_interfaces WHERE active AND mode = 'server'`)
if err == nil {
defer wgRows.Close()
for wgRows.Next() {
var name string
if wgRows.Scan(&name) == nil {
view.WGServerIfaces = append(view.WGServerIfaces, name)
}
}
}
return view, nil
}

View File

@@ -98,6 +98,15 @@ table inet edgeguard {
ip saddr {{.SrcCIDR}} ct state new accept comment "auto-forward for NAT rule {{.ID}}"
{{end}}{{end}}{{end}}
# Auto-Forward für WireGuard-Server-Interfaces: Peer-to-Peer-
# Traffic (Peer A → Peer B, beide via dasselbe wg-Interface)
# muss durch die Box forwarded werden. Ohne diese Regel droppt
# policy=drop den Traffic, auch wenn WG ihn korrekt entschlüsselt.
# Return-Pakete gehen bereits via ct state established durch.
{{range .WGServerIfaces}}
iifname "{{.}}" accept comment "auto: WireGuard peer-forward {{.}}"
{{end}}
# Default-Drop-Logging (limit-rated, siehe input-chain).
limit rate 10/second log prefix "edgeguard:drop-forward " group 0
}