new-site/infra/firewall/pw-firewall.nft

55 lines
1.9 KiB
Text

#!/usr/sbin/nft -f
# Performance West host firewall.
# Goal: expose ONLY public-facing ports to the internet; keep all container /
# k3s / loopback traffic fully open so nothing internal breaks.
#
# Dedicated table (pw_fw) with a high-priority (-150) input hook so it is
# evaluated BEFORE kube-router's ACCEPT chain in the standard 'filter' table.
# fail2ban (f2b-table) stays untouched.
table inet pw_fw
delete table inet pw_fw
table inet pw_fw {
set pub_tcp {
type inet_service
# Public-facing ports only.
elements = { 22, 22022, 80, 443 }
# NB: 22 kept too in case provider/console uses it; SSH is on 22022.
}
# Trusted admin source IPs allowed to reach git/forgejo (3022) and other
# non-public admin ports. Update with: nft add element inet pw_fw trusted_admin { <ip> }
set trusted_admin {
type ipv4_addr
flags interval
elements = { 76.228.206.147 }
}
chain input {
type filter hook input priority -150; policy accept;
# 1) Always allow loopback + already-established flows.
iif "lo" accept
ct state established,related accept
ct state invalid drop
# 2) Fully trust internal networks (docker bridges, flannel pod/service,
# cni0). Containers and k3s must keep talking unrestricted.
ip saddr { 127.0.0.0/8, 172.16.0.0/12, 10.42.0.0/16, 10.43.0.0/16 } accept
iifname { "docker0", "br-*", "cni0", "flannel.1", "kube-*", "veth*", "cilium*" } accept
# 3) Allow ICMP (ping / path MTU) - safe and useful for diagnostics.
ip protocol icmp accept
ip6 nexthdr icmpv6 accept
# 4) Trusted-admin allow-list for git/forgejo SSH (3022).
ip saddr @trusted_admin tcp dport 3022 accept
# 5) Public allow-list (new inbound from the internet).
tcp dport @pub_tcp accept
# 6) Everything else arriving on the public uplink is dropped.
iifname "ens18" drop
}
}