#!/usr/sbin/nft -f # # This configuration file is customized by fox, # Optimize nftables rules for local TS server. # table inet router flush table inet router table inet router { # # Flowtable # flowtable ft { hook ingress priority filter; devices = { eth0 }; counter; } # # Filter rules # chain input { type filter hook input priority filter; policy drop; iif "lo" accept comment "defconf: accept traffic from loopback" ct state established,related accept comment "defconf: handle inbound flows" tcp flags & (fin | syn | rst | ack) == syn jump syn_flood comment "defconf: rate limit new TCP connections" iifname "eth0" accept comment "defconf: accept LAN IPv4 / IPv6 input traffic" iifname "tailscale0" goto accept_from_tailscale comment "tsconf: handle TS IPv4 / IPv6 input traffic" } chain forward { type filter hook forward priority filter; policy drop; ct state established,related flow add @ft accept comment "defconf: offload and accept forwarded flows" iifname "eth0" goto forward_lan comment "defconf: handle LAN IPv4 / IPv6 forward traffic" iifname "tailscale0" goto forward_tailscale comment "tsconf: handle TS IPv4 / IPv6 forward traffic" } chain output { type filter hook output priority filter; policy accept; oif "lo" accept comment "defconf: accept traffic towards loopback" ct state established,related accept comment "defconf: handle outbound flows" oifname "eth0" goto accept_to_lan comment "defconf: handle LAN IPv4 / IPv6 output traffic" oifname "tailscale0" goto accept_to_tailscale comment "tsconf: handle TS IPv4 / IPv6 output traffic" } chain syn_flood { limit rate 50/second burst 100 packets return comment "defconf: accept new TCP connections below rate-limit" counter drop comment "defconf: drop excess new TCP connections" } chain forward_lan { oifname "tailscale0" goto accept_to_tailscale comment "tsconf: accept LAN to TS forwarding" ct status dnat accept comment "lanconf: accept port forwards" oifname "eth0" goto accept_to_lan } chain forward_tailscale { oifname "eth0" goto accept_to_lan comment "tsconf: accept TS to LAN forwarding" oifname "tailscale0" goto accept_to_tailscale } chain accept_to_lan { meta nfproto ipv4 ct state invalid counter drop comment "defconf: prevent LAN NATv4 leakage" accept comment "defconf: accept LAN IPv4 / IPv6 traffic" } chain accept_from_tailscale { meta nfproto ipv4 counter accept comment "tsconf: accept TS IPv4 traffic" meta nfproto ipv6 counter accept comment "tsconf: accept TS IPv6 traffic" } chain accept_to_tailscale { meta nfproto ipv4 counter accept comment "tsconf: accept TS IPv4 traffic" meta nfproto ipv6 counter accept comment "tsconf: accept TS IPv6 traffic" } # # NAT rules # chain dstnat { type nat hook prerouting priority dstnat; policy accept; iifname { "eth0", "tailscale0" } meta l4proto { tcp, udp } th dport domain goto redirect_dns comment "defconf: handle LAN IPv4 / IPv6 dstnat traffic" } chain srcnat { type nat hook postrouting priority srcnat; policy accept; oifname "eth0" meta nfproto ipv4 counter masquerade comment "defconf: masquerade LAN IPv4 traffic" } chain redirect_dns { meta nfproto ipv4 counter redirect comment "lanconf: LAN IPv4 DNS redirect" meta nfproto ipv6 counter redirect comment "lanconf: LAN IPv6 DNS redirect" } # # Mangle rules # chain mangle_postrouting { type filter hook postrouting priority mangle; policy accept; oifname "eth0" tcp flags & (fin | syn | rst) == syn tcp option maxseg size set rt mtu comment "defconf: zone LAN IPv4 / IPv6 egress MTU fixing" } chain mangle_forward { type filter hook forward priority mangle; policy accept; iifname "eth0" tcp flags & (fin | syn | rst) == syn tcp option maxseg size set rt mtu comment "defconf: zone LAN IPv4 / IPv6 ingress MTU fixing" } }