aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorLibravatar sommerfeld <sommerfeld@sommerfeld.dev>2026-05-13 13:43:41 +0100
committerLibravatar sommerfeld <sommerfeld@sommerfeld.dev>2026-05-13 13:43:41 +0100
commitfa081c7a7dbe0ab3660f6f6d7860b5a815370c5d (patch)
treebb5c26fec71586618fdbaac58cd3e09a99b3db8b
parent8567dd49e9e688f26dc0b266f211655974539299 (diff)
downloaddotfiles-fa081c7a7dbe0ab3660f6f6d7860b5a815370c5d.tar.gz
dotfiles-fa081c7a7dbe0ab3660f6f6d7860b5a815370c5d.tar.bz2
dotfiles-fa081c7a7dbe0ab3660f6f6d7860b5a815370c5d.zip
fix(nftables): allow DHCP/DNS and forwarding for libvirt virbr0
The host firewall has policy=drop on both input and forward chains. libvirt creates its own nftables table for virbr0 NAT, but: 1. It does not touch the input chain at all, so DHCP packets from guests (UDP/67) are dropped before reaching dnsmasq. Result: Windows guest stuck on 169.254.x APIPA forever. 2. Its forward-chain accepts have the same hook+priority as ours. In nftables, all chains at a hook+priority must accept (any drop wins), so our policy=drop would block guest egress and return traffic even though libvirt's chain explicitly accepts. Add minimal carve-outs for virbr0: DHCP+DNS in input, guest egress and return traffic in forward.
-rw-r--r--etc/nftables.conf16
1 files changed, 16 insertions, 0 deletions
diff --git a/etc/nftables.conf b/etc/nftables.conf
index 610aa7e..50bb842 100644
--- a/etc/nftables.conf
+++ b/etc/nftables.conf
@@ -14,11 +14,27 @@ table inet filter {
ct state {established, related} accept comment "allow tracked connections"
iif lo accept comment "allow from loopback"
meta l4proto { icmp, icmpv6 } accept comment "allow icmp"
+
+ # libvirt's NAT bridge: let guests reach the host's dnsmasq for DHCP+DNS.
+ # libvirt manages its own forward/NAT chains but does NOT touch the input
+ # chain, so without this rule guests get no IP (DHCP packets are dropped
+ # before dnsmasq sees them).
+ iif "virbr0" udp dport { 53, 67 } accept comment "libvirt: DHCP+DNS from guests"
+ iif "virbr0" tcp dport 53 accept comment "libvirt: DNS over TCP from guests"
+
pkttype host limit rate 5/second counter reject with icmpx type admin-prohibited
counter
}
chain forward {
type filter hook forward priority filter
policy drop
+
+ # libvirt's NAT bridge: permit guest traffic to be forwarded. libvirt's
+ # own table accepts these explicitly at the same hook+priority, but with
+ # nftables a packet must be accepted by ALL chains at that priority, so
+ # our policy=drop would otherwise block all guest egress and return
+ # traffic. Mirror libvirt's accepts here for the default NAT bridge.
+ iif "virbr0" accept comment "libvirt: guest egress"
+ oif "virbr0" ct state established,related accept comment "libvirt: guest return"
}
}