|
| 1 | +#!/bin/bash |
| 2 | + |
| 3 | +# SSH Public Key Authentication Test |
| 4 | +# |
| 5 | +# This script tests that older OpenSSH client versions can still connect to an |
| 6 | +# XCP-ng server using public key authentication |
| 7 | +# |
| 8 | +# Usage: |
| 9 | +# test-ssh-public-key-auth.sh <host> <version> <keytype> |
| 10 | +# |
| 11 | +# Context: |
| 12 | +# Due to the removal of the ssh-rsa signature algorithm in OpenSSH 9.8, older |
| 13 | +# clients (version < 7.2) are no longer able to use public key authentication |
| 14 | +# with ssh-rsa keys. Howerver, newer OpenSSH versions (7.2 and above) should |
| 15 | +# still be able to authenticate using ssh-rsa keys, as well as ed25519 keys. |
| 16 | +# |
| 17 | +# This script can be used to verify this assumption by running: |
| 18 | +# |
| 19 | +# $ scripts/test-ssh-public-key-auth.sh HOST 7.2_p2-r5 rsa |
| 20 | +# |
| 21 | +# It requires Docker or Podman to be installed. |
| 22 | + |
| 23 | +# -e: Exit immediately if a command exits with a non-zero status. |
| 24 | +# -u: Treat unset variables as an error and exit immediately. |
| 25 | +set -eu |
| 26 | + |
| 27 | +# Constants and defaults |
| 28 | +USER="root" |
| 29 | +PASSWORD="" |
| 30 | +SSH_OPTIONS="-o StrictHostKeyChecking=no" |
| 31 | +IMAGE_BASE_NAME="sig9/alpine-openssh-client" |
| 32 | + |
| 33 | +print_help() { |
| 34 | + cat <<'EOF' |
| 35 | +Usage: |
| 36 | + test-ssh-public-key-auth.sh <host> <version> <keytype> |
| 37 | +
|
| 38 | +Description: |
| 39 | + Runs an SSH public key authentication test |
| 40 | + Requires Docker or Podman to be installed. |
| 41 | +
|
| 42 | +Example: |
| 43 | + scripts/test-ssh-public-key-auth.sh HOST 7.2_p2-r5 rsa |
| 44 | +EOF |
| 45 | +} |
| 46 | + |
| 47 | +silent_unless_fail() { |
| 48 | + local err |
| 49 | + # Run the command passed as arguments, capture stderr, discard stdout |
| 50 | + if ! err=$("$@" 2>/dev/stdout >/dev/null); then |
| 51 | + echo "$err" >&2 |
| 52 | + echo "❌ Test failed" |
| 53 | + return 1 |
| 54 | + fi |
| 55 | +} |
| 56 | + |
| 57 | +# Parse arguments |
| 58 | +if [ "${1:-}" = "-h" ] || [ "${1:-}" = "--help" ]; then |
| 59 | + print_help |
| 60 | + exit 0 |
| 61 | +fi |
| 62 | +if [ "$#" -ne 3 ]; then |
| 63 | + echo "Expected exactly three arguments: <host> <version> <keytype>" >&2 |
| 64 | + print_help |
| 65 | + exit 1 |
| 66 | +fi |
| 67 | + |
| 68 | +# Get arguments |
| 69 | +HOST="$1" |
| 70 | +VERSION="$2" |
| 71 | +KEY_TYPE="$3" |
| 72 | +IMAGE="$IMAGE_BASE_NAME:$VERSION" |
| 73 | +KEY_NAME="testing_${VERSION}_${KEY_TYPE}" |
| 74 | +COMMENT="$(uuidgen)@testing-${VERSION}-${KEY_TYPE}" |
| 75 | +CLEANUP="sed -i /$COMMENT\$/d ~/.ssh/authorized_keys" |
| 76 | + |
| 77 | +# Detect the container engine |
| 78 | +if command -v podman &> /dev/null; then |
| 79 | + CONTAINER_ENGINE="podman" |
| 80 | +elif command -v docker &> /dev/null; then |
| 81 | + CONTAINER_ENGINE="docker" |
| 82 | +else |
| 83 | + echo "Error: Neither podman nor docker found." |
| 84 | + exit 1 |
| 85 | +fi |
| 86 | + |
| 87 | +# Prompt for password |
| 88 | +if [ -z "$PASSWORD" ]; then |
| 89 | + read -s -p $'Enter \e[1m'"$USER@$HOST"$'\e[0m password: ' PASSWORD |
| 90 | + echo "" |
| 91 | +fi |
| 92 | + |
| 93 | +echo "Pulling Docker image $IMAGE..." |
| 94 | +silent_unless_fail $CONTAINER_ENGINE pull "$IMAGE" |
| 95 | + |
| 96 | +echo "Generating SSH key pair..." |
| 97 | +trap 'rm -f "$KEY_NAME" "$KEY_NAME.pub"' EXIT |
| 98 | +silent_unless_fail $CONTAINER_ENGINE run --rm -v "$PWD:/data" "$IMAGE" -c "cd /data && ssh-keygen -t $KEY_TYPE -f $KEY_NAME -C '$COMMENT' -N ''" |
| 99 | + |
| 100 | +echo "Copying public key to $USER@$HOST..." |
| 101 | +silent_unless_fail $CONTAINER_ENGINE run --rm -v "$PWD:/data" "$IMAGE" -c "mkdir -p /root/.ssh && sshpass -p '$PASSWORD' ssh-copy-id -i /data/$KEY_NAME.pub $SSH_OPTIONS '$USER@$HOST'" |
| 102 | + |
| 103 | +echo "Verifying SSH connection..." |
| 104 | +silent_unless_fail $CONTAINER_ENGINE run --rm -v "$PWD:/data" "$IMAGE" -c "ssh $SSH_OPTIONS -i /data/$KEY_NAME '$USER@$HOST' 'echo hello'" |
| 105 | + |
| 106 | +echo "SSH connection successful, cleaning up..." |
| 107 | +silent_unless_fail $CONTAINER_ENGINE run --rm -v "$PWD:/data" "$IMAGE" -c "ssh $SSH_OPTIONS -i /data/$KEY_NAME '$USER@$HOST' '$CLEANUP'" |
| 108 | + |
| 109 | +echo "✅ Test passed" |
0 commit comments