#!/usr/sbin/nft -f # Forward the tailnet entry point to the edge guest. # # This is the ONLY lab traffic rule the physical host carries. Everything else # that used to live here — nginx config, certificates, certbot, the deploy hook # — now lives on kc-lab-edge and is destroyed with it. # # DNAT only, never SNAT. The guests' default route is the host, so replies come # back through here and conntrack reverses the translation on its own. Adding a # masquerade would rewrite the source and the edge would see 192.168.122.1 for # every client — which would silently invalidate the X-Forwarded-For contract # that this lab measures. # # PREROUTING nat runs before the routing decision, so this wins over any local # socket on :80/:443. That makes the cutover atomic and the rollback a single # `nft delete table ip lab_edge`. table ip lab_edge delete table ip lab_edge table ip lab_edge { chain prerouting { type nat hook prerouting priority dstnat; policy accept; iifname "tailscale0" tcp dport { 80, 443 } dnat to 192.168.122.10 } # libvirt's own forward rules accept RELATED,ESTABLISHED into the guest # subnet but not a NEW inbound connection. This runs ahead of them. chain forward { type filter hook forward priority filter - 10; policy accept; ip daddr 192.168.122.10 tcp dport { 80, 443 } ct state new accept } }