From 115c508c0ecfa4b255de854d433ba02eaf029b29 Mon Sep 17 00:00:00 2001 From: sommerfeld Date: Fri, 22 May 2026 14:28:18 +0100 Subject: fix(nftables): waydroid DHCP/DNS ingress, drop manual NAT table Mirror the libvirt pattern by accepting DHCP+DNS on waydroid0 so the Android container's DhcpClient can lease an IP from dnsmasq. Remove the manual ip nat MASQUERADE table: waydroid-container installs its own MASQUERADE rule via iptables-nft compat, so the explicit table is redundant (and was clobbering anything else in ip nat via the destroy table). --- etc/nftables.conf | 28 +++++++++------------------- 1 file changed, 9 insertions(+), 19 deletions(-) diff --git a/etc/nftables.conf b/etc/nftables.conf index c1a37c5..e4f68ed 100644 --- a/etc/nftables.conf +++ b/etc/nftables.conf @@ -22,6 +22,12 @@ table inet filter { iifname "virbr0" udp dport { 53, 67 } accept comment "libvirt: DHCP+DNS from guests" iifname "virbr0" tcp dport 53 accept comment "libvirt: DNS over TCP from guests" + # Waydroid's NAT bridge: same pattern as libvirt. The Android container's + # DhcpClient broadcasts DHCPDISCOVER on waydroid0; without this rule it's + # dropped before dnsmasq sees it and the container never gets an IP. + iifname "waydroid0" udp dport { 53, 67 } accept comment "waydroid: DHCP+DNS from container" + iifname "waydroid0" tcp dport 53 accept comment "waydroid: DNS over TCP from container" + pkttype host limit rate 5/second counter reject with icmpx type admin-prohibited counter } @@ -39,26 +45,10 @@ table inet filter { iifname "virbr0" accept comment "libvirt: guest egress" oifname "virbr0" ct state established,related accept comment "libvirt: guest return" - # Waydroid's NAT bridge: same pattern as libvirt. Unlike libvirt, waydroid - # does NOT install its own MASQUERADE rule reliably (it tries via the - # legacy iptables binary which isn't present), so we both forward-accept - # here AND install MASQUERADE in the ip nat table below. + # Waydroid's NAT bridge: same pattern as libvirt. Waydroid's container + # service installs MASQUERADE itself via iptables-nft compat, so no + # explicit nat table is needed here -- only the forward-chain accepts. iifname "waydroid0" accept comment "waydroid: guest egress" oifname "waydroid0" ct state established,related accept comment "waydroid: guest return" } } - -# NAT for waydroid's Android container. The waydroid-container service is -# supposed to add this via iptables but ships only the iptables-legacy code -# path; on a pure nftables host (no iptables-nft compat shim active) the rule -# never lands. Declaring it here is deterministic and survives reloads. -destroy table ip nat -table ip nat { - chain postrouting { - type nat hook postrouting priority srcnat - policy accept - - ip saddr 192.168.240.0/24 oifname != "waydroid0" masquerade \ - comment "waydroid: MASQUERADE container egress" - } -} -- cgit v1.3.1