From 155536d2c04789fe1c0efe74734558b032a9bdb0 Mon Sep 17 00:00:00 2001 From: datadunia Date: Thu, 4 Jun 2026 20:02:36 +0700 Subject: [PATCH] docs: add INPUT vs FORWARD chain architecture to AGENTS.md --- AGENTS.md | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/AGENTS.md b/AGENTS.md index 3ae47b3..c3d7c07 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -120,6 +120,48 @@ if d.AllowInternet { - NOT used for server-side WireGuard kernel config - Example: `10.172.21.0/24` allows peer to reach full subnet via firewall + routes full subnet through VPN on client +## FIREWALL CHAINS — INPUT vs FORWARD (CRITICAL) + +nftables traffic enters different chains depending on destination: +- **Traffic TO server's own IP** (e.g. 10.172.21.1) → **INPUT chain** +- **Traffic THROUGH server** (peer-to-peer, e.g. 10.172.21.2 → 10.172.21.3) → **FORWARD chain** + +### Rule routing in code +| Destination | Chain | Method | +|-------------|-------|--------| +| Server's own `interface_address` | INPUT | `AddInputFirewallRule()` | +| Other peer IPs / subnets | FORWARD | `AddFirewallRule()` | + +### Detection logic (syncRuleToFirewall) +```go +serverIP = strings.Split(localServer.InterfaceAddress, "/")[0] +destBase = strings.Split(destCIDR, "/")[0] +if destBase == serverIP { + fw.AddInputFirewallRule(...) // → INPUT chain +} else { + fw.AddFirewallRule(...) // → FORWARD chain +} +``` + +### Anti-pattern +```go +// WRONG — all rules go to FORWARD, server IP rules are dead +fw.AddFirewallRule(...) // for dest=10.172.21.1 → enters FORWARD chain → never matched +``` + +### Correct pattern +```go +// CORRECT — detect server IP, route to correct chain +if destBase == serverIP { + fw.AddInputFirewallRule(...) // → INPUT chain (matches traffic TO server) +} else { + fw.AddFirewallRule(...) // → FORWARD chain (matches traffic THROUGH server) +} +``` + +### Why +Traffic to server's own IP is processed by INPUT chain, not FORWARD chain. Placing rules in FORWARD chain for server-bound traffic makes them dead rules that never match. + ## UNIQUE STYLES - **Zero-Attack Surface**: `/auth/register` locked; admin via `-create-admin` CLI only - **Stealth Agent**: No `/etc/wireguard/` — config in memory only