tstest/natlab: add FreeBSD test case for SSH test
Add logic to generateFreeBSDUserData to allow for an SSH connection as root for FreeBSD. Add FreeBSD test cases to ssh_test that exercise the same paths as the existing Ubuntu tests but for BSD. Updates https://github.com/tailscale/corp/issues/44813 Updates https://github.com/tailscale/tailscale/issues/13038 Signed-off-by: Mario Minardi <mario@tailscale.com>
This commit is contained in:
committed by
Mario Minardi
parent
7e609b2581
commit
8bc4c09a46
@@ -157,6 +157,15 @@ func (e *Env) generateFreeBSDUserData(n *Node) string {
|
|||||||
|
|
||||||
ud.WriteString("runcmd:\n")
|
ud.WriteString("runcmd:\n")
|
||||||
|
|
||||||
|
// Enable root SSH login for debugging via the debug NIC.
|
||||||
|
ud.WriteString(" - \"echo 'PermitRootLogin yes' >>/etc/ssh/sshd_config\"\n")
|
||||||
|
ud.WriteString(" - \"echo 'PubkeyAuthentication yes' >>/etc/ssh/sshd_config\"\n")
|
||||||
|
// Also inject the host's SSH key if available.
|
||||||
|
if pubkey, err := os.ReadFile("/tmp/vmtest_key.pub"); err == nil {
|
||||||
|
ud.WriteString(" - \"mkdir -p /root/.ssh && chmod 700 /root/.ssh\"\n")
|
||||||
|
fmt.Fprintf(&ud, " - \"echo '%s' >/root/.ssh/authorized_keys && chmod 600 /root/.ssh/authorized_keys\"\n", strings.TrimSpace(string(pubkey)))
|
||||||
|
}
|
||||||
|
|
||||||
// /usr/local/bin may not exist on a fresh FreeBSD cloud image (it's
|
// /usr/local/bin may not exist on a fresh FreeBSD cloud image (it's
|
||||||
// created when the first package is installed).
|
// created when the first package is installed).
|
||||||
ud.WriteString(" - \"mkdir -p /usr/local/bin\"\n")
|
ud.WriteString(" - \"mkdir -p /usr/local/bin\"\n")
|
||||||
|
|||||||
@@ -17,11 +17,11 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// TestTailscaleSSH exercises the Tailscale SSH server ("tailscale up --ssh",
|
// TestTailscaleSSH exercises the Tailscale SSH server ("tailscale up --ssh",
|
||||||
// not a system sshd) on both Ubuntu and gokrazy nodes, with an Ubuntu node
|
// not a system sshd) on Ubuntu, FreeBSD, and gokrazy nodes, with an Ubuntu node
|
||||||
// as the SSH client.
|
// as the SSH client.
|
||||||
//
|
//
|
||||||
// On Ubuntu it tests logging in as both root and a non-root user, which
|
// On Ubuntu and FreeBSD it tests logging in as both root and a non-root user,
|
||||||
// exercises the incubator's su-based login path.
|
// which exercises the incubator's su-based login path.
|
||||||
//
|
//
|
||||||
// On gokrazy it exercises the gokrazy special cases in the SSH code:
|
// On gokrazy it exercises the gokrazy special cases in the SSH code:
|
||||||
// util/osuser hard-codes the login shell to /tmp/serial-busybox/ash and
|
// util/osuser hard-codes the login shell to /tmp/serial-busybox/ash and
|
||||||
@@ -33,14 +33,20 @@ func TestTailscaleSSH(t *testing.T) {
|
|||||||
client := sshTestNode(env, "client", vmtest.Ubuntu2404)
|
client := sshTestNode(env, "client", vmtest.Ubuntu2404)
|
||||||
ubuntu := sshTestNode(env, "ubuntu", vmtest.Ubuntu2404, vmtest.TailscaleSSH())
|
ubuntu := sshTestNode(env, "ubuntu", vmtest.Ubuntu2404, vmtest.TailscaleSSH())
|
||||||
gokrazy := sshTestNode(env, "gokrazy", vmtest.Gokrazy, vmtest.TailscaleSSH())
|
gokrazy := sshTestNode(env, "gokrazy", vmtest.Gokrazy, vmtest.TailscaleSSH())
|
||||||
|
freebsd := sshTestNode(env, "freebsd", vmtest.FreeBSD150, vmtest.TailscaleSSH())
|
||||||
env.Start()
|
env.Start()
|
||||||
|
|
||||||
if out, err := env.SSHExec(ubuntu, "useradd -m -s /bin/bash tsuser"); err != nil {
|
if out, err := env.SSHExec(ubuntu, "useradd -m -s /bin/bash tsuser"); err != nil {
|
||||||
t.Fatalf("useradd: %v\n%s", err, out)
|
t.Fatalf("useradd: %v\n%s", err, out)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if out, err := env.SSHExec(freebsd, "pw useradd tsuser -m"); err != nil {
|
||||||
|
t.Fatalf("pw useradd: %v\n%s", err, out)
|
||||||
|
}
|
||||||
|
|
||||||
ubuntuIP := tailscaleIP4(t, env, ubuntu)
|
ubuntuIP := tailscaleIP4(t, env, ubuntu)
|
||||||
gokrazyIP := tailscaleIP4(t, env, gokrazy)
|
gokrazyIP := tailscaleIP4(t, env, gokrazy)
|
||||||
|
freebsdIP := tailscaleIP4(t, env, freebsd)
|
||||||
|
|
||||||
// ssh runs cmd as user on the node at ip over Tailscale SSH, from the
|
// ssh runs cmd as user on the node at ip over Tailscale SSH, from the
|
||||||
// client node, returning the combined output and the ssh client's exit
|
// client node, returning the combined output and the ssh client's exit
|
||||||
@@ -93,6 +99,7 @@ func TestTailscaleSSH(t *testing.T) {
|
|||||||
}
|
}
|
||||||
waitSSH("ubuntu", "root", ubuntuIP)
|
waitSSH("ubuntu", "root", ubuntuIP)
|
||||||
waitSSH("gokrazy", "root", gokrazyIP)
|
waitSSH("gokrazy", "root", gokrazyIP)
|
||||||
|
waitSSH("freebsd", "root", freebsdIP)
|
||||||
|
|
||||||
check := func(desc, user string, ip netip.Addr, cmd, want string) {
|
check := func(desc, user string, ip netip.Addr, cmd, want string) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
@@ -109,11 +116,19 @@ func TestTailscaleSSH(t *testing.T) {
|
|||||||
check("ubuntu root login", "root", ubuntuIP, "id -un && pwd", "root\n/root")
|
check("ubuntu root login", "root", ubuntuIP, "id -un && pwd", "root\n/root")
|
||||||
check("ubuntu non-root login", "tsuser", ubuntuIP, "id -un && pwd", "tsuser\n/home/tsuser")
|
check("ubuntu non-root login", "tsuser", ubuntuIP, "id -un && pwd", "tsuser\n/home/tsuser")
|
||||||
|
|
||||||
|
check("freebsd root login", "root", freebsdIP, "id -un && pwd", "root\n/root")
|
||||||
|
check("freebsd non-root login", "tsuser", freebsdIP, "id -un && pwd", "tsuser\n/home/tsuser")
|
||||||
|
|
||||||
// A nonexistent user is rejected on Ubuntu...
|
// A nonexistent user is rejected on Ubuntu...
|
||||||
if out, code := ssh("nosuchuser", ubuntuIP, "true"); code == 0 {
|
if out, code := ssh("nosuchuser", ubuntuIP, "true"); code == 0 {
|
||||||
t.Errorf("ubuntu nonexistent user: ssh succeeded, want failure:\n%s", out)
|
t.Errorf("ubuntu nonexistent user: ssh succeeded, want failure:\n%s", out)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// and rejected on FreeBSD...
|
||||||
|
if out, code := ssh("nosuchuser", freebsdIP, "true"); code == 0 {
|
||||||
|
t.Errorf("freebsd nonexistent user: ssh succeeded, want failure:\n%s", out)
|
||||||
|
}
|
||||||
|
|
||||||
// ... but on gokrazy any username works and becomes root, via the
|
// ... but on gokrazy any username works and becomes root, via the
|
||||||
// synthesized-user fallback in util/osuser (uid 0, home dir "/").
|
// synthesized-user fallback in util/osuser (uid 0, home dir "/").
|
||||||
// $0 is the login shell the session ran the command with, which on
|
// $0 is the login shell the session ran the command with, which on
|
||||||
|
|||||||
Reference in New Issue
Block a user