SSH — Авторизация по ключу, что делать если ключ украли.
Ни для кого ни секрет насколько удобна авторизация по публичному ключу, а если для кого-то секрет - то можете ознакомиться вот с этой статьёй.
Но случается и такое, что ключ нужно заменить, причины? Честно говоря вижу только две - ключ скомпрометирован и, что почти то же самое, его украли.
Заменить ключ не составляет особого труда - всего-то нужно удалить с серверов старый публичный и записать вместо него новый. Вроде бы всё предельно просто, а что если серверов не один, не два и не три, а 10, 20 и более? Вот тут-то и просыпается великая и могучая лень 🙂 Но есть необходимость, а значит нужно что-то делать.
На этот случай и был написан небольшой скрипт:
renew.sh
# Author: Dmitriy Beketov (freemandigger --@-- gmail.com)
# Site: http://gentooway.ru
# Licence: Attribution-Noncommercial 3.0 Unported (http://creativecommons.org/licenses/by-nc/3.0/)
USAGE="Usage: ${0#*/} [-i id_rsa.old] [-d] <id_rsa.pub.old> <id_rsa.pub.new> <host list>"
privkey=""
dryrun=0
# Parse command line
while getopts i:d opt; do
case "$opt" in
i) privkey="$OPTARG";;
d) dryrun=1;;
*) echo $USAGE;;
esac
done
shift $(($OPTIND - 1))
[[ "$1" == '--' ]] && shift
if [[ $# -lt 3 ]]; then
echo $USAGE
exit 1
fi
oldpubkey=$1
hostlist=$3
newpubkey=$2
# Check files for exist
if [ "$privkey" ]; then
if [ ! -f "$privkey" ]; then
echo $USAGE
echo "Old private key file not found"
exit 1
fi
privkey="-i $privkey"
fi
if [ ! -f "$oldpubkey" ]; then
echo $USAGE
echo "Old public key file not found"
exit 1
fi
if [ ! -f "$hostlist" ]; then
echo $USAGE
echo "Host list not found"
exit 1
fi
if [ ! -f "$newpubkey" ]; then
echo $USAGE
echo "New public key file not found"
exit 1
fi
# Get the part of old public key for grep
OLD=`cat $oldpubkey | awk '{print $2}'`
SSH='/usr/bin/ssh'
SSH_COPY='/usr/bin/ssh-copy-id'
SCP='/usr/bin/scp'
test $dryrun -gt 0 && echo "START DRY RUN" || echo "START"
for host in `cat $hostlist`
do
printf "Copy new key to $host\n"
$SCP -q $privkey $newpubkey $host:.ssh/newpubkey
if [ "$?" > 0 ]; then
printf "\t[OK]\n"
printf "\tAdding new key to authorized_keys\n"
test $dryrun -gt 0 && printf "dry run" || $SSH $privkey $host "cat ~/.ssh/newpubkey >> ~/.ssh/authorized_keys"
test $? -gt 0 && printf "\t[FAIL]\n" || printf "\t[OK]\n"
printf "\tDeleting temporary file of new public key\n"
$SSH $privkey $host "rm ~/.ssh/newpubkey"
test $? -gt 0 && printf "\t[FAIL]\n" || printf "\t[OK]\n"
printf "\tBackup authorized_keys to authorized_keys.bak\n"
test $dryrun -gt 0 && printf "dry run" || $SSH $privkey $host cp .ssh/authorized_keys .ssh/authorized_keys.bak
test $? -gt 0 && printf "\t[FAIL]\n" || printf "\t[OK]\n"
printf "\tDeleting old public key from authorized_keys\n"
test $dryrun -gt 0 && printf "dry run" || $SSH $privkey $host "cat ~/.ssh/authorized_keys.bak | grep -v '$OLD' > ~/.ssh/authorized_keys"
test $? -gt 0 && printf "\t[FAIL]\n" || printf "\t[OK]\n"
else
printf "\t[FALSE]\n"
fi
done
echo "FINISH"
exit 0
Параметры вызова (не обязательные):
-d - Тестовый запуск, скрипт попробует скопировать новый ключ во временный файл на удалённом сервере, а затем его же и удалить.
-i - Ключ для авторизации на серверах, на случай если в ~/.ssh/id_rsa уже установлен новый ключ то в данном параметре можно указать где брать старый.
Параметры вызова (обязательные):
id_rsa.pub.old - старый публичный ключ, который нужно заменить.
id_rsa.pub.new - новый публичный ключ.
host list - файл со списком пользователей/серверов, где нужно заменить ключ, формат user@host или из ~/.ssh/config
user2@host2
user223@host4
my_predefined_host
blabla@eee
Также можно скачать скрипт