This repository has been archived by the owner on Jan 1, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathupdate_host_keys
executable file
·113 lines (93 loc) · 3.55 KB
/
update_host_keys
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#!/bin/bash
set -uE -o pipefail
resolve_all_names() {
local domain="tfb.net"
for h in "$@" ; do
for host in "$h" "${h%%.*}" "$h.$domain" \
"${h//./-pvt.}" "${h//./-pub.}" "${h//./-mgmt.}" \
"${h//./-pvt.}.$domain" "${h//./-pub.}.$domain" "${h//./-mgmt.}.$domain"
do
host "$host" 2>&1 \
| grep -v NXDOMAIN \
| egrep -wo "(([0-9]+\.){3}[0-9]+|([0-9a-f]{1,4}:){7}[0-9a-f]{1,4}|[a-z0-9][a-z0-9\.-]+\.($domain|cat|sh))" \
| sort -u
done
echo "$h"
echo "${h%%.*}"
done
}
resolve_ptr() {
host "$1" | grep -w 'domain name pointer' | cut -d' ' -f5 | sed 's/\.$//'
}
ssh() {
command ssh -o ConnectTimeout=4 -o BatchMode=yes -o StrictHostKeyChecking=no -o LogLevel=QUIET "$@"
}
forgive_ssh_validation() {
local rc=1
case "$1" in
pdu1*|brienne-mgmt*|brienne-lom*) rc=0 ;;
esac
return $rc
}
get_ssh_port() {
case "$1" in
10.1.2.*|pdu*|brienne-mgmt*) echo 22 ;;
*) echo 1009 ;;
esac
}
is_host_alive() {
local host="$1"
local pingcmd="ping"
if [[ "$host" =~ .*:.* ]] ; then
pingcmd="ping6"
fi
$pingcmd -q -c 1 -w 1 "$host" >/dev/null 2>&1
}
log () { echo -e "$*"; }
okay () { notice "\e[32m$*\e[0m"; }
info () { notice "\e[36m$*\e[0m"; }
warn () { notice "\e[33m$*\e[0m" >&2; }
notice () { log "\e[1m$*\e[22m"; }
error () { warn "\e[31m$*\e[0m"; }
fatal () { error "$@"; exit 1; }
main() {
declare -A host_groups=(
[mlt]="bran.mlt sansa.mlt brienne.mlt pdu1.mlt smsgw1.mlt"
[rbsov]="tyrion.rbsov theon.rbsov"
[gce]="jorah.gce root-me.gce bets-pe.gce ns1.gce neech-me-uk.gce"
)
for group in "${!host_groups[@]}" ; do
echo "# Automatically generated by $0 at $(date)" > "ssh_known_hosts.$group.j2"
for host in $(resolve_all_names ${host_groups[$group]} | sort -u) ; do
local forward="$(resolve_ptr "$host")"
if ! is_host_alive "$host" ; then
error "No ping response from $host${forward:+ ($forward)}; skipping ..."
continue
fi
local port="$(get_ssh_port $host)"
local keyscan="$(ssh-keyscan -T 4 -H -t rsa -p $port $host 2>/dev/null)"
local pubkey1="${keyscan##* }"
local pubkey2="$(ssh -p $port "$host" "cut -d' ' -f2 /etc/ssh/ssh_host_rsa_key.pub")"
if [[ -z "$pubkey1" ]] ; then
warn "No host key returned by $host ${forward:+($forward) }[$group] using ssh-keyscan."
elif forgive_ssh_validation "$host" || forgive_ssh_validation "$forward" ; then
okay "Added $host ${forward:+($forward) }to $group."
echo "$keyscan" >> "ssh_known_hosts.$group.j2"
elif [[ -z "$pubkey2" ]] ; then
warn "No host key returned by $host ${forward:+($forward) }[$group] using ssh."
elif [[ "$pubkey1" == "$pubkey2" ]] ; then
okay "Added $host ${forward:+($forward) }to $group."
echo "$keyscan" >> "ssh_known_hosts.$group.j2"
elif ! [[ "$pubkey1" == "$pubkey2" ]] ; then
warn "Host key mismatch for $host [$group]."
else
error "Unknown $host ${forward:+($forward) }[$group]; $keyscan" >&2
fi
done
done
mv -v ssh_known_hosts.*.j2 roles/openssh-client/templates/ \
&& ~/src/ansible/play --tag openssh-client -l bran.mlt \
&& ~/src/ansible/play --tag openssh-client
}
ssh-add -l >/dev/null 2>&1 || ssh-add
main "$@"