nix/shared/bastion/nftables.nix
2025-07-21 22:49:14 +02:00

86 lines
No EOL
3.2 KiB
Nix

{ lib, ... }:
{
networking = {
nat.enable = false;
firewall.enable = lib.mkForce false;
nftables = {
enable = true;
checkRuleset = true;
flushRuleset = true;
tables = {
filter = {
family = "inet";
content = ''
chain preroute {
type filter hook prerouting priority -150; policy accept;
}
chain input {
type filter hook input priority 0; policy drop;
# Authorized already setup connection
ct state related,established accept
# Reject sus stuff
ct state invalid counter drop
tcp flags & (fin|syn|rst|ack) != syn ct state new counter drop
# Loopback
iif lo accept
# ICMP
icmp type { echo-request } limit rate 4/second accept
icmpv6 type { echo-request } limit rate 4/second accept
ip protocol icmp accept
icmpv6 type { nd-neighbor-solicit, nd-router-advert, nd-neighbor-advert } accept
# SSH
tcp dport 22 accept
# Mesh
udp dport 51820 accept
# Mgmt
udp dport 51920 accept
# Log anything else
ip protocol tcp counter log prefix "tcp.in.dropped: "
ip protocol udp counter log prefix "udp.in.dropped: "
}
chain forward {
type filter hook forward priority 0; policy drop;
ct state related,established accept
ct state invalid counter drop
iifname mgmt oifname mesh accept
}
chain output {
type filter hook output priority 0; policy accept;
}
chain postroute {
type filter hook postrouting priority 50; policy accept;
}
'';
};
# We'll not nat the outgoing wg packet
# Instead custom routing is done on all
# other node to sent it back correclty
# That allow for custom ACL for the mgmt
# ip addresses
nat = {
family = "inet";
content = ''
chain prerouting {
type nat hook prerouting priority -100; policy accept;
}
chain postrouting {
type nat hook postrouting priority 100; policy accept;
}
'';
};
};
};
};
}