#!/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 } # No forward chain here on purpose. libvirt's guest_input chain ends in # `oif virbr0 ... reject`, and an accept in an earlier base chain does NOT # stop a later chain from rejecting — that is nftables, not iptables. The # hole is punched inside libvirt's own chain by the unit's ExecStartPost. }