Exposure: joining the tailnet #3

Closed
opened 2026-10-31 13:09:02 +00:00 by mikluko · 2 comments
Owner

Map: #1

Question

How does the pod join the tailnet? The OIDC Ingress is ruled out (see the research ticket). Requirement: it joins a configured tailnet on a configured control server, defaulting to Tailscale's (https://controlplane.tailscale.com), so Headscale or similar works without an image change.

Candidates:

  • Rex's built-in node (--tailscale, --tailscale-hostname, --tailscale-auth-key-file). rex server run --help shows no control-URL flag; whether its tsnet honours one (env or config) is unverified.
  • A tailscaled sidecar (--login-server configurable) with Rex on tailnet-serve or the tailnet address through --tailscaled-socket.

The answer names the mechanism, the config knobs (control URL, hostname, tags), where the auth key and node state live (/srv/rex, OpenBao), and who may connect (node owner or --tailnet-allow-identified).

Map: #1 ## Question How does the pod join the tailnet? The OIDC Ingress is ruled out (see the research ticket). Requirement: it joins a configured tailnet on a configured control server, defaulting to Tailscale's (`https://controlplane.tailscale.com`), so Headscale or similar works without an image change. Candidates: - Rex's built-in node (`--tailscale`, `--tailscale-hostname`, `--tailscale-auth-key-file`). `rex server run --help` shows no control-URL flag; whether its tsnet honours one (env or config) is unverified. - A `tailscaled` sidecar (`--login-server` configurable) with Rex on `tailnet-serve` or the tailnet address through `--tailscaled-socket`. The answer names the mechanism, the config knobs (control URL, hostname, tags), where the auth key and node state live (`/srv/rex`, OpenBao), and who may connect (node owner or `--tailnet-allow-identified`).
mikluko changed title from Exposure: OIDC Ingress or tailnet to Exposure: joining the tailnet 2026-10-31 15:41:40 +00:00
Author
Owner

Fact for the control-URL requirement: the Rex binary embeds tailscale.com/tsnet with (*Server).getControlURL and the TS_CONTROL_URL env knob. In tsnet that function returns Server.ControlURL, else TS_CONTROL_URL, else https://controlplane.tailscale.com. So the built-in node (--tailscale) should follow TS_CONTROL_URL with no flag. Checked in the macOS build's strings only; not yet confirmed on the Linux package or against a non-Tailscale controller.

Fact for the control-URL requirement: the Rex binary embeds `tailscale.com/tsnet` with `(*Server).getControlURL` and the `TS_CONTROL_URL` env knob. In tsnet that function returns `Server.ControlURL`, else `TS_CONTROL_URL`, else `https://controlplane.tailscale.com`. So the built-in node (`--tailscale`) should follow `TS_CONTROL_URL` with no flag. Checked in the macOS build's strings only; not yet confirmed on the Linux package or against a non-Tailscale controller.
mikluko self-assigned this 2026-10-31 16:12:49 +00:00
Author
Owner

Answer

  • Tailnet: my Tailscale SaaS tailnet. TS_CONTROL_URL is a knob, unset by default (Tailscale's control server); Headscale is gone from saraksh.
  • Mechanism: Rex's built-in node, rex server run --tailscale. No sidecar. That tsnet honours TS_CONTROL_URL is verified only from binary strings; the manifests ticket confirms it, with a tailscaled sidecar as fallback.
  • Hostname: kuberex by default, overridable with TS_HOSTNAME.
  • Identity: untagged node owned by my account; Rex's default admits only the node owner. No ACL change.
  • Join key: one-time, pre-authorized, non-ephemeral. A secret parameter: a file passed to --tailscale-auth-key-file, path in TS_AUTHKEY_FILE. On saraksh, Secret rex-tailscale from an ExternalSecret on OpenBao kv/k8s/agents/rex-tailscale.
  • Node state: under --state-dir on /srv/rex; restarts reuse the identity, the key is needed only at first enrollment.
  • Key expiry: disabled for kuberex in the admin console right after the first enrollment.
## Answer - **Tailnet:** my Tailscale SaaS tailnet. `TS_CONTROL_URL` is a knob, unset by default (Tailscale's control server); Headscale is gone from `saraksh`. - **Mechanism:** Rex's built-in node, `rex server run --tailscale`. No sidecar. That tsnet honours `TS_CONTROL_URL` is verified only from binary strings; the manifests ticket confirms it, with a `tailscaled` sidecar as fallback. - **Hostname:** `kuberex` by default, overridable with `TS_HOSTNAME`. - **Identity:** untagged node owned by my account; Rex's default admits only the node owner. No ACL change. - **Join key:** one-time, pre-authorized, non-ephemeral. A secret parameter: a file passed to `--tailscale-auth-key-file`, path in `TS_AUTHKEY_FILE`. On `saraksh`, Secret `rex-tailscale` from an ExternalSecret on OpenBao `kv/k8s/agents/rex-tailscale`. - **Node state:** under `--state-dir` on `/srv/rex`; restarts reuse the identity, the key is needed only at first enrollment. - **Key expiry:** disabled for `kuberex` in the admin console right after the first enrollment.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Reference
mikluko/kuberex#3
No description provided.