-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathpushsshkeys
136 lines (112 loc) · 4.38 KB
/
pushsshkeys
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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#!/bin/bash
# Purpose: This is a wrapper script for expect.sshkeys
# This does some pre-req checks and distributes sshkeys
# to a List of servers in a required file: "serverList"
# Author: Rawiri Blundell, Datacom
# Date: June 2014
# Variables
serverList=serverlist
adminPwd="${PWD}/.pwdfiler"
compareStrings=1
# Basic Horizontal Rule function
hr() {
printf '%*s\n' "${1:-$COLUMNS}" | tr ' ' "${2:-#}"
}
# Check that $serverList exists
if [[ ! -f "${serverList}" ]]; then
printf '%s\n' "File '${serverList}' is required and doesn't exist where I expect it" \
"Please ensure this file is present in ${PWD}"
exit 1
fi
# Greet
hr 40
printf '\t%s\n' "You are running ${0##*/}"
hr 40
printf '%s\n' "" "This script attempts to distribute your sshkey across" \
" all the servers in the file '${serverList}'" \
"" "This assumes you have access on all servers listed, using the same password" \
"If not, consider exiting and sorting that out."
read -rp "Press [Enter] to continue or Ctrl-C to exit"
#### SSH Stuff ####
# Check for sshkeys and if not found, generate
# Does the local host support ed25519?
# Ancient versions of ssh don't have '-Q' so also likely won't have ed25519
# If you wanted a more portable test: man ssh | grep ed25519
if ssh -Q key 2>/dev/null | grep -q ed25519; then
localED25519=true
fi
# If the local host supports ed25519 and doesn't have a key, generate it
if [[ "${localED25519}" = "true" ]] && [[ ! -f ~/.ssh/id_ed25519.pub ]]; then
printf '%s\n' "I could not find an ed25519 sshkey, let me generate one for you..."
ssh-keygen -t ed25519 -N "" -f ~/.ssh/id_ed25519
fi
# Let's also generate an RSA key with 2048 bits for legacy purposes
if [[ ! -f ~/.ssh/id_rsa.pub ]]; then
printf '%s\n' "I could not find an RSA sshkey, let me generate one for you..."
ssh-keygen -t rsa -b 2048 -N "" -f ~/.ssh/id_rsa
fi
# Sanitise the serverlist file to prevent failures down the track
while read -r host; do
if ! nslookup "${host}" >/dev/null 2>&1; then
sed -i "/^${host}$/d" "${serverList}"
fi
done < "${serverList}"
# Get ~/.ssh/known_hosts up to scratch, this should reduce the need to depend on expect
# to take care of interacting with remote hosts for fingerprinting
# First, notify the user
printf '%s\n' "Please wait while I perform maintenance on your known_hosts file..."
if [[ -f ~/.ssh/known_hosts ]]; then
# Backup the current known_hosts file
# We filter out hosts that we're going to check anyway
# This auto-updates the entries (e.g. server rebuilds are catered for)
grep -vif "${serverList}" ~/.ssh/known_hosts > ~/.ssh/known_hosts.old
fi
# Generate a temporary known_hosts file from the serverlist
if [[ "${localED25519}" = "true" ]]; then
ssh-keyscan -t rsa,ed25519 -f "${serverList}" > ~/.ssh/known_hosts.new 2>/dev/null
else
ssh-keyscan -t rsa -f "${serverList}" > ~/.ssh/known_hosts.new 2>/dev/null
fi
# Now cat the old and new files together
cat ~/.ssh/known_hosts.old ~/.ssh/known_hosts.new 2>/dev/null | sort | uniq -u > ~/.ssh/known_hosts
# Double check perms
chmod 600 ~/.ssh/known_hosts
#### /SSH Stuff ####
# Remove any existing pwdfiler files and generate a new one
rm -f "${adminPwd}"
# Prompt for the authentication password twice
while (( compareStrings > 0 )); do
hr 40
printf '%s' "Please enter your password for authenticating and press [Enter]: "
read -rs pwdin1
printf '\n%s' "Please confirm your password and press [Enter]: "
read -rs pwdin2
# Compare the two, if they don't match, try again
if [[ "${pwdin1}" != "${pwdin2}" ]]; then
echo ""
read -rp "The passwords entered do not match. Press [Enter] to start again."
compareStrings=$(( compareStrings + 1 ))
else
# If the passwords match, write it to .pwdfiler
echo "${pwdin1}" > "${adminPwd}"
# And give the condition to exit the while loop
compareStrings=0
fi
done
# Secure pwdfiler
chmod 600 "${adminPwd}"
# Heavy Lifting
for host in $(<"${serverList}"); do
# We now call an expect script that essentially automates the following
#ssh-copy-id -i /home/$user/.ssh/id_rsa.pub "${host}"
if grep "${host}" ~/.ssh/known_hosts | grep -q ed25519; then
./expect.sshkeys "${host}" ed25519
else
./expect.sshkeys "${host}" rsa
fi
# Alternative method that might be figured out in the future:
#cat ~/.ssh/id_rsa.pub | ssh $user@$host "cat - >> .ssh/authorized_keys"
done
# Cleanup
# Remove any pwdfiler files
#rm -f "${adminPwd}"