Created
March 20, 2023 08:32
-
-
Save 0xc0392b/27b39a319efc88e8caaa24c0afe3751d to your computer and use it in GitHub Desktop.
nftables ruleset for secure home router with VPN
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/sbin/nft -f | |
| # based on | |
| # https://wiki.nftables.org/wiki-nftables/index.php/Simple_ruleset_for_a_home_router | |
| # https://www.ivpn.net/knowledgebase/linux/linux-how-do-i-prevent-vpn-leaks-using-nftables-and-openvpn/ | |
| # reset | |
| flush ruleset | |
| # devices | |
| define DEV_WORLD = wlan0 | |
| define DEV_PRIVATE = eno1 | |
| define DEV_TUNNEL = tun0 | |
| # networks | |
| define NET_PRIVATE = 192.168.100.0/24 | |
| # VPN servers | |
| define VPN_SERVERS = { xxx.xxx.xxx.xxx } | |
| table ip global { | |
| chain inbound_world { | |
| # accept traffic from local DHCP servers | |
| ip saddr 255.255.255.255 counter accept | |
| } | |
| chain inbound_private { | |
| # accept pings on private interface | |
| icmp type echo-request limit rate 5/second accept | |
| # accept dhcp, ssh, dns on private interface | |
| ip protocol . th dport vmap { | |
| tcp . 22 : accept, | |
| udp . 53 : accept, | |
| tcp . 53 : accept, | |
| udp . 67 : accept | |
| } | |
| } | |
| chain inbound { | |
| # drop everything by default | |
| type filter hook input priority 0; policy drop; | |
| # accept established and related packets, drop invalid | |
| ct state vmap { | |
| established : accept, | |
| related : accept, | |
| invalid : drop | |
| } | |
| # accept loopback, anything else jump to chain for evaluation | |
| iifname vmap { | |
| lo : accept, | |
| $DEV_WORLD : jump inbound_world, | |
| $DEV_PRIVATE : jump inbound_private | |
| } | |
| } | |
| chain outbound_world { | |
| # accept traffic to local DHCP servers | |
| ip daddr 255.255.255.255 counter accept | |
| # accept traffic to VPN servers | |
| ip daddr $VPN_SERVERS counter accept | |
| } | |
| chain outbound_private { | |
| # accept pings on private interface | |
| icmp type echo-request limit rate 5/second accept | |
| } | |
| chain outbound { | |
| # drop everything by default | |
| type filter hook output priority 0; policy drop; | |
| # accept established and related packets, drop invalid | |
| ct state vmap { | |
| established : accept, | |
| related : accept, | |
| invalid : drop | |
| } | |
| # accept loopback and VPN traffic, anything else jump to chain for evaluation | |
| oifname vmap { | |
| lo : accept, | |
| $DEV_TUNNEL : accept, | |
| $DEV_WORLD : jump outbound_world, | |
| $DEV_PRIVATE : jump outbound_private | |
| } | |
| } | |
| chain forward { | |
| # drop everything by default | |
| type filter hook forward priority 0; policy drop; | |
| # accept traffic from established and related packets, drop invalid | |
| ct state vmap { | |
| established : accept, | |
| related : accept, | |
| invalid : drop | |
| } | |
| # connections from internal to internal or internet are allowed | |
| iifname $DEV_PRIVATE accept | |
| } | |
| chain postrouting { | |
| # accept everything by default | |
| type nat hook postrouting priority 100; policy accept; | |
| # masquerade private network IP addresses (private <-nat-> world) | |
| ip saddr $NET_PRIVATE oifname $DEV_TUNNEL masquerade | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment