Deploy Headscale as the non-HTTP TCP connectivity layer (replaces mesh0) #35
Labels
No labels
blocked
conflicted
curated
in-progress
in-review
needs-decision
No milestone
No project
No assignees
2 participants
Due date
No due date set.
Dependencies
No dependencies set
Reference
larandar/flaky-mesh#35
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Stable ID: FM-HEADSCALE
Source: owner ruling 2026-08-06 (#32 mesh decommission)
Disposition: open — spike, gated on one container check
Blocked by: nothing
Decision
Headscale replaces mesh0 as the non-HTTP TCP connectivity layer. Every host
gets a stable
100.x.y.zaddress that bypasses Cloudflare entirely.Resolves: SSH discovery without CF (#32 Q2), monitoring scraping path, sops
key trust transport, mobile client connectivity (the original mesh0 failure).
Why Headscale
headscaleis in nixpkgs;services.headscalemodule existsservices.tailscale) on each host point at the self-hostedlogin server — no SaaS dependency
property mesh0 lacked — it died on mobile)
Scope
Headscale control server. Deploy on bifrost (or a small VPS).
services.headscale.enable, config:server_url,base_domain,DERP map, listen addresses. One flake module.
Per-host tailscale client.
services.tailscale.enable+extraUpFlags = ["--login-server" "https://headscale.et0.pw"]on eachfleet host. Pre-auth keys minted via headscale CLI.
just sshupdate. Today resolves via tofu output. Adds headscaleaddress as the primary path, tofu as fallback. Known_hosts survives —
stable address, same host key.
DNS.
headscale.et0.pwfor the control server. MagicDNS for host names(optional —
100.x.y.zaddresses work directly).Mobile. Tailscale app on phone, pointed at custom login server. This is
the connectivity that mesh0 failed to provide.
The one check that gates everything
Does
/dev/net/tunexist in a vpsFree container?tailscaled needs either
/dev/net/tun(kernel networking) or userspacenetworking mode (
--tun=userspace-networking). The container may not exposethe tun device — same class of constraint that killed nested KVM
(migration plan §Phase 3.4).
for other hosts (subnet router mode unavailable). May be acceptable for
SSH/scraping but limits the overlay's utility.
Five-minute check on a running container:
ls -la /dev/net/tun.Non-scope
Headscale is for non-HTTP TCP only.
Authelia authenticates users.
Acceptance
/dev/net/tunavailability checked on a vpsFree containerservices.headscaledeployed and serving pre-auth keysjust sshworks over headscale addresstraffic flows)
just checkgreenProvenance
Owner ruling 2026-08-06 during mesh decommission (#32) SSH discovery
discussion. Freenet evaluated and ruled out (content routing, not TCP tunnel).
Headscale is the known-quantity overlay that solves the discovery problem
mesh0 was meant to solve, with mobile properties mesh0 lacked.
Grooming state: Superseded
Evidence: lar.ad/flake-ops#239 (
Epic: Deploy vegr overlay (Nebula) — Phase 1 v4-safety, ratified 2026-08-17). Impl pick swapped Headscale → Nebula; hostile-mobile explicitly out of scope; heimdallr as lighthouse re-ratified (seevegr R6and this repo's #165 provenance).Body edited in place to prepend the supersession banner and updated Decision; historical Headscale rationale preserved beneath per grill rule 5 (preserve historical decisions as provenance).
Ticket disposition: stays open until vegr epic #239 ships. FM-HEADSCALE stable ID stays owned here.