Repository navigation
Tailscale 1.104.2 for TS-2026-013 (eMudhra intermediates) #65
Description
Tailscale security bulletin TS-2026-013 (published 2026-10-21; tracked on CannObserv/provisioner#77). The private keys for eight eMudhra TLS intermediates leaked. Tailscale's client trusts the OS root store, so anyone holding one of those keys could pass as a TLS site "with no warning". The fix is Tailscale v1.104.2 or later. It's built with Go 1.27.3, which distrusts those intermediates even when they're still in the system store. No workaround is given. Mesh traffic (WireGuard, node keys) isn't affected.
The same compromise, beyond Tailscale: exe.dev's advisory (https://exe.dev/security/emudhra-compromise, 2026-10-20) comes with a remediation command, ssh exe.dev remediate-emudhra-compromise, run from the Mac. It fixes the system store and the tools that bundle their own roots (uv, claude, opencode, headless-shell). It doesn't reach a Python venv's certifi, which httpx and requests use instead of the system store. On co-provisioner that certifi still trusted the emSign chain afterwards (CannObserv/provisioner#79; fix at certifi ≥ 2026.10.19, per CannObserv/address-validator#343). A process started before the fix keeps the old trust until it restarts. This upgrade restarts tailscaled.
For this host
- The canary. co-processor goes first. Its result clears the service nodes to go.
- co-processor is a bus participant: afterwards, check its consumer reconnected, and ask broker for a bus-health reading.
- No
.skills/patching-hostsknob in this repo (read 2026-10-22), so this is a hand run oftailscalealone, provisioner#60's shape:The version is pinned andtailscale version --daemon # before sudo apt-get update apt-get install -s --only-upgrade tailscale=1.104.2 # expect: tailscale alone sudo NEEDRESTART_MODE=l apt-get install --only-upgrade tailscale=1.104.2 </dev/null tailscale version --daemon; systemctl show tailscaled -p MainPID,ActiveEnterTimestamp
-yis left out, so apt aborts rather than doing more than the simulation showed.
What to expect (measured on co-provisioner, provisioner#60 and #77)
- The package's postinst restarts
tailscaled. The tailnet was down for about 2 s: 2.0 s for 1.102.4 → 1.104.1, and 2.2 s for 1.104.1 → 1.104.2. - Listeners bound to the tailnet address stayed bound. An established tailnet TCP socket survived once (#57 docs: a dispatch-essence change is notice, not coordination #60) and timed out once (Adopt host patching: needrestart l, posture scheduled, first window #77). In the timeout case, the client reconnected after one backoff. Expect either outcome.
NEEDRESTART_MODE=lkeeps needrestart from restarting anything else. PID1's own lines may be missing from the journal (provisioner#62), so prove the restart fromsystemctl show tailscaled -p MainPID,ActiveEnterTimestamp.
Done when
-
tailscale version --daemonreports 1.104.2 or later for client and daemon, and Go 1.27.3 or later. - The host's health checks pass afterwards.
- A comment on CannObserv/provisioner#77 gives the version before and after and the UTC time. That issue's closing table is built from them.
The order across the cohort is in provisioner#77: co-processor first, as the canary; then each service node, each checked with the broker's bus-health probe; co-broker last.
Activity
gregoryfoster commentedon Oct 22, 2026
Hand-off from the burn-down epic #24, 2026-10-22. This is next, ahead of everything else: it is a security fix, and co-processor is the cohort's canary in CannObserv/provisioner#77's order, so every other service node waits on its result. Ops only: a hand run, with no repo change and no deploy. #66 (certifi in Processor's venv, the same compromise) comes right after, as its own PR and deploy. Don't combine them: one restart at a time, each checked.
Pre-flight, measured by the coordinator at 2026-10-22T23:20Z:
tailscale version --daemon: client and daemon 1.102.4, Go 1.26.6. That is two minors behind, where co-provisioner went from 1.104.1.apt-cache policy tailscale: candidate 1.104.2.tailscaled:MainPID=292, up since 2026-10-03T16:53:19Z.DropInPathsis/etc/systemd/system/tailscaled.service.d/90-processor-oom.conf, andOOMScoreAdjust=-950(DEPLOYMENT.md § Tailscale DNS → tailscaled's OOM rank).ca-certificates20260816ubuntu0.24.04.1). Systemcurlrejects the advisory's test host. The venv's certifi doesn't, but that is certifi ≥ 2026.10.19: the live venv still trusts the eMudhra-compromised emSign G3 chain #66.The run: the issue's commands, as written, as
exedevwithsudo. Simulate first. If the simulation shows anything besidestailscale, stop and report it.What can bite on this host specifically:
/etc/resolv.confand points it at MagicDNS (100.100.100.100), so for about 2 s nothing on the host resolves. Afterwards, check that/etc/resolv.confstill points at100.100.100.100, thatgetent hosts brokeranswers, and thattailscale statuslistsbroker./etc/systemd/system/tailscaled.service.d/, but check:systemctl show tailscaled -p DropInPaths,OOMScoreAdjust, and/proc/<new MainPID>/oom_score_adj=-950.processoris still active withNRestarts=0;liveness check-in,checkin 202) lands within 5 min;ack: complete). Traffic is sparse, so this may take an hour or more. Note the wait rather than block the provisioner#77 comment on it.systemctl show tailscaled -p MainPID,ActiveEnterTimestamp, not the journal (provisioner#62).Health checks for "Done when" on this host:
tailscale version --daemonshows client and daemon ≥ 1.104.2, Go ≥ 1.27.3;MainPID;broker;processoris active,NRestarts=0, and liveness isok;ok/202 (it calls GitHub, so this also proves DNS and egress);Gates (operator):
Known limits to state: if no command arrives before the close, say that the post-upgrade ack wasn't observed, and that the coordinator will confirm it at the next check-in.
Out of scope:
.skills/patching-hostsadoption here (the issue notes there's no knob).Ship: no branch or PR: this changes the host only. Record the commands and output in a comment on #65, post the approved provisioner#77 comment, then close #65 with each box and its evidence.
Kickoff prompt:
gregoryfoster commentedon Oct 22, 2026
Run, 2026-10-22, as
exedevwithsudo: 1.102.4 → 1.104.2. tailscaled restarted at 23:40:29Z. The issue's commands, as written.Before (23:39:42Z): client and daemon
1.102.4,go1.26.6;tailscaledMainPID=292,ActiveEnterTimestamp=2026-10-03 16:53:19;OOMScoreAdjust=-950, drop-in90-processor-oom.conf; candidate1.104.2.Simulation:
tailscalealone.Real run (
NEEDRESTART_MODE=l, pinned, no-y), 23:40:24.03Z → 23:40:33.41Z, exit 0:After:
systemctl showMainPID292 → 1080778,ActiveEnterTimestamp23:40:29Zcontrol: mapRoutine: exiting23:40:28.099Z →Starting -> Running23:40:30.393ZDropInPaths=…/90-processor-oom.conf,OOMScoreAdjust=-950,/proc/1080778/oom_score_adj=-950/etc/resolv.conf→100.100.100.100;getent hosts broker→100.97.91.19;tailscale statuslistsbroker(direct)processorMainPID=960780(unchanged since 2026-10-21),NRestarts=0at 23:51:04Z; one established connection tobroker:6379journalctl -u processor -p warninghas no entriesok: noliveness check-in failedorconsume loop staleacross the two ticks after the restart. It logs only on failure or recovery (liveness.py), so silence is theokdrift checkkind: ok,checkin: 202at 23:41:12Z (GitHub, so DNS and egress too)ack: completeat 23:44:02Z,message_id 1792712641422-0,command_id 01M5K002VVHHSDDXE4KDCRDD9P, attempt 1Pending: the provisioner#77 comment and the broker's bus-health reading. Both are cross-repo and await the operator's approval.
gregoryfoster commentedon Oct 23, 2026
Done. Closing with the evidence for each box:
tailscale version --daemon: client and daemon1.104.2,go1.27.3. Before, it was1.102.4,go1.26.6(issuecomment-6353911059).MainPID292 → 1080778, 23:40:29Z); its OOM drop-in is in effect (-950on the new PID); MagicDNS resolvesbroker;processorstayed active withNRestarts=0and logged no WARNING or ERROR; livenessok; driftok/202 at 23:41:12Z; the next command acked at 23:44:02Z (issuecomment-6353911059).Bus-health reading: asked of broker on CannObserv/broker#119 (issuecomment-6354166528). It isn't in yet. The coordinator picks it up at the next check-in on #24.
Next: #66, certifi in Processor's venv, as its own PR and deploy.