If you turned on tailscale set --ssh so you'd never have to copy another public key around your homelab, you have an update to install. The Tailscale SSH vulnerabilities from the "Tailworm" report are fixed in Tailscale v1.104.4. The one that matters most let an authenticated peer reach root-only Unix sockets through SSH forwarding, including the Docker socket and the tailscaled local API. Anyone who can talk to either of those owns the box.
For the facts I've stuck to Tailscale's own bulletins and docs, and I point out where the researcher's claims go further than Tailscale's. After that there's a two-command check for your nodes and the five settings I'd look at tonight.
The Tailworm timeline
- October 24: Erica Windisch of Cyberdione Labs publishes "Tailworm", 11 findings against Tailscale 1.104.2 and headscale 0.29.5, tested in her lab October 22 to 24 (Startup Fortune, which dates the release October 25). She sent the findings and a proof of concept to Tailscale's security contact first, but didn't wait for coordinated disclosure. Tailscale says the report reached it on the morning of Saturday, October 24, and went public two hours later.
- October 26: Tailscale posts an investigation and remediation update. It says "Most of the Tailscale SSH issues we've identified concern privilege escalation" and that "In some circumstances" an already-authorized SSH user "may be able to perform actions beyond the permissions of their configured local user." It also says "we're not recommending that everyone disable Tailscale SSH." Four security bulletins, TS-2026-014 through TS-2026-017, carry the same date.
- October 28: Tailscale's findings and fixes post points everyone to v1.104.4. None of the bulletins lists a CVE ID.
The "worm" framing is the researcher's, not Tailscale's. Her chain starts with control of one approved device plus an SSH rule that permits forwarding. A race in Tailscale SSH's Unix socket forwarding gets root on another machine, and from there the attacker mints a new enrolment key and adds a rogue device the tailnet trusts. Tailscale's wording is narrower: "the vulnerabilities don't allow an unauthenticated attacker to connect to arbitrary Tailscale SSH servers," and exploitation "requires an existing foothold on an authorized peer in the tailnet."
Neither account is wrong. Nobody on the internet walks into your tailnet with this, but if your kid's laptop or that old Raspberry Pi running a sketchy container is a peer with SSH rights, that device is the foothold.
TS-2026-014 to TS-2026-017: what each bulletin means
| Bulletin | What broke | You're affected if | Interim mitigation |
|---|---|---|---|
| TS-2026-014 | Tailscale SSH Unix socket forwarding (ssh -L / -R) could reach root-only sockets (Docker, tailscaled local API) | Tailscale SSH is on and your policy allows local or remote forwarding | TS_SSH_DISABLE_FORWARDING=1 |
| TS-2026-015 | Unbounded memory growth in SSH session handling can get tailscaled OOM-killed and drop all networking on the node | You run the Tailscale SSH server (needs an authenticated, policy-allowed session) | None listed |
| TS-2026-016 | tailscale serve Unix backends could reach privileged sockets, including the local API ("full node takeover") | A local operator can write Serve config, or local users can write to configured backend paths | None listed |
| TS-2026-017 | HTTP/2 streams sharing serve state could apply one mount's Tailscale-App-Capabilities to another | Serve with TLS and two or more mounts with different capability requirements | None listed |
The fix for all four is 1.104.4 or newer. The bulletins don't say which older versions are affected, so treat everything before 1.104.4 as vulnerable.
Am I affected? A 60-second check
Run this on every box you own:
tailscale version
tailscale debug prefs | grep -i runsshIf the version is below 1.104.4 and RunSSH is true, that node is running the vulnerable Tailscale SSH server. If you only use stock OpenSSH over your tailnet, with sshd listening on the Tailscale IP and your own keys, the SSH bugs don't touch you. Several people on Hacker News argued that describes most users, though nobody had numbers. For TS-2026-016 and -017, also check whether you use tailscale serve.
For headscale users: the bugs are in tailscaled on your nodes, not in the control server. Self-hosting coordination doesn't get you out of updating clients.
The 5 settings to check tonight
1. Update to 1.104.4 and turn on auto-update
sudo tailscale update
tailscale version # want 1.104.4 or later
sudo tailscale set --auto-updatetailscale update doesn't work on every platform. If you installed from a distro package, apt upgrade tailscale or the equivalent does the same job. Mike Shaver, Tailscale's VP of engineering, told people on Reddit to keep automatic updates on and restrict who can forward ports rather than rip out Tailscale SSH, and for a homelab I agree.
2. Kill SSH forwarding if you don't use it
This is Tailscale's interim mitigation for TS-2026-014. I'd keep it after patching too, because forwarding was the route into root-only sockets. On a systemd host:
sudo systemctl edit tailscaled
# add:
# [Service]
# Environment=TS_SSH_DISABLE_FORWARDING=1
sudo systemctl restart tailscaledTailscale SSH stays on; only forwarding goes. If you've never typed ssh -L or -R to a Tailscale SSH host, you won't notice.
3. Audit your ssh rules, especially autogroup:nonroot
Open the policy file in the admin console and read every entry in "ssh". The Tailscale SSH docs have a warning people skim past: if you change dst away from autogroup:self and keep autogroup:nonroot in users, "anyone permitted by the src setting will be able to SSH in as any nonroot user on the dst device."
This is the kind of rule I'd want instead:
"ssh": [
{
"action": "check",
"src": ["group:admins"],
"dst": ["tag:servers"],
"users": ["deploy"],
"checkPeriod": "12h"
}
]Name the users and groups. Delete any rule that exists because you were testing something in 2023. Clients pick up rule changes within seconds, and revoking a rule ends existing SSH sessions, so make sure you have another way into the box before you edit.
4. Use check mode on anything you care about
Tailscale's post-fix advice is to consider check mode for sensitive systems. With "action": "check" the user has to re-authenticate with your identity provider every checkPeriod. The default is 12 hours; the range is 1 minute to 168 hours. A stolen laptop with a live Tailscale session no longer comes with a free shell on your NAS.
Be careful with "checkPeriod": "always", though. It can trip up Ansible and anything else that opens lots of SSH connections quickly, so give machine-to-machine access its own tightly scoped accept rule.
5. Look for a foothold that's already been used
The researcher's chain ends with a minted enrolment key and a new device. So check:
- The admin console's configuration audit logs for auth keys you didn't create and policy edits you didn't make.
tailscale statusfor nodes you don't recognise.journalctl -u tailscaledon your SSH hosts for sessions at times you were asleep.
If something turns up, revoke the key, remove the device and rotate node and SSH host keys with tailscale up --ssh --force-reauth.
Should you go back to plain OpenSSH keys?
For a homelab with fewer than ten servers, I would. Keep Tailscale for the network and use OpenSSH for the shell.
Tailscale SSH puts authentication, sessions and forwarding inside a daemon that runs as root. That's extra code on a privileged path, and TS-2026-014 is exactly what goes wrong there. OpenSSH has had decades of people attacking that same path. The boring setup works: sshd bound to the Tailscale IP, PasswordAuthentication no, an ed25519 key per device. Tailscale's ACLs still decide who can reach port 22, so you get two independent layers.
# /etc/ssh/sshd_config.d/tailnet.conf
ListenAddress 100.x.y.z
PasswordAuthentication no
PermitRootLogin noOne gotcha: if sshd starts before tailscaled has brought up its address, the bind fails at boot. Order ssh.service after tailscaled.service (or set net.ipv4.ip_nonlocal_bind=1) and test a reboot before you rely on it.
Get OpenSSH working over the tailnet first, and only then turn Tailscale SSH off with tailscale set --ssh=false.
Tailscale SSH still earns its place in some setups. If you depend on check mode tied to your IdP, session recording, or revoking a whole team's access from one policy file, OpenSSH won't give you that for free. Patched, with forwarding off and check mode on, it's a reasonable tool.
On the disclosure fight: Tailscale went from a public report on October 24 to bulletins on October 26 and a fixed release by October 28. That's quick. The bulletins still don't list affected version ranges or CVEs, and "In some circumstances" does a lot of work in the first update. Next time I'd like to be told exactly which versions to hunt for.
So, for the comments: do you still trust Tailscale SSH on your homelab after this, or are you moving back to plain OpenSSH keys? And if you're staying, is your ssh rule set actually any tighter than the default?
