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
}