forked from heavy-duty/rig
fix(bootstrap): converge the tailnet hostname on an already-joined box
`bootstrap` skips `tailscale up` when the box has already joined — which is what lets a re-run work without spending a pre-auth key. But skipping it also skipped `--hostname`, so the TAILNET name never converged: a box that joined under the wrong name (e.g. `--hostname` omitted, defaulting to the ROLE) stayed misnamed permanently, and re-running rig — the documented repair path — could not fix it. rig is convergent by contract; this was the one field that wasn't. The already-joined path now compares the current tailnet hostname against `--hostname` and reconciles it with `tailscale set --hostname` (no re-auth, no key). A failure warns rather than dying: a cosmetic name is not worth failing a bootstrap over. Safe by construction: Tailscale ACLs cannot bind a rule's dst to a hostname (it must be a tag, an IP, or a `hosts` alias — which is precisely why acl.hujson pins coolify-box to an IP), so a rename cannot silently void a grant. It also will not clobber a deliberate rename — a machine renamed in the admin console keeps that name and is no longer overridden by the device hostname. Found in the same session as the sshd first-wins bug (#6): an operator ran `bootstrap control-plane` on the prod box without `--hostname`, and no re-run could undo the resulting name. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
0c070ae5f0
commit
2181e87a0f
2 changed files with 28 additions and 0 deletions
|
|
@ -42,6 +42,14 @@ enables periodic unattended upgrades); writes an sshd hardening drop-in
|
|||
**verifies it took effect** via `sshd -T`; sets the system hostname; installs
|
||||
tailscale and joins your tailnet.
|
||||
|
||||
**`--hostname` converges both names.** On a box that has already joined,
|
||||
`bootstrap` skips `tailscale up` (so a re-run needs no pre-auth key) — but it
|
||||
still reconciles the **tailnet** hostname via `tailscale set --hostname`. Without
|
||||
that, a box which joined under the wrong name — say `--hostname` was omitted, so
|
||||
it defaulted to the *role* — stayed misnamed forever, and re-running rig, the
|
||||
documented repair, could not fix it. A machine you deliberately renamed in the
|
||||
admin console keeps that name; rig will not fight it.
|
||||
|
||||
> **Why the drop-in is `00-rig.conf` and not `99-`.** `sshd_config` is
|
||||
> **first-wins** — *"for each keyword, the first obtained value will be used"*
|
||||
> (`sshd_config(5)`) — and `Include` expands its glob in lexical order. Cloud
|
||||
|
|
|
|||
|
|
@ -170,6 +170,26 @@ if ! command -v tailscale >/dev/null 2>&1; then
|
|||
fi
|
||||
if tailscale status >/dev/null 2>&1; then
|
||||
log "tailnet already joined; skipping tailscale up (no pre-auth key needed)"
|
||||
# ...but skipping `tailscale up` also skipped --hostname, so the TAILNET name
|
||||
# never converged: a box that joined under the wrong name (e.g. --hostname
|
||||
# omitted, so it defaulted to the ROLE) stayed misnamed forever, and re-running
|
||||
# rig — the documented repair — could not fix it. rig is convergent by
|
||||
# contract; this was the one field that wasn't. `tailscale set` converges it
|
||||
# without a re-auth or a pre-auth key.
|
||||
#
|
||||
# Safe by construction here: Tailscale ACLs cannot bind a rule's dst to a
|
||||
# hostname (it must be a tag, an IP, or a `hosts` alias — which is exactly why
|
||||
# acl.hujson pins coolify-box to an IP), so a rename cannot silently void a
|
||||
# grant. It also will NOT clobber a deliberate rename: a machine renamed in the
|
||||
# admin console keeps that name, and the device hostname no longer overrides it.
|
||||
current_ts_name="$(tailscale status --peers=false 2>/dev/null | awk 'NR==1 {print $2}')"
|
||||
if [ -n "$current_ts_name" ] && [ "$current_ts_name" != "$TS_HOSTNAME" ]; then
|
||||
log "tailnet hostname is '${current_ts_name}', want '${TS_HOSTNAME}' — converging"
|
||||
tailscale set --hostname="$TS_HOSTNAME" \
|
||||
|| warn "tailscale set --hostname failed; rename '${current_ts_name}' -> '${TS_HOSTNAME}' in the admin console"
|
||||
else
|
||||
log "tailnet hostname already ${TS_HOSTNAME}"
|
||||
fi
|
||||
else
|
||||
# env override, else prompt; never touches disk
|
||||
if [ -z "${TS_AUTHKEY:-}" ]; then
|
||||
|
|
|
|||
Loading…
Reference in a new issue