2026
A Linux host network-policy daemon: keep routes, policy routing, firewall, NAT, traffic control and sysctls as desired state and apply them idempotently through ip, nft and tc.
netpolicyd holds a desired network configuration for a Linux host —
routes, policy rules, addresses, firewall, NAT, traffic control and sysctls —
and applies it with ip, nft, tc and sysctl. netpolicyctl is its
control panel: a terminal UI with an easy mode and an advanced mode, plus a CLI.
| Surface | Applied with |
|---|---|
| Policies | High-level ordered rules expanded to ip rule / table routes / NAT |
| Routes and IP rules | ip route, ip rule |
| Addresses and links | ip addr, ip link |
| Firewall and NAT | nftables (masquerade, SNAT, forward helpers) |
| IP lists | Named CIDR groups, compiled to nft sets |
| Traffic control | HTB egress shaping and ingress policing |
| Sysctls | ip_forward, rp_filter, … |
It also shows live state: a read-only dump of the host's firewall and routing,
and interface rates plus socket inventory from /proc/net/dev and ss.
PUT /v1/desired).POST /v1/apply builds an ordered command plan. ?dry_run=1 returns the
same plan without touching the host.nft -f script that declares,
deletes and redefines the inet netpolicyd table in a single transaction —
no half-applied window, no stacked duplicates. Rules outside that table are
left alone.curl -s -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"name":"src-via-gre-lab","priority":10,
"subjects":[{"kind":"cidr","value":"10.77.0.4/32"}],
"destination":{"kind":"any","value":"0.0.0.0/0"},
"action":"egress","egress_name":"gre-lab","source_cidr":"10.77.0.4/32"}' \
http://127.0.0.1:51910/v1/policies
netpolicyctl apply
This plans an ip rule and a routing table defaulting via gre-lab, plus
masquerade out that device unless an explicit NAT already covers it.
CAP_NET_ADMIN. Without the ip binary, or with --mock,
it only plans.Go, Bubble Tea for the TUI, nftables, iproute2, tc. Licensed under the GNU AGPL v3.