|
Bogdan Timofte
authored
2 weeks ago
|
1
|
#!/usr/bin/env bash
|
|
|
2
|
# Migrate legacy SSH key (id_rsa_old) to modern key (id_ed25519) on hosts
|
|
|
3
|
# Usage: ./tools/migrate-modern-key.sh [host-alias]
|
|
|
4
|
# If no host specified, migrates all legacy hosts
|
|
|
5
|
|
|
|
6
|
set -euo pipefail
|
|
|
7
|
|
|
|
8
|
project_root=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)
|
|
|
9
|
modern_key_file="$HOME/.ssh/id_ed25519.pub"
|
|
|
10
|
legacy_key_file="$HOME/.ssh/keys/id_rsa_old"
|
|
|
11
|
|
|
|
12
|
if [[ ! -f "$modern_key_file" ]]; then
|
|
|
13
|
printf "Error: Modern key not found at %s\n" "$modern_key_file" >&2
|
|
|
14
|
exit 1
|
|
|
15
|
fi
|
|
|
16
|
|
|
|
17
|
if [[ ! -f "$legacy_key_file" ]]; then
|
|
|
18
|
printf "Error: Legacy key not found at %s\n" "$legacy_key_file" >&2
|
|
|
19
|
exit 1
|
|
|
20
|
fi
|
|
|
21
|
|
|
|
22
|
modern_key=$(cat "$modern_key_file")
|
|
|
23
|
|
|
|
24
|
migrate_host() {
|
|
|
25
|
local host=$1
|
|
|
26
|
local ip
|
|
|
27
|
local user
|
|
|
28
|
|
|
|
29
|
# Get host config
|
|
|
30
|
ip=$(ssh -G "$host" 2>/dev/null | grep "^hostname " | cut -d' ' -f2) || {
|
|
|
31
|
printf "Error: Cannot resolve host %s\n" "$host" >&2
|
|
|
32
|
return 1
|
|
|
33
|
}
|
|
|
34
|
|
|
|
35
|
user=$(ssh -G "$host" 2>/dev/null | grep "^user " | cut -d' ' -f2) || user="root"
|
|
|
36
|
|
|
|
37
|
printf "Migrating %s (%s@%s)...\n" "$host" "$user" "$ip"
|
|
|
38
|
|
|
|
39
|
# Try with modern key first (might already be migrated)
|
|
|
40
|
if timeout 2 ssh -o BatchMode=yes -o ConnectTimeout=1 "$host" "true" 2>/dev/null; then
|
|
|
41
|
printf " ✓ Already using modern key\n"
|
|
|
42
|
return 0
|
|
|
43
|
fi
|
|
|
44
|
|
|
|
45
|
# Try legacy key to install modern key
|
|
|
46
|
if timeout 5 ssh -i "$legacy_key_file" -o StrictHostKeyChecking=accept-new \
|
|
|
47
|
-o ConnectTimeout=2 "${user}@${ip}" \
|
|
|
48
|
"mkdir -p ~/.ssh && \
|
|
|
49
|
grep -q '$(printf '%s' "$modern_key" | sed 's/[&/\]/\\&/g')' ~/.ssh/authorized_keys 2>/dev/null || \
|
|
|
50
|
echo '$modern_key' >> ~/.ssh/authorized_keys && \
|
|
|
51
|
chmod 600 ~/.ssh/authorized_keys && \
|
|
|
52
|
echo 'OK'" 2>/dev/null; then
|
|
|
53
|
printf " ✓ Modern key installed\n"
|
|
|
54
|
|
|
|
55
|
# Verify
|
|
|
56
|
sleep 1
|
|
|
57
|
if timeout 2 ssh -o BatchMode=yes -o ConnectTimeout=1 "$host" "true" 2>/dev/null; then
|
|
|
58
|
printf " ✓ Verified\n"
|
|
|
59
|
return 0
|
|
|
60
|
else
|
|
|
61
|
printf " ⚠ Installation ok, verification pending\n"
|
|
|
62
|
return 1
|
|
|
63
|
fi
|
|
|
64
|
else
|
|
|
65
|
printf " ✗ Legacy key access failed\n"
|
|
|
66
|
return 1
|
|
|
67
|
fi
|
|
|
68
|
}
|
|
|
69
|
|
|
|
70
|
if [[ $# -gt 0 ]]; then
|
|
|
71
|
# Migrate specific host
|
|
|
72
|
migrate_host "$1"
|
|
|
73
|
else
|
|
|
74
|
# Migrate all legacy hosts
|
|
|
75
|
printf "=== Migrating all legacy hosts to modern key ===\n\n"
|
|
|
76
|
|
|
|
77
|
failed=()
|
|
|
78
|
success=()
|
|
|
79
|
|
|
|
80
|
while IFS= read -r host; do
|
|
|
81
|
if migrate_host "$host"; then
|
|
|
82
|
success+=("$host")
|
|
|
83
|
else
|
|
|
84
|
failed+=("$host")
|
|
|
85
|
fi
|
|
|
86
|
printf "\n"
|
|
|
87
|
done < <(grep -E "^Host is-" "$project_root/inventory/hosts-local.yaml" \
|
|
|
88
|
| grep -oE "is-[a-z0-9-]+" | sort -u)
|
|
|
89
|
|
|
|
90
|
printf "\n=== Migration Summary ===\n"
|
|
|
91
|
printf "Success: %d\n" "${#success[@]}"
|
|
|
92
|
printf "Failed: %d\n" "${#failed[@]}"
|
|
|
93
|
|
|
|
94
|
if [[ ${#failed[@]} -gt 0 ]]; then
|
|
|
95
|
printf "\nFailed hosts:\n"
|
|
|
96
|
printf " %s\n" "${failed[@]}"
|
|
|
97
|
exit 1
|
|
|
98
|
fi
|
|
|
99
|
fi
|