Commit a61e7fdd authored by Michael Völske's avatar Michael Völske

authorized-ssh-keys: add option to remove a given key everywhere

Closes code-generic/code-admin-knowledgebase#12
parent 21335c5b
......@@ -10,13 +10,13 @@ scriptPath=${0%/*}
. "$scriptPath"/../../libs/bashhelper.sh
. "$scriptPath"/../../libs/shflags
check_tools "ssh" "salt"
check_tools "ssh" "salt" "pv" "awk" "pr"
#
# Define usage screen.
#
usage() {
echo "usage:
echo "usage:
$(basename "$0")
description:
......@@ -30,51 +30,117 @@ description:
#
FLAGS_HELP=$(usage)
export FLAGS_HELP
DEFINE_boolean report true 'Print key report after collecting' p
DEFINE_boolean remove false 'Select keys for removing/revoking after collecting' r
FLAGS "$@" || exit 1 # Parse command line arguments.
eval set -- "${FLAGS_ARGV}"
KEY_LIST=$( mktemp )
#
# Main
#
main() {
collect_keys() {
timeout -k1 6 salt -t 5 '*' cmd.run \
'find /root /home -path "*/.ssh/authorized_keys" -maxdepth 5 -exec cat \{\} \; 2> /dev/null ' \
--output=txt \
| pv -rblt -N 'collecting keys' \
| sort -t: -k2 -k1V \
> $KEY_LIST
echo $KEY_LIST
}
brief_key() {
T=$( echo -n $1 | sed 's/ssh-//' )
K=$2
CK=$( echo -n $K | base64 -d 2>/dev/null )
shift 2
echo "$T..${K:$((${#K}-4)):4}[$( printf '%04d' $(( ${#CK} * 8 )) )bit]" $@
}
key_report() {
NUM_DEAD=0
KEYCOUNT=0
declare -A KPH
LIST=$( mktemp )
salt '*' cmd.run 'find /root /home -path "*/.ssh/authorized_keys" -maxdepth 4 -exec cat \{\} \;' --output=txt \
| sort -t: -k2 -k1V \
> $LIST
OUT=$(mktemp)
while IFS=":" read -r -a LINE ; do
H=${LINE[0]}
K=${LINE[1]}
if [[ $K =~ "did not return" ]]; then
NUM_DEAD=$(( NUM_DEAD + 1))
continue
fi
if [[ $K =~ ^[\ \t]*$ ]]; then K=""; fi
if [[ $K != $LASTKEY && $K != "" ]]; then
echo Key: $K
echo Used on hosts:
KEYCOUNT=$(( $KEYCOUNT + 1 ))
LASTHOST=""
fi
if [[ $K != "" && $H != $LASTHOST ]]; then
echo " - $H"
LASTHOST=$H
KPH[$H]=$(( ${KPH[$H]} + 1 ))
fi
LASTKEY=$K
done < $LIST
rm -f $LIST
H=${LINE[0]}
K=${LINE[1]}
if [[ $K =~ "did not return" ]]; then
NUM_DEAD=$(( NUM_DEAD + 1))
continue
fi
if [[ $K =~ ^[\ \t]*$ ]]; then K=""; fi
if [[ $K != $LASTKEY && $K != "" ]]; then
echo Key: $( brief_key $K )
KEYCOUNT=$(( $KEYCOUNT + 1 ))
LASTHOST=""
fi
if [[ $K != "" && $H != $LASTHOST ]]; then
echo " - $H"
LASTHOST=$H
KPH[$H]=$(( ${KPH[$H]} + 1 ))
fi
LASTKEY=$K
done < $KEY_LIST > $OUT
pr -Tt -w $( tput cols ) --columns $(( $( tput cols ) / 50 )) "$OUT"
rm -f "${OUT}"
echo "TOTAL UNIQUE KEYS: $KEYCOUNT; $NUM_DEAD hosts offline; ${#KPH[@]} hosts online."
}
select_and_remove_keys() {
declare -A KEYS
IN=$(mktemp)
OUT=$(mktemp)
I=0
awk -F: '/did not return/ { next; } { print $2; }' $KEY_LIST | sort | uniq -c \
| sed 's/^ *\([0-9]\+\) /\1\t/' > $IN
while IFS=$'\t' read -r -a ITEM ; do
N=${ITEM[0]}
KEY=$( echo ${ITEM[1]} | sed 's/^ *//' )
[[ ${#KEY} -gt 0 && ${KEY} != 'find' ]] || continue
printf "%3d) %s (%d hosts)\n" $I "$( brief_key $KEY )" "$N"
KEYS[$I]="$KEY"
I=$((I+1))
done < $IN > $OUT
pr -Tt -w $( tput cols ) --columns $(( $( tput cols ) / 50 )) $OUT
rm -f $IN
rm -f $OUT
read -p 'Key numbers to remove, space separated: ' -a REM
for I in "${REM[@]}"; do
echo "The following key will be removed from all hosts:"
echo ${KEYS[$I]}
export KEY="${KEYS[$I]}"
yes_no_prompt "Proceed?" && {
KEY=$( echo $KEY | sed 's/^ *//;s/ *$//' | base64 -w0 )
timeout -k1 5 salt -t 5 '*' cmd.run "find /root /home -maxdepth 5 -path '*/.ssh/authorized_keys' -print0 | xargs -0 -n1 -I % bash -c 'TMP=\$(mktemp) && grep -Fxv -f <( echo $KEY | base64 -d ) \"%\" > \${TMP} && ( diff -q -c0 \${TMP} \"%\" || mv -v \${TMP} \"%\" ) ' "
}
done
}
#
# Main
#
main() {
collect_keys
[[ ${FLAGS_report} = ${FLAGS_TRUE} ]] && key_report
[[ ${FLAGS_remove} = ${FLAGS_TRUE} ]] && select_and_remove_keys
rm -f $KEY_LIST
echo "IMPORTANT NOTICE: Only hosts reachable via salt have been checked. Please check hosts not managed via salt manually (webis.uni-weimar.de, staff workstations) "
}
#
# Start programm with parameters.
#
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment