package firewall import ( "fmt" "strings" "github.com/ngoduykhanh/wireguard-ui/model" ) // GlobalTableName is the dedicated nftables table for the host-wide // allow/block lists, kept separate from every per-server table. const GlobalTableName = "wireguard_ui_global" // GenerateGlobalRuleset renders the host-wide allow/block list ruleset. // It runs at priority -10, before any per-server table (priority 0), so it // applies to ALL traffic on the host, not just WireGuard - this is meant to // be the one central place for IP allow/block lists. Allow entries take // precedence over block entries. func GenerateGlobalRuleset(entries []model.IPListEntry) string { var allow, block []string for _, e := range entries { if e.ListType == "allow" { allow = append(allow, e.CIDR) } else if e.ListType == "block" { block = append(block, e.CIDR) } } var b strings.Builder fmt.Fprintf(&b, "# Host-wide allow/block list, generated by wireguard-ui-multi.\n") fmt.Fprintf(&b, "# Applies to all traffic on this host (priority -10), before any\n") fmt.Fprintf(&b, "# per-server WireGuard firewall table.\n\n") fmt.Fprintf(&b, "table inet %s {\n", GlobalTableName) fmt.Fprintf(&b, " set allowlist {\n type ipv4_addr; flags interval;\n auto-merge\n") if len(allow) > 0 { fmt.Fprintf(&b, " elements = { %s }\n", strings.Join(allow, ", ")) } fmt.Fprintf(&b, " }\n\n") fmt.Fprintf(&b, " set blocklist {\n type ipv4_addr; flags interval;\n auto-merge\n") if len(block) > 0 { fmt.Fprintf(&b, " elements = { %s }\n", strings.Join(block, ", ")) } fmt.Fprintf(&b, " }\n\n") fmt.Fprintf(&b, " chain input {\n") fmt.Fprintf(&b, " type filter hook input priority -10; policy accept;\n") fmt.Fprintf(&b, " ip saddr @allowlist accept comment \"wg-ui-multi: global allowlist\"\n") fmt.Fprintf(&b, " ip saddr @blocklist drop comment \"wg-ui-multi: global blocklist\"\n") fmt.Fprintf(&b, " }\n\n") fmt.Fprintf(&b, " chain forward {\n") fmt.Fprintf(&b, " type filter hook forward priority -10; policy accept;\n") fmt.Fprintf(&b, " ip saddr @allowlist accept comment \"wg-ui-multi: global allowlist\"\n") fmt.Fprintf(&b, " ip saddr @blocklist drop comment \"wg-ui-multi: global blocklist\"\n") fmt.Fprintf(&b, " }\n") fmt.Fprintf(&b, "}\n") return b.String() }