feat: make key authentication failures diagnosable #2

Open
butterrobot wants to merge 2 commits from butterrobot/diagnose-key-auth-failures into main AGit

View file

@ -38,10 +38,27 @@ trap 'rm -f "$KEY_FILE"' EXIT
echo "$INPUT_KEY" > "$KEY_FILE" echo "$INPUT_KEY" > "$KEY_FILE"
chmod 600 "$KEY_FILE" chmod 600 "$KEY_FILE"
# -P "" so an encrypted key reports a passphrase error instead of hanging on a prompt.
if ! DEPLOY_PUBLIC_KEY="$(ssh-keygen -y -P "" -f "$KEY_FILE" 2>&1)"; then
echo "Error: the 'key' input is not a usable unencrypted OpenSSH private key." >&2
echo "ssh-keygen: ${DEPLOY_PUBLIC_KEY}" >&2
exit 1
fi
# The public half is not a secret, and printing it is what makes an authentication
# failure diagnosable: it is the exact line that must be in authorized_keys.
echo "Authenticating to ${INPUT_HOST} as ${INPUT_USERNAME} with public key:"
echo " ${DEPLOY_PUBLIC_KEY}"
# The fingerprint is what sshd reports at LogLevel VERBOSE, so printing it here
# lets a rejected key be matched against the target's auth log directly.
echo " fingerprint: $(ssh-keygen -lf "$KEY_FILE" 2>/dev/null || echo unavailable)"
ssh-keyscan -p "$SSH_PORT" -H "$INPUT_HOST" >> "$KNOWN_HOSTS" 2>/dev/null ssh-keyscan -p "$SSH_PORT" -H "$INPUT_HOST" >> "$KNOWN_HOSTS" 2>/dev/null
# BatchMode stops ssh falling back to interactive password auth, which otherwise
# buries a rejected key under two generic "Permission denied" prompts.
rsync -avz \ rsync -avz \
-e "ssh -i $KEY_FILE -o UserKnownHostsFile=$KNOWN_HOSTS -p $SSH_PORT -o ConnectTimeout=30" \ -e "ssh -i $KEY_FILE -o IdentitiesOnly=yes -o BatchMode=yes -o UserKnownHostsFile=$KNOWN_HOSTS -p $SSH_PORT -o ConnectTimeout=30" \
$INPUT_ARGS \ $INPUT_ARGS \
"${SOURCE}/" \ "${SOURCE}/" \
"${INPUT_USERNAME}@${INPUT_HOST}:${INPUT_TARGET}/" "${INPUT_USERNAME}@${INPUT_HOST}:${INPUT_TARGET}/"