diff --git a/.github/workflows/bash-syntax.yml b/.github/workflows/bash-syntax.yml index 084e152..fcfea4b 100644 --- a/.github/workflows/bash-syntax.yml +++ b/.github/workflows/bash-syntax.yml @@ -59,3 +59,6 @@ jobs: - name: Test initial backup policy and upload retry run: bash tests/test-backup-initial-retry.sh + + - name: Test step 3 socket activation runtime directory + run: bash tests/test-step3-runtime-directory.sh diff --git a/ochenstarik-server-user-3.sh b/ochenstarik-server-user-3.sh index c557d42..a4bcad8 100644 --- a/ochenstarik-server-user-3.sh +++ b/ochenstarik-server-user-3.sh @@ -73,6 +73,12 @@ is_valid_port() { (( 10#$port >= 1 && 10#$port <= 65535 )) } +prepare_sshd_runtime_directory() { + # Socket-activated Ubuntu can have no active ssh.service after an upgrade. + # Its RuntimeDirectory then does not exist, but standalone sshd -t needs it. + install -d -o root -g root -m 755 /run/sshd +} + read_ip_mode() { local mode=both if [[ -e "$IP_FAMILY_CONFIG" ]]; then @@ -517,6 +523,7 @@ UsePAM yes EOF chmod 644 "$SSHD_DROPIN" +prepare_sshd_runtime_directory sshd -t || die "sshd syntax validation failed" # Capture the complete output once. With pipefail enabled, piping `sshd -T` # into an awk program that exits after the first match can terminate sshd with diff --git a/tests/test-step3-runtime-directory.sh b/tests/test-step3-runtime-directory.sh new file mode 100644 index 0000000..8c3bd7a --- /dev/null +++ b/tests/test-step3-runtime-directory.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash +set -Eeuo pipefail +cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." +source <(awk '/^\[\[ "\$EUID"/{exit} {print}' ochenstarik-server-user-3.sh) +test_dir="$(mktemp -d)" +trap 'rm -rf -- "$test_dir"' EXIT + +# Relocate just the privileged filesystem boundary; use the real install +# binary to check first creation, idempotency and repair of unsafe modes. +install() { + [[ "$*" == '-d -o root -g root -m 755 /run/sshd' ]] + /usr/bin/install -d -m 755 "$test_dir/sshd" +} +prepare_sshd_runtime_directory +[[ -d "$test_dir/sshd" && "$(stat -c %a "$test_dir/sshd")" == 755 ]] +chmod 777 "$test_dir/sshd" +prepare_sshd_runtime_directory +[[ "$(stat -c %a "$test_dir/sshd")" == 755 ]] + +# The runtime prerequisite must run before standalone configuration validation. +prepare_line="$(grep -n '^prepare_sshd_runtime_directory$' ochenstarik-server-user-3.sh | cut -d: -f1)" +validate_line="$(grep -n '^sshd -t ' ochenstarik-server-user-3.sh | cut -d: -f1)" +((prepare_line < validate_line)) +printf 'Step 3 socket-activation runtime directory tests passed.\n'