Files
nix-config-ryan4yin/modules/nixos/base/networking/firewall.nix
T
Ryan Yin 267ccd9d34 fix(firewall): note the one port that is open to the Internet
Assisted-by: DeepSeek Harness 0.2.1-rc.2 (deepseek-flash)
2026-10-22 00:54:27 +08:00

61 lines
2.4 KiB
Nix

{ lib, myvars, ... }:
let
inherit (myvars.networking) lanCidr;
# The host that scrapes the exporters (VictoriaMetrics runs on youko).
monitoringHost = myvars.networking.hostsAddr.youko.ipv4;
in
{
# Hosts bring their own firewall as defence in depth behind the router's
# (which stays on, with port mappings for the few ports we need): the home
# LAN and the tailnet are trusted equally (tighten the tailnet with Tailscale
# ACLs), and everything else is denied on both address families.
networking.nftables.enable = true;
networking.firewall = {
enable = true;
# Nothing is opened to the Internet except Tailscale's WireGuard port
# below. LAN/tailnet/local-container access comes from the rules below;
# per-service `openFirewall` ports are suppressed.
allowedTCPPorts = lib.mkForce [ ];
allowedUDPPorts = lib.mkForce [ ];
extraInputRules = ''
# node_exporter is scraped only by the monitoring host, not the whole
# LAN/tailnet/local containers.
ip saddr != ${monitoringHost} tcp dport 9100 drop
# The NVIDIA GPU exporter (desktop only) is likewise scraped only by the
# monitoring host.
ip saddr != ${monitoringHost} tcp dport 9835 drop
# smartctl_exporter (drive/SSD SMART health) is scraped only by the
# monitoring host.
ip saddr != ${monitoringHost} tcp dport 9633 drop
# Monitoring uses the stable IPv4 address above. Deny IPv6 exporter
# connections before broad LAN/tailnet/container trust can accept them;
# this does not restrict other IPv6 services or loopback access.
meta nfproto ipv6 tcp dport { 9100, 9835, 9633 } drop
# VNC consoles (libvirt on the VM hosts, and x11vnc inside the guests)
# are never exposed to the LAN, tailnet, or containers: reach them
# through an SSH tunnel. Loopback is accepted by the firewall's own rule.
tcp dport { 5900, 5901, 5902, 5903, 5910 } drop
# The local container bridge and the tailnet have the same access as the
# LAN. Kept after the drop above so neither can reach node_exporter.
iifname "podman0" accept
iifname "tailscale0" accept
# The home LAN is the trusted core.
ip saddr ${lanCidr} accept
ip6 saddr fe80::/10 accept
# Tailscale's WireGuard port, for direct (non-DERP) connections. The LAN
# and tailnet are accepted above, so this is the only port open to the
# Internet.
udp dport 41641 accept
'';
};
}