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:
committed by
Brad Fitzpatrick
parent
2506ede862
commit
c436dec43c
@@ -428,6 +428,7 @@ type Node struct {
|
||||
vnetNode *vnet.Node // primary vnet node (set during Start)
|
||||
agent *vnet.NodeAgentClient
|
||||
joinTailnet bool
|
||||
runSSH bool // true to enable the node's Tailscale SSH server
|
||||
noAgent bool // true to skip TTA agent setup (e.g. macOS VMs without TTA)
|
||||
advertiseRoutes string
|
||||
snatSubnetRoutes *bool // nil means default (true)
|
||||
@@ -458,6 +459,8 @@ func (e *Env) AddNode(name string, opts ...any) *Node {
|
||||
case nodeOptNoTailscale:
|
||||
n.joinTailnet = false
|
||||
vnetOpts = append(vnetOpts, vnet.DontJoinTailnet)
|
||||
case nodeOptTailscaleSSH:
|
||||
n.runSSH = true
|
||||
case nodeOptNoAgent:
|
||||
n.noAgent = true
|
||||
case nodeOptAdvertiseRoutes:
|
||||
@@ -515,6 +518,7 @@ func (n *Node) DropControlTraffic() {
|
||||
|
||||
type nodeOptOS OSImage
|
||||
type nodeOptNoTailscale struct{}
|
||||
type nodeOptTailscaleSSH struct{}
|
||||
type nodeOptNoAgent struct{}
|
||||
type nodeOptAdvertiseRoutes string
|
||||
type nodeOptSNATSubnetRoutes bool
|
||||
@@ -526,6 +530,13 @@ func OS(img OSImage) nodeOptOS { return nodeOptOS(img) }
|
||||
// DontJoinTailnet returns a NodeOption that prevents the node from running tailscale up.
|
||||
func DontJoinTailnet() nodeOptNoTailscale { return nodeOptNoTailscale{} }
|
||||
|
||||
// TailscaleSSH returns a NodeOption that enables the node's Tailscale SSH
|
||||
// server by passing --ssh to tailscale up. If any node has this option, the
|
||||
// test control server is configured with a permissive SSH policy that lets
|
||||
// any tailnet node connect as any SSH user, mapped to the same-named local
|
||||
// user.
|
||||
func TailscaleSSH() nodeOptTailscaleSSH { return nodeOptTailscaleSSH{} }
|
||||
|
||||
// NoAgent returns a NodeOption that skips TTA agent setup. The node will not
|
||||
// have a test agent, so agent-dependent operations (Status, ExecOnNode, etc.)
|
||||
// won't work. Useful for VMs that just need to boot and respond to ICMP.
|
||||
@@ -709,6 +720,9 @@ func (e *Env) tailscaleUp(ctx context.Context, n *Node) error {
|
||||
if n.advertiseRoutes != "" {
|
||||
url += "&advertise-routes=" + n.advertiseRoutes
|
||||
}
|
||||
if n.runSSH {
|
||||
url += "&ssh=true"
|
||||
}
|
||||
if n.snatSubnetRoutes != nil {
|
||||
if *n.snatSubnetRoutes {
|
||||
url += "&snat-subnet-routes=true"
|
||||
@@ -1636,6 +1650,18 @@ func (e *Env) initVnet() {
|
||||
}
|
||||
cs.DNSConfig.Proxied = true
|
||||
}
|
||||
for _, n := range e.nodes {
|
||||
if n.runSSH {
|
||||
e.server.ControlServer().SSHPolicy = &tailcfg.SSHPolicy{
|
||||
Rules: []*tailcfg.SSHRule{{
|
||||
Principals: []*tailcfg.SSHPrincipal{{Any: true}},
|
||||
SSHUsers: map[string]string{"*": "="},
|
||||
Action: &tailcfg.SSHAction{Accept: true},
|
||||
}},
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user