summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorPercy Wegmann <percy@tailscale.com>2024-06-12 18:02:54 -0500
committerPercy Wegmann <ox.to.a.cart@gmail.com>2024-06-12 20:29:48 -0500
commitd7fdc01f7f1266fa6cddefcb0dd07d81b445cdca (patch)
tree84e03754001bc3e47e7694a7da239c98a9f2dd08
parent02e3c046aa381262ec30742797f8f5efbd40aabd (diff)
downloadtailscale-d7fdc01f7f1266fa6cddefcb0dd07d81b445cdca.tar.xz
tailscale-d7fdc01f7f1266fa6cddefcb0dd07d81b445cdca.zip
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 <percy@tailscale.com>
-rw-r--r--ssh/tailssh/incubator.go39
-rw-r--r--ssh/tailssh/testcontainers/Dockerfile15
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