Выявление сессий по ключу SSH: различия между версиями
Дым (обсуждение | вклад) м (Дым переименовал страницу Выявление входов по ключу SSH в Выявление сессий по ключу SSH) |
Дым (обсуждение | вклад) Нет описания правки |
||
(не показано 11 промежуточных версий этого же участника) | |||
Строка 16: | Строка 16: | ||
#!/bin/bash | #!/bin/bash | ||
USER=${1:-admin} # умолчальный юзер, если не задан иной. | |||
KEYS=`eval echo ~$USER`/.ssh/authorized_keys # ключ-файл. | |||
UNIT=ssh | UNIT=ssh | ||
case `awk -F= '/^NAME/{gsub("\"","");print $2}' /etc/os-release` in | case `awk -F= '/^NAME/{gsub("\"","");print $2}' /etc/os-release` in | ||
ALT*) UNIT+=d;; | ALT*) UNIT+=d;; | ||
esac | esac | ||
case $LANG in | case $LANG in | ||
ru*)printf " Дата Время Логин | ru*)printf " Дата Время Логин Откуда Чей ключ\n";; | ||
*) printf " Date Time Login | *) printf " Date Time Login Where from Key owner\n" | ||
esac | esac | ||
## В старых линуксах лучше делать так: | |||
LINE=($LOGINS) | readarray -t LOGINS < <(journalctl -o short-iso -u $UNIT | \ | ||
awk '/Accepted publickey/{sub("ROOT USER","");print $1,$7,$9,$14}') | |||
for ((i=0;i<${#LOGINS[@]};i++)); do | |||
LINE=(${LOGINS[$i]}) | |||
DATE=${LINE[0]%+*} | DATE=${LINE[0]%+*} | ||
OWNER=`ssh-keygen -E SHA256 -lf $KEYS | grep "${LINE[3]}" | cut -d' ' -f3` | OWNER=`ssh-keygen -E SHA256 -lf $KEYS | grep "${LINE[3]}" | cut -d' ' -f3` | ||
printf "${DATE/T/ } %-10s %-15s | printf "${DATE/T/ } %-10s %-15s $OWNER\n" ${LINE[1]} ${LINE[2]} | ||
done | |||
</source> | </source> | ||
|} | |} | ||
Вывод выглядит так: | Вывод выглядит так: | ||
<pre> | <pre> | ||
Дата Время Логин | Дата Время Логин Откуда Чей ключ | ||
год-мес-день ЧЧ:ММ:СС логин ип.ад.ре.с владелец@ключа | год-мес-день ЧЧ:ММ:СС логин ип.ад.ре.с владелец@ключа | ||
... | ... | ||
Строка 49: | Строка 52: | ||
Куда сложней обстоит дело с завершением таких сеансов ввиду перманентной долбёжки ботами, войти которые не могут (не только ввиду отключённого парольного доступа, но их ещё и {{cmd|fail2ban}} за настырность блокирует), однако выходить после неудач вынуждены — что журналируется, забивая выходы «честных бродяг». | Куда сложней обстоит дело с завершением таких сеансов ввиду перманентной долбёжки ботами, войти которые не могут (не только ввиду отключённого парольного доступа, но их ещё и {{cmd|fail2ban}} за настырность блокирует), однако выходить после неудач вынуждены — что журналируется, забивая выходы «честных бродяг». | ||
Посему длительность сессии приходится прикидывать наугад, выявляя глазами ближайшие | Посему длительность сессии приходится прикидывать наугад, выявляя глазами логауты, ближайшие под логином по ключу. | ||
Можно ещё поискать {{cmd|awk '/Received disconnect/'}} по совпадающим адресу и номеру порта, но сколько времени займёт такой поиск — угадать крайне затруднительно. | Можно ещё поискать {{cmd|awk '/Received disconnect/'}} по совпадающим адресу и номеру порта, но сколько времени займёт такой поиск — угадать крайне затруднительно. |
Текущая версия от 14:06, 29 сентября 2023
Входы
Когда к одному логину на сервере приходится давать доступ нескольким персоналиям (например, разным разработчикам к логину webmaster
для работы с сайтом), хотелось бы понимать, кто именно, откуда и когда входил.
И это далеко не столь сложно, как может представляться, поскольку в журнал SSHd сыплются в т.ч. сообщения формата:
<дата> <время> <хост назначения> <демон[пид]> Accepted publickey for <логин> from <IP-адрес> port <номер> ssh2: <алгоритм ключа> <контрольная сумма ключа>
В то же время, чек-суммы ключей для допущенных пользователей…
- можно получить командой ssh-keygen -E SHA256 -lf ~/.ssh/authorized_keys из указанного в ней файла, где они хранятся в виде:
ssh-<алгоритм> <публичный ключ> <его владелец>
- и сопоставить их со входами этих пользователей.
Набросал для этих целей скриптец:
/usr/local/bin/sswho |
---|
#!/bin/bash
USER=${1:-admin} # умолчальный юзер, если не задан иной.
KEYS=`eval echo ~$USER`/.ssh/authorized_keys # ключ-файл.
UNIT=ssh
case `awk -F= '/^NAME/{gsub("\"","");print $2}' /etc/os-release` in
ALT*) UNIT+=d;;
esac
case $LANG in
ru*)printf " Дата Время Логин Откуда Чей ключ\n";;
*) printf " Date Time Login Where from Key owner\n"
esac
## В старых линуксах лучше делать так:
readarray -t LOGINS < <(journalctl -o short-iso -u $UNIT | \
awk '/Accepted publickey/{sub("ROOT USER","");print $1,$7,$9,$14}')
for ((i=0;i<${#LOGINS[@]};i++)); do
LINE=(${LOGINS[$i]})
DATE=${LINE[0]%+*}
OWNER=`ssh-keygen -E SHA256 -lf $KEYS | grep "${LINE[3]}" | cut -d' ' -f3`
printf "${DATE/T/ } %-10s %-15s $OWNER\n" ${LINE[1]} ${LINE[2]}
done
|
Вывод выглядит так:
Дата Время Логин Откуда Чей ключ год-мес-день ЧЧ:ММ:СС логин ип.ад.ре.с владелец@ключа ... год-мес-день ЧЧ:ММ:СС логин ип.ад.ре.с владелец@ключа
Выходы
Куда сложней обстоит дело с завершением таких сеансов ввиду перманентной долбёжки ботами, войти которые не могут (не только ввиду отключённого парольного доступа, но их ещё и fail2ban за настырность блокирует), однако выходить после неудач вынуждены — что журналируется, забивая выходы «честных бродяг».
Посему длительность сессии приходится прикидывать наугад, выявляя глазами логауты, ближайшие под логином по ключу.
Можно ещё поискать awk '/Received disconnect/' по совпадающим адресу и номеру порта, но сколько времени займёт такой поиск — угадать крайне затруднительно.