tstest, cmd/tta: add Tailscale SSH end-to-end VM test

Add TestTailscaleSSH to tstest/natlab/vmtest, exercising the Tailscale
SSH server (tailscale up --ssh, not a system sshd) end to end: an
Ubuntu client node SSHes over the tailnet into an Ubuntu server node
as both root and a non-root user, and into a gokrazy node.

The gokrazy sessions exercise the gokrazy special cases in the SSH
code: util/osuser hard-codes the login shell to serial-busybox ash and
synthesizes a root user when lookup fails (so any username works and
becomes root, unlike Ubuntu where nonexistent users are rejected), and
the incubator's findSU refuses su on gokrazy, handling sessions
in-process.

To support this, testcontrol gains an SSHPolicy field that's sent in
MapResponses along with the CapabilitySSH node capability, tta's /up
handler accepts an ssh=true parameter, and vmtest gains a
TailscaleSSH node option that wires the two together with a
permissive any-principal policy.

Updates tailscale/corp#44813
Updates #13038

Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Change-Id: I3f6b9c41a72e05d8c94dd7f6ab1937cf24b81c92
This commit is contained in:
Brad Fitzpatrick
2026-07-13 15:04:51 -07:00
committed by Brad Fitzpatrick
parent 2506ede862
commit c436dec43c
4 changed files with 190 additions and 0 deletions
+3
View File
@@ -198,6 +198,9 @@ func main() {
if r.URL.Query().Get("accept-routes") == "true" {
args = append(args, "--accept-routes")
}
if r.URL.Query().Get("ssh") == "true" {
args = append(args, "--ssh")
}
serveCmd(w, "tailscale", args...)
})
ttaMux.HandleFunc("/set", func(w http.ResponseWriter, r *http.Request) {