nixos-config/machines/shinobu/services/router/rules.nft

174 lines
5.5 KiB
Plaintext

# SPDX-FileCopyrightText: 2023-2024 Simon Bruder <simon@sbruder.de>
#
# SPDX-License-Identifier: AGPL-3.0-or-later
define NAT_LAN_IFACES = { "br-lan", "br-guest" }
define PHYSICAL_WAN = "enp1s0"
# only includes interfaces that use NAT
define NAT_WAN_IFACES = { $PHYSICAL_WAN }
# also includes interfaces that do not use NAT
define WAN_IFACES = { $NAT_WAN_IFACES, "wg-he" }
table inet filter {
chain forward {
type filter hook forward priority filter; policy drop
# Use MSS clamping to avoid too large packets not going through the tunnel.
tcp flags syn / syn,rst tcp option maxseg size set rt mtu
# plastic router, might be vulnerable (FIXME v6 is still reachable)
iifname "br-guest" ip daddr "192.168.0.1" drop
# allow traffic between selected VLANs and wan
iifname $NAT_LAN_IFACES oifname $WAN_IFACES counter accept
iifname $WAN_IFACES oifname $NAT_LAN_IFACES ct state established,related counter accept
# allow lan clients to be publicly reachable
iifname "wg-he" oifname "br-lan" counter accept
# traffic from lan to all other vlans is allowed
iifname "br-lan" oifname $VLAN_BRIDGES counter accept;
iifname $VLAN_BRIDGES oifname "br-lan" ct state established,related counter accept
iifname $WAN_IFACES oifname "br-iot" ct state established,related counter accept
}
}
table ip nat {
chain postrouting {
type nat hook postrouting priority filter; policy accept
oifname $NAT_WAN_IFACES masquerade
}
}
# Bypass HE tunnel by setting a firewall mark.
# This acts in two places that are handled separatly by nftables:
# Packets from the local host (output hook) and forwared packets (prerouting hook).
# To simplify the handling,
# there is a single chain that handles both,
# which is jumped to from the specific chains.
# Additionally, masquerading is allowed for all packages with a destination of the dynamic set.
table ip6 he-bypass {
# Dynamically managed by dnsmasq (based on resolved addresses).
set addresses {
type ipv6_addr
comment "IPv6 addresses for which the HE tunnel should be bypassed by using NAT on wan instead"
}
# This must be of type route, otherwise no route lookup will be performed
chain output {
type route hook output priority mangle
jump common
}
# This does not need to be of type route
chain prerouting {
type filter hook prerouting priority mangle
jump common
}
chain common {
ip6 daddr @addresses mark set 0x7974 counter
}
chain postrouting {
type nat hook postrouting priority filter; policy accept
oifname $NAT_WAN_IFACES ip6 daddr @addresses masquerade
}
}
table ip6 public-access {
chain input {
type filter hook input priority filter; policy accept
iifname "wg-he" oifname "br-lan" counter accept
}
}
# Only allow select connections from and to (physical) wan,
# overriding NixOS firewall in some cases.
table inet restrict-wan {
# Priorities must be higher than filter (0),
# which the NixOS firewall uses.
chain input {
type filter hook input priority -50; policy accept
# accept responses
iifname $PHYSICAL_WAN ct state established,related counter accept
# accept icmpv6
iifname $PHYSICAL_WAN icmpv6 type { nd-neighbor-solicit, nd-router-advert, nd-neighbor-advert } accept
# drop everything else
iifname $PHYSICAL_WAN counter drop
}
# This handles all packets (local and forwarded)
chain postrouting {
type filter hook postrouting priority 0; policy accept
# accept connections over physical wan
oifname $PHYSICAL_WAN counter accept
}
}
# Traffic control
# Neets output and prerouting to match packets from localhost and lan
table inet tc {
chain output {
type route hook output priority mangle
# hardcoded, but unlikely to change
ip daddr { "9.9.9.9", "149.112.112.112" } meta priority set 1:3 counter return comment "DNS (4)"
ip6 daddr { "2620:fe::9", "2620:fe::fe" } meta priority set 1:3 counter return comment "DNS (6)"
jump common
}
chain forward {
type filter hook forward priority mangle
jump common
}
chain common {
iifname "br-guest" meta priority set 1:a counter return comment "guest network"
meta l4proto tcp meta length 1-64 meta priority set 1:3 counter return comment "small tcp packets"
tcp dport 22 ip dscp af21 meta priority set 1:4 counter return comment "interactive SSH (4)"
tcp dport 22 ip6 dscp af21 meta priority set 1:4 counter return comment "interactive SSH (6)"
meta l4proto udp ip dscp af13 meta priority set 1:5 ip dscp set cs0 counter return comment "fuuko torrent"
ip daddr 168.119.176.53 tcp dport 443 ip dscp af12 meta priority set 1:9 counter return comment "restic (4)"
ip6 daddr 2a01:4f8:c012:2f4::1 tcp dport 443 ip6 dscp af12 meta priority set 1:9 counter return comment "restic (6)"
meta l4proto { tcp, udp } th dport 443 meta priority set 1:6 counter return comment "HTTPS"
ip daddr 168.119.176.53 udp dport 51820 meta priority set 1:7 counter return comment "wg-home"
meta l4proto { tcp, udp } ip dscp ef meta priority set 1:8 counter return comment "VoIP (4)"
meta l4proto { tcp, udp } ip6 dscp ef meta priority set 1:8 counter return comment "VoIP (6)"
meta l4proto { tcp, udp } th dport 64738 meta priority set 1:8 counter return comment "Mumble"
}
}
# Tracing infrastructure, can be used for debugging (nft monitor trace)
table inet trace {
chain prerouting {
type filter hook prerouting priority raw - 1
jump common
}
chain output {
type filter hook output priority raw - 1
jump common
}
chain common {
# Add tracing rule here
# … meta nftrace set 1
# DO NOT COMMIT ANY TRACING RULES
}
}