1 contributor
#!/usr/bin/env bash
# Migrate legacy SSH key (id_rsa_old) to modern key (id_ed25519) on hosts
# Usage: ./tools/migrate-modern-key.sh [host-alias]
# If no host specified, migrates all legacy hosts
set -euo pipefail
project_root=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)
modern_key_file="$HOME/.ssh/id_ed25519.pub"
legacy_key_file="$HOME/.ssh/keys/id_rsa_old"
if [[ ! -f "$modern_key_file" ]]; then
printf "Error: Modern key not found at %s\n" "$modern_key_file" >&2
exit 1
fi
if [[ ! -f "$legacy_key_file" ]]; then
printf "Error: Legacy key not found at %s\n" "$legacy_key_file" >&2
exit 1
fi
modern_key=$(cat "$modern_key_file")
migrate_host() {
local host=$1
local ip
local user
# Get host config
ip=$(ssh -G "$host" 2>/dev/null | grep "^hostname " | cut -d' ' -f2) || {
printf "Error: Cannot resolve host %s\n" "$host" >&2
return 1
}
user=$(ssh -G "$host" 2>/dev/null | grep "^user " | cut -d' ' -f2) || user="root"
printf "Migrating %s (%s@%s)...\n" "$host" "$user" "$ip"
# Try with modern key first (might already be migrated)
if timeout 2 ssh -o BatchMode=yes -o ConnectTimeout=1 "$host" "true" 2>/dev/null; then
printf " ✓ Already using modern key\n"
return 0
fi
# Try legacy key to install modern key
if timeout 5 ssh -i "$legacy_key_file" -o StrictHostKeyChecking=accept-new \
-o ConnectTimeout=2 "${user}@${ip}" \
"mkdir -p ~/.ssh && \
grep -q '$(printf '%s' "$modern_key" | sed 's/[&/\]/\\&/g')' ~/.ssh/authorized_keys 2>/dev/null || \
echo '$modern_key' >> ~/.ssh/authorized_keys && \
chmod 600 ~/.ssh/authorized_keys && \
echo 'OK'" 2>/dev/null; then
printf " ✓ Modern key installed\n"
# Verify
sleep 1
if timeout 2 ssh -o BatchMode=yes -o ConnectTimeout=1 "$host" "true" 2>/dev/null; then
printf " ✓ Verified\n"
return 0
else
printf " ⚠ Installation ok, verification pending\n"
return 1
fi
else
printf " ✗ Legacy key access failed\n"
return 1
fi
}
if [[ $# -gt 0 ]]; then
# Migrate specific host
migrate_host "$1"
else
# Migrate all legacy hosts
printf "=== Migrating all legacy hosts to modern key ===\n\n"
failed=()
success=()
while IFS= read -r host; do
if migrate_host "$host"; then
success+=("$host")
else
failed+=("$host")
fi
printf "\n"
done < <(grep -E "^Host is-" "$project_root/inventory/hosts-local.yaml" \
| grep -oE "is-[a-z0-9-]+" | sort -u)
printf "\n=== Migration Summary ===\n"
printf "Success: %d\n" "${#success[@]}"
printf "Failed: %d\n" "${#failed[@]}"
if [[ ${#failed[@]} -gt 0 ]]; then
printf "\nFailed hosts:\n"
printf " %s\n" "${failed[@]}"
exit 1
fi
fi