Tailscale SSH none-Auth Root Login Looks Like a Vulnerability — It Usually Isn't¶
A verbose SSH probe (ssh -v) against a fleet host can show Authenticated using "none" for a root login — no key, no password. The first read is "unauthenticated root shell, total compromise." On a host running Tailscale SSH, this is normal, documented behavior, not a broken sshd.
Symptoms¶
ssh -v -o BatchMode=yes -o PubkeyAuthentication=no root@<host>succeeds and returns a working shell.- The verbose log shows
Authenticated using "none"rather thanpublickeyorpassword. - The host's own
sshd_configlooks correctly locked down (PermitRootLogin without-password,PasswordAuthentication no,PubkeyAuthentication yes) — which makes the result more alarming, not less, at first glance. - Other hosts in the same fleet, probed the same way, correctly return
Permission denied (publickey).
Root Cause¶
Tailscale SSH intercepts the connection before it reaches the host's sshd at all. Authentication happens at the tailnet layer — Tailscale verifies the connecting device's tailnet identity and checks it against the Tailscale ACL's ssh rules. If the ACL grants access, Tailscale hands off an already-authenticated session; the SSH client-side handshake reports none because no separate key or password exchange occurred (there was nothing left for sshd to authenticate).
This means: on a host with Tailscale SSH enabled, sshd_config's PermitRootLogin / PasswordAuthentication / PubkeyAuthentication settings are irrelevant to Tailscale-SSH-mediated connections — they only govern connections that reach sshd through the normal network path (LAN, direct SSH before Tailscale's interception). A host can have a textbook-perfect sshd_config and still show none auth over Tailscale, because Tailscale SSH never lets the request get that far.
How to Confirm This Is What's Happening (Not a Real Breach)¶
-
Check whether Tailscale SSH is actually enabled on the host:
"RunSSH": trueconfirms Tailscale SSH is on for that host. -
Confirm it isn't systemic — probe a host you know is key-only (Tailscale SSH disabled) the same way. It should correctly reject with
Permission denied (publickey). If every host in the fleet showsnone, something is genuinely wrong; if only the Tailscale-SSH-enabled ones do, this is expected. -
Check where the probe originated from. A probe run from a Tailscale-routed shell (an agent/MCP tool with tailnet access, another tailnet device, etc.) will be admitted exactly like any other tailnet member — that's the ACL working as designed, not a bypass.
The Real Control Point¶
Once Tailscale SSH is confirmed as the mechanism, sshd_config stops being the thing to audit. The Tailscale ACL is now the only gate between a tailnet member and root on that host. Two things matter:
- Who is in the tailnet — every device/user with tailnet membership is a candidate for whatever the ACL's
sshrules allow. On a single-operator personal tailnet this is a much smaller blast radius than a shared/team tailnet. - What the ACL's
sshblock actually grants — checksrc,dst, andusersin the ACL policy. An overly broadusers: ["root"]grant fromsrc: ["autogroup:member"]to every host is the equivalent of handing out root SSH to everyone on the tailnet.
Treat a none-auth finding as a prompt to review the ACL, not as proof of a broken host.
Notes¶
BatchModesuccess is not proof of key auth. A fleet audit that only checks "doesssh -o BatchMode=yes <host> 'id'succeed" cannot distinguish realpublickeyauth from Tailscale-SSHnoneauth — both return success. If planning to revoke a key fleet-wide, first confirm per-host whether Tailscale SSH is also enabled; revoking the key would not lock out a host where Tailscale SSH grants access independently.- This is the same reasoning that applies to Tailscale SSH: Unexpected Re-Authentication Prompt — Tailscale SSH's
action: acceptvsaction: checkACL setting governs the experience, and the same ACL block is the thing to inspect for both symptoms.