#!/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