From d7fdc01f7f1266fa6cddefcb0dd07d81b445cdca Mon Sep 17 00:00:00 2001 From: Percy Wegmann Date: Wed, 12 Jun 2024 18:02:54 -0500 Subject: [PATCH] ssh/tailssh: check IsSELinuxEnforcing in tailscaled process Checking in the incubator as this used to do fails because the getenforce command is not on the PATH. Updates #12442 Signed-off-by: Percy Wegmann --- ssh/tailssh/incubator.go | 39 ++++++++++++++++----------- ssh/tailssh/testcontainers/Dockerfile | 15 ++++++++++- 2 files changed, 38 insertions(+), 16 deletions(-) diff --git a/ssh/tailssh/incubator.go b/ssh/tailssh/incubator.go index e43486072..799c116c1 100644 --- a/ssh/tailssh/incubator.go +++ b/ssh/tailssh/incubator.go @@ -121,6 +121,13 @@ func (ss *sshSession) newIncubatorCommand(logf logger.Logf) (cmd *exec.Cmd, err "--tty-name=", // updated in-place by startWithPTY } + // We have to check the below outside of the incubator process, because it + // relies on the "getenforce" command being on the PATH, which it is not + // when in the incubator. + if runtime.GOOS == "linux" && hostinfo.IsSELinuxEnforcing() { + incubatorArgs = append(incubatorArgs, "--is-selinux-enforcing") + } + forceV1Behavior := ss.conn.srv.lb.NetMap().HasCap(tailcfg.NodeAttrSSHBehaviorV1) if forceV1Behavior { incubatorArgs = append(incubatorArgs, "--force-v1-behavior") @@ -167,20 +174,21 @@ func (stdRWC) Close() error { } type incubatorArgs struct { - loginShell string - uid int - gid int - gids []int - localUser string - remoteUser string - remoteIP string - ttyName string - hasTTY bool - cmd string - isSFTP bool - isShell bool - forceV1Behavior bool - debugTest bool + loginShell string + uid int + gid int + gids []int + localUser string + remoteUser string + remoteIP string + ttyName string + hasTTY bool + cmd string + isSFTP bool + isShell bool + forceV1Behavior bool + debugTest bool + isSELinuxEnforcing bool } func parseIncubatorArgs(args []string) (incubatorArgs, error) { @@ -202,6 +210,7 @@ func parseIncubatorArgs(args []string) (incubatorArgs, error) { flags.BoolVar(&ia.isSFTP, "sftp", false, "run sftp server (cmd is ignored)") flags.BoolVar(&ia.forceV1Behavior, "force-v1-behavior", false, "allow falling back to the su command if login is unavailable") flags.BoolVar(&ia.debugTest, "debug-test", false, "should debug in test mode") + flags.BoolVar(&ia.isSELinuxEnforcing, "is-selinux-enforcing", false, "whether SELinux is in enforcing mode") flags.Parse(args) for _, g := range strings.Split(groups, ",") { @@ -338,7 +347,7 @@ func shouldAttemptLoginShell(dlogf logger.Logf, ia incubatorArgs) bool { return false } - return runningAsRoot() && !hostinfo.IsSELinuxEnforcing() + return runningAsRoot() && !ia.isSELinuxEnforcing } func runningAsRoot() bool { diff --git a/ssh/tailssh/testcontainers/Dockerfile b/ssh/tailssh/testcontainers/Dockerfile index cb24aca12..d712dd298 100644 --- a/ssh/tailssh/testcontainers/Dockerfile +++ b/ssh/tailssh/testcontainers/Dockerfile @@ -31,9 +31,22 @@ RUN TAILSCALED_PATH=`pwd`tailscaled ./tailssh.test -test.v -test.run TestIntegra RUN echo "Then run tests as non-root user testuser and make sure tests still pass." RUN chown testuser:groupone /tmp/tailscalessh.log RUN TAILSCALED_PATH=`pwd`tailscaled su -m testuser -c "./tailssh.test -test.v -test.run TestIntegration TestDoDropPrivileges" +RUN chown root:root /tmp/tailscalessh.log + +RUN echo "Then run tests in a system that's pretending to be SELinux in enforcing mode" +RUN mv /usr/bin/login /tmp/login_orig +# Use nonsense for /usr/bin/login so that it fails. +# It's not the same failure mode as in SELinux, but failure is good enough for test. +RUN echo "adsfasdfasdf" > /usr/bin/login +RUN chmod 755 /usr/bin/login +# Simulate getenforce command +RUN printf "#!/bin/bash\necho 'Enforcing'" > /usr/bin/getenforce +RUN chmod 755 /usr/bin/getenforce +RUN TAILSCALED_PATH=`pwd`tailscaled ./tailssh.test -test.v -test.run TestIntegration +RUN mv /tmp/login_orig /usr/bin/login +RUN rm /usr/bin/getenforce RUN echo "Then remove the login command and make sure tests still pass." -RUN chown root:root /tmp/tailscalessh.log RUN rm `which login` RUN rm -Rf /home/testuser RUN TAILSCALED_PATH=`pwd`tailscaled ./tailssh.test -test.v -test.run TestIntegrationSFTP