ssh/tailssh: speed up SSH integration tests
Parallelize the SSH integration tests across OS targets and reduce per-container overhead: - CI: use GitHub Actions matrix strategy to run all 4 OS containers (ubuntu:focal, ubuntu:jammy, ubuntu:noble, alpine:latest) in parallel instead of sequentially (~4x wall-clock improvement) - Makefile: run docker builds in parallel for local dev too - Dockerfile: consolidate ~20 separate RUN commands into 5 (one per test phase), eliminating Docker layer overhead. Combine test binary invocations where no state mutation is needed between them. Fix a bug where TestDoDropPrivileges was silently not being run (was passed as a second positional arg to -test.run instead of using regex alternation). - TestMain: replace tail -F + 2s sleep with synchronous log read, eliminating 2s overhead per test binary invocation. Set debugTest once in TestMain instead of redundantly in each test function. - session.read(): close channel on EOF so non-shell tests return immediately instead of waiting for the 1s silence timeout. Updates #19244 Change-Id: I2cc8588964fbce0dd7b654fb94e7ff33440b8584 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
committed by
Brad Fitzpatrick
parent
cfed69f3ed
commit
e2fa9ff140
@@ -28,64 +28,68 @@ COPY tailssh.test .
|
||||
|
||||
RUN chmod 755 tailscaled
|
||||
|
||||
RUN echo "First run tests normally."
|
||||
RUN eval `ssh-agent -s` && TAILSCALED_PATH=`pwd`tailscaled ./tailssh.test -test.v -test.run TestSSHAgentForwarding
|
||||
RUN if echo "$BASE" | grep "ubuntu:"; then rm -Rf /home/testuser; fi
|
||||
RUN TAILSCALED_PATH=`pwd`tailscaled ./tailssh.test -test.v -test.run TestIntegrationSFTP
|
||||
RUN if echo "$BASE" | grep "ubuntu:"; then rm -Rf /home/testuser; fi
|
||||
RUN TAILSCALED_PATH=`pwd`tailscaled ./tailssh.test -test.v -test.run TestIntegrationSCP
|
||||
RUN if echo "$BASE" | grep "ubuntu:"; then rm -Rf /home/testuser; fi
|
||||
RUN TAILSCALED_PATH=`pwd`tailscaled ./tailssh.test -test.v -test.run TestIntegrationSSH
|
||||
RUN if echo "$BASE" | grep "ubuntu:"; then rm -Rf /home/testuser; fi
|
||||
RUN TAILSCALED_PATH=`pwd`tailscaled ./tailssh.test -test.v -test.run TestIntegrationParamiko
|
||||
RUN TAILSCALED_PATH=`pwd`tailscaled ./tailssh.test -test.v -test.run TestLocalUnixForwarding
|
||||
RUN TAILSCALED_PATH=`pwd`tailscaled ./tailssh.test -test.v -test.run TestReverseUnixForwarding
|
||||
RUN TAILSCALED_PATH=`pwd`tailscaled ./tailssh.test -test.v -test.run TestUnixForwardingDenied
|
||||
RUN TAILSCALED_PATH=`pwd`tailscaled ./tailssh.test -test.v -test.run TestUnixForwardingPathRestriction
|
||||
# Run tests normally.
|
||||
# On Ubuntu, delete testuser's home directory between tests to verify
|
||||
# that PAM's pam_mkhomedir recreates it each time.
|
||||
RUN set -e && \
|
||||
eval $(ssh-agent -s) && \
|
||||
TAILSCALED_PATH=$(pwd)/tailscaled ./tailssh.test -test.v -test.run TestSSHAgentForwarding && \
|
||||
if echo "$BASE" | grep -q "ubuntu:"; then rm -Rf /home/testuser; fi && \
|
||||
TAILSCALED_PATH=$(pwd)/tailscaled ./tailssh.test -test.v -test.run TestIntegrationSFTP && \
|
||||
if echo "$BASE" | grep -q "ubuntu:"; then rm -Rf /home/testuser; fi && \
|
||||
TAILSCALED_PATH=$(pwd)/tailscaled ./tailssh.test -test.v -test.run TestIntegrationSCP && \
|
||||
if echo "$BASE" | grep -q "ubuntu:"; then rm -Rf /home/testuser; fi && \
|
||||
TAILSCALED_PATH=$(pwd)/tailscaled ./tailssh.test -test.v -test.run TestIntegrationSSH && \
|
||||
if echo "$BASE" | grep -q "ubuntu:"; then rm -Rf /home/testuser; fi && \
|
||||
TAILSCALED_PATH=$(pwd)/tailscaled ./tailssh.test -test.v -test.run TestIntegrationParamiko && \
|
||||
TAILSCALED_PATH=$(pwd)/tailscaled ./tailssh.test -test.v -test.run TestLocalUnixForwarding && \
|
||||
TAILSCALED_PATH=$(pwd)/tailscaled ./tailssh.test -test.v -test.run TestReverseUnixForwarding && \
|
||||
TAILSCALED_PATH=$(pwd)/tailscaled ./tailssh.test -test.v -test.run TestUnixForwardingDenied && \
|
||||
TAILSCALED_PATH=$(pwd)/tailscaled ./tailssh.test -test.v -test.run TestUnixForwardingPathRestriction
|
||||
|
||||
RUN echo "Then run tests as non-root user testuser and make sure tests still pass."
|
||||
RUN touch /tmp/tailscalessh.log
|
||||
RUN chown testuser:groupone /tmp/tailscalessh.log
|
||||
RUN TAILSCALED_PATH=`pwd`tailscaled eval `su -m testuser -c ssh-agent -s` && su -m testuser -c "./tailssh.test -test.v -test.run TestSSHAgentForwarding"
|
||||
RUN TAILSCALED_PATH=`pwd`tailscaled su -m testuser -c "./tailssh.test -test.v -test.run TestIntegration TestDoDropPrivileges"
|
||||
RUN echo "Also, deny everyone access to the user's home directory and make sure non file-related tests still pass."
|
||||
RUN mkdir -p /home/testuser && chown testuser:groupone /home/testuser && chmod 0000 /home/testuser
|
||||
RUN TAILSCALED_PATH=`pwd`tailscaled SKIP_FILE_OPS=1 su -m testuser -c "./tailssh.test -test.v -test.run TestIntegrationSSH"
|
||||
RUN chmod 0755 /home/testuser
|
||||
RUN chown root:root /tmp/tailscalessh.log
|
||||
# Run tests as non-root user testuser and make sure tests still pass.
|
||||
RUN set -e && \
|
||||
touch /tmp/tailscalessh.log && \
|
||||
chown testuser:groupone /tmp/tailscalessh.log && \
|
||||
export TAILSCALED_PATH=$(pwd)/tailscaled && \
|
||||
eval $(su -m testuser -c "ssh-agent -s") && \
|
||||
su -m testuser -c "./tailssh.test -test.v -test.run 'TestSSHAgentForwarding|TestIntegration|TestDoDropPrivileges'" && \
|
||||
echo "Also, deny everyone access to the user's home directory and make sure non file-related tests still pass." && \
|
||||
mkdir -p /home/testuser && chown testuser:groupone /home/testuser && chmod 0000 /home/testuser && \
|
||||
SKIP_FILE_OPS=1 su -m testuser -c "./tailssh.test -test.v -test.run TestIntegrationSSH" && \
|
||||
chmod 0755 /home/testuser && \
|
||||
chown root:root /tmp/tailscalessh.log
|
||||
|
||||
RUN if echo "$BASE" | grep "ubuntu:"; then \
|
||||
echo "Then run tests in a system that's pretending to be SELinux in enforcing mode" && \
|
||||
# Remove execute permissions for /usr/bin/login so that it fails.
|
||||
# On Ubuntu, run tests pretending to be SELinux in enforcing mode.
|
||||
RUN if echo "$BASE" | grep -q "ubuntu:"; then \
|
||||
set -e && \
|
||||
echo "Run tests in a system that's pretending to be SELinux in enforcing mode" && \
|
||||
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.
|
||||
echo "adsfasdfasdf" > /usr/bin/login && \
|
||||
chmod 755 /usr/bin/login && \
|
||||
# Simulate getenforce command
|
||||
printf "#!/bin/bash\necho 'Enforcing'" > /usr/bin/getenforce && \
|
||||
chmod 755 /usr/bin/getenforce && \
|
||||
eval `ssh-agent -s` && TAILSCALED_PATH=`pwd`tailscaled ./tailssh.test -test.v -test.run TestSSHAgentForwarding && \
|
||||
TAILSCALED_PATH=`pwd`tailscaled ./tailssh.test -test.v -test.run TestIntegration && \
|
||||
eval $(ssh-agent -s) && \
|
||||
TAILSCALED_PATH=$(pwd)/tailscaled ./tailssh.test -test.v -test.run 'TestSSHAgentForwarding|TestIntegration' && \
|
||||
mv /tmp/login_orig /usr/bin/login && \
|
||||
rm /usr/bin/getenforce \
|
||||
; fi
|
||||
|
||||
RUN echo "Then remove the login command and make sure tests still pass."
|
||||
RUN rm `which login`
|
||||
RUN eval `ssh-agent -s` && TAILSCALED_PATH=`pwd`tailscaled ./tailssh.test -test.v -test.run TestSSHAgentForwarding
|
||||
RUN if echo "$BASE" | grep "ubuntu:"; then rm -Rf /home/testuser; fi
|
||||
RUN TAILSCALED_PATH=`pwd`tailscaled ./tailssh.test -test.v -test.run TestIntegrationSFTP
|
||||
RUN if echo "$BASE" | grep "ubuntu:"; then rm -Rf /home/testuser; fi
|
||||
RUN TAILSCALED_PATH=`pwd`tailscaled ./tailssh.test -test.v -test.run TestIntegrationSCP
|
||||
RUN if echo "$BASE" | grep "ubuntu:"; then rm -Rf /home/testuser; fi
|
||||
RUN TAILSCALED_PATH=`pwd`tailscaled ./tailssh.test -test.v -test.run TestIntegrationSSH
|
||||
# Remove the login command and make sure tests still pass.
|
||||
RUN set -e && \
|
||||
rm $(which login) && \
|
||||
eval $(ssh-agent -s) && \
|
||||
TAILSCALED_PATH=$(pwd)/tailscaled ./tailssh.test -test.v -test.run TestSSHAgentForwarding && \
|
||||
if echo "$BASE" | grep -q "ubuntu:"; then rm -Rf /home/testuser; fi && \
|
||||
TAILSCALED_PATH=$(pwd)/tailscaled ./tailssh.test -test.v -test.run TestIntegrationSFTP && \
|
||||
if echo "$BASE" | grep -q "ubuntu:"; then rm -Rf /home/testuser; fi && \
|
||||
TAILSCALED_PATH=$(pwd)/tailscaled ./tailssh.test -test.v -test.run TestIntegrationSCP && \
|
||||
if echo "$BASE" | grep -q "ubuntu:"; then rm -Rf /home/testuser; fi && \
|
||||
TAILSCALED_PATH=$(pwd)/tailscaled ./tailssh.test -test.v -test.run TestIntegrationSSH
|
||||
|
||||
RUN echo "Then remove the su command and make sure tests still pass."
|
||||
RUN chown root:root /tmp/tailscalessh.log
|
||||
RUN rm `which su`
|
||||
RUN eval `ssh-agent -s` && TAILSCALED_PATH=`pwd`tailscaled ./tailssh.test -test.v -test.run TestSSHAgentForwarding
|
||||
RUN TAILSCALED_PATH=`pwd`tailscaled ./tailssh.test -test.v -test.run TestIntegration
|
||||
|
||||
RUN echo "Test doDropPrivileges"
|
||||
RUN TAILSCALED_PATH=`pwd`tailscaled ./tailssh.test -test.v -test.run TestDoDropPrivileges
|
||||
# Remove the su command and make sure tests still pass.
|
||||
RUN set -e && \
|
||||
chown root:root /tmp/tailscalessh.log && \
|
||||
rm $(which su) && \
|
||||
eval $(ssh-agent -s) && \
|
||||
TAILSCALED_PATH=$(pwd)/tailscaled ./tailssh.test -test.v -test.run 'TestSSHAgentForwarding|TestIntegration|TestDoDropPrivileges'
|
||||
|
||||
Reference in New Issue
Block a user