Created
January 8, 2026 07:22
-
-
Save federkamm/b85b0a8acaca9d086ac6616e0219ca16 to your computer and use it in GitHub Desktop.
nft: split tunnel VPN by user-group (with firewall, custom DNS, and kill-switch)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bash | |
| # - untrusted vpn on tun0 | |
| # - don't accept unexpected input (chain vpn/input) | |
| # - don't forward any traffic (chain vpn/forward) | |
| # - route traffic from group 'vpn' over tun0, (e.g. "sg vpn 'curl ifconfig.me'") | |
| # - NOTE: chain vpn/route needs to be of type 'route' to trigger route lookup by fwmark! | |
| # - nat DNS traffic (port 53) to custom DNS (chain vpn/nat) | |
| # - masquerade traffic over tun0 since initial route lookup suggests bindings to wrong socket! | |
| # - kill marked traffic that does not travel over tun0 | |
| ip route add default via 10.0.0.1 dev tun0 table 1 | |
| ip rule add fwmark 1 lookup 1 | |
| nft -f - <<EOF | |
| table inet vpn | |
| flush table inet vpn | |
| delete table inet vpn | |
| table inet vpn { | |
| chain input { | |
| type filter hook input priority filter; | |
| iif "tun0" ct state != { established, related } drop | |
| } | |
| chain forward { | |
| type filter hook forward priority filter; | |
| iif "tun0" drop | |
| } | |
| chain route { | |
| type route hook output priority mangle; | |
| meta skgid vpn ct mark set 1 | |
| ct mark 1 meta mark set 1 | |
| } | |
| chain nat { | |
| type nat hook output priority -100; # dstnat | |
| th dport 53 ct mark 1 dnat ip to 9.9.9.9 | |
| } | |
| chain masq { | |
| type nat hook postrouting priority srcnat; | |
| ct mark 1 masquerade | |
| } | |
| chain kill { | |
| type filter hook postrouting priority security; | |
| meta mark 1 oif != "tun0" drop | |
| } | |
| } | |
| EOF |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment