feat(amneziawg): Phase 2b — per-client port-forwarding

Admins can now set a per-client ForwardedPorts string (e.g. "80, 443,
8000-8100") that gets DNAT'd + FORWARD'd to that peer's tunnel address
via iptables rules in PostUp/PostDown, ported and simplified from
coinman-dev/3ax-ui's shared/portfwd.

Two decisions worth flagging for future readers:

- The iptables --comment tag on each rule is awg-fwd-<fnv32a(email)>,
  not the raw client email. Email is admin/API-supplied free text that
  ends up embedded in a shell-executed PostUp/PostDown line; a hash
  can never carry a shell metacharacter through where raw
  interpolation could.
- The reconcile manager gained a third fingerprint (portFwdFP, next to
  the existing structural/peers ones). `awg syncconf` only touches the
  WireGuard peer table — it never re-applies PostUp/PostDown iptables
  rules — so a port-forward-only change has to force a full
  awg-quick down+up bounce, same as a structural change, rather than
  the lighter sync a plain peer add/remove can use.

Also fixes a real pre-existing bug found while wiring up IPv6 client
allocation in the previous commit's spirit: allocateWireguardAddress
always suffixed "/32" regardless of address family, which produced
invalid host bits for IPv6 (needs "/128").

ForwardedPorts flows through model.Client -> model.ClientRecord
(gorm column wg_forwarded_ports, auto-migrated) -> ToRecord/ToClient/
MergeClientRecord, mirroring the awgServer field's earlier lesson
that new fields need checking against a second, hand-maintained
persistence-layer struct.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Kuzz007
2026-07-25 17:54:05 +03:00
parent 9eaae5fd6a
commit 69de904bf6
15 changed files with 361 additions and 93 deletions
+8
View File
@@ -1050,6 +1050,10 @@
"description": "Flow control (XTLS)",
"type": "string"
},
"forwardedPorts": {
"description": "AmneziaWG per-client port-forwarding spec, e.g. \"80,443,8000-8100\"",
"type": "string"
},
"group": {
"description": "Logical grouping label",
"type": "string"
@@ -1188,6 +1192,9 @@
"flow": {
"type": "string"
},
"forwardedPorts": {
"type": "string"
},
"group": {
"type": "string"
},
@@ -1251,6 +1258,7 @@
"enable",
"expiryTime",
"flow",
"forwardedPorts",
"group",
"id",
"keepAlive",