halkyon/deploy/forward/wg-halkyon.nft
Tizian 「ティツィアーン」 29844c7fa6
feat(deploy): halkyon.li's forward through ramiel and its host at home (ADR 0039)
ramiel's HAProxy passes halkyon.li's TLS connections, unopened, through a
WireGuard tunnel to the instance at home, with the visitor's address in a
PROXY header, and everything else to ramiel's own Caddy, moved to the
loopback. Each end's nftables table lets the tunnel carry HAProxy's 443 and
the SSH jump's 22 alone, and nothing from home to ramiel.

The host at home: sshd with keys alone, the root disk unlocked over SSH at
boot (dropbear-initramfs, D20), Docker's and containerd's data bind-mounted
from the HDD, and home's end of the tunnel before Docker. An instance behind
the forward (compose.forwarded.yaml) publishes 443 on the tunnel's address
alone, trusts the PROXY header from ramiel alone, and gets its certificates
through TLS-ALPN, without HTTP/3.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-11-08 19:59:39 +01:00

39 lines
1.5 KiB
Text

# The rules around ramiel's end of the tunnel to halkyon.li (ADR 0039, D9, D17), loaded
# by wg-quick as the tunnel comes up and deleted as it goes (wg-halkyon.conf), so they
# live exactly as long as it. As /etc/wireguard/wg-halkyon.nft on ramiel (root, 0600).
#
# A table of their own, apart from ufw's: a packet the table drops is dropped whatever
# ufw says, and what it accepts still meets ufw's rules after it.
#
# - Into the tunnel: new connections to home's Caddy (443, from HAProxy) and sshd (22,
# the jump from away), then their replies; nothing else.
# - From the tunnel: replies alone, so a taken-over home reaches neither ramiel's sshd
# nor Forgejo nor anything else listening here.
# - Through the tunnel: nothing; ramiel routes nothing between it and anywhere else.
#
# IPv4 alone: the tunnel carries no IPv6 (D8).
# Made and deleted first, so loading this again replaces it whole.
table inet halkyon_tunnel {}
delete table inet halkyon_tunnel
table inet halkyon_tunnel {
chain input {
type filter hook input priority filter - 1; policy accept;
iifname "wg-halkyon" ct state established,related accept
iifname "wg-halkyon" drop
}
chain output {
type filter hook output priority filter - 1; policy accept;
oifname "wg-halkyon" ct state established,related accept
oifname "wg-halkyon" ip daddr 10.61.97.2 tcp dport { 22, 443 } accept
oifname "wg-halkyon" drop
}
chain forward {
type filter hook forward priority filter - 1; policy accept;
iifname "wg-halkyon" drop
oifname "wg-halkyon" drop
}
}