From db25302c85b1123176d4a997c94d77c90c88f6ed Mon Sep 17 00:00:00 2001 From: mikl Date: Tue, 29 Sep 2026 01:49:11 +0300 Subject: [PATCH] fix(heather): restore inbound Docker access with WAN return routing --- hosts/heather/astrnet.nix | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/hosts/heather/astrnet.nix b/hosts/heather/astrnet.nix index 1113df1..bc1a805 100644 --- a/hosts/heather/astrnet.nix +++ b/hosts/heather/astrnet.nix @@ -33,6 +33,10 @@ let # to reach their own endpoints through the mesh default). wanTable = "100"; wgMark = "0x4d49"; + # Mark only WAN connections forwarded to published Docker ports. Their + # replies originate from a container, so the `from wanIp4` rule cannot + # select the WAN until after routing/NAT. Restore wgMark on the reply. + dockerInboundMark = "0x4d4a"; wanRules = [ { fam = "-4"; sel = "fwmark ${wgMark}"; } { fam = "-4"; sel = "from ${wanIp4}"; } @@ -93,6 +97,12 @@ in { nft list table inet astrnet_guard >/dev/null 2>&1 && nft delete table inet astrnet_guard nft -f - <<'RULES' table inet astrnet_guard { + chain prerouting { + type filter hook prerouting priority -150; policy accept; + # Reply packets from Docker inherit the connection mark before the + # routing decision; only public-WAN inbound connections get this mark. + iifname "br-*" ct mark ${dockerInboundMark} meta mark set ${wgMark} + } chain input { type filter hook input priority -150; policy accept; # Full inbound access from AstrNet to Heather, IPv4 and IPv6. @@ -102,7 +112,12 @@ in { } chain forward { type filter hook forward priority -150; policy accept; - # Only replies to Docker-initiated connections, never new mesh transit. + # A public connection DNATed by Docker must return via the public WAN, + # not the AstrNet default. This does not affect Docker-originated egress. + iifname "enp7s0" oifname "br-*" ct status dnat ct mark set ${dockerInboundMark} + # Allow mesh peers to reach only Docker-published ports (DNAT), not + # arbitrary forwarded destinations. Host services use the input chain. + iifname { "wg-mic-der", "wg-mic-bd8" } oifname "br-*" ct status dnat accept iifname { "wg-mic-der", "wg-mic-bd8" } ct state established,related accept iifname { "wg-mic-der", "wg-mic-bd8" } drop }