50 000 попыток за ночь: переходим на SSH-ключи
В логах одного из серверов обнаружили пятьдесят тысяч попыток входа за ночь - словарная атака на SSH. Перевели всё на ключи, убрали пароли, сдвинули порт. Атаки не прекратились, но стали бесполезны.
Брутфорс SSH-портов становится массовым - ключи вытесняют пароли на Linux-серверах
Началось банально. Один из сисадминов заметил, что сервер под утро ведёт себя как-то вяло - не критично, но заметно. Открыли /var/log/auth.log - и там пятьдесят с чем-то тысяч строк вида Failed password for invalid user admin from 218.x.x.x. За одну ночь. Один сервер. Один порт 22.
Формально - ничего страшного. Пароли у нас были нормальные, root-логин по SSH отключён. Но сам факт такого объёма атаки потребовал разобраться и закрыть вопрос правильно, а не просто посмотреть и забыть.
Откуда это берётся
Про ботнеты мы уже писали: заражённые машины по всему миру, никакой координации с человеком, просто перебирают адреса и словари. SSH на 22 порту - одна из любимых целей. Словарь несложный: admin, root, test, user, guest, ftp, плюс имена типа john, oracle, postgres. Потом идут пароли: 123456, password, admin, название сервиса.
Если в системе есть хоть один слабый аккаунт - рано или поздно попадут. А с пятьюдесятью тысячами попыток за ночь вопрос не «если», а «когда».
Что сделали
Решение на самом деле простое, просто требует аккуратности при накатке - не хочется выйти из сервера и не войти обратно.
Генерация ключей. На каждой рабочей машине администраторов генерируем пару через ssh-keygen. Алгоритм RSA, 2048 бит - вполне нормально. Приватный ключ с паролем, публичный - на сервер в ~/.ssh/authorized_keys. Это принципиальный момент: приватный ключ никуда не отправляется, сидит на машине администратора за паролем.
Проверяем, что вход по ключу работает - не закрывая существующую сессию. Открываем второй терминал, пробуем. Если зашло - продолжаем.
Правим sshd_config:
PasswordAuthentication no
ChallengeResponseAuthentication no
PermitRootLogin no
Перечитываем конфиг (service ssh reload), проверяем в третьем терминале - теперь без ключа не войти. Закрываем лишние сессии.
Меняем порт. 22 - порт, который сканируют в первую очередь. Перевели на нестандартный (что-то выше тысячи). Это не защита сама по себе - кто ищёт целенаправленно, найдёт. Но девяносто процентов автоматических сканеров работают по стандартным портам, и объём мусора в логах сразу падает.
AllowUsers - явный список пользователей, которым разрешён SSH. Всё, что не в списке, автоматически получает отказ ещё до авторизации.
Что поменялось
Атаки не прекратились. Они и не могут прекратиться - мы не контролируем ботнеты. Но теперь это выглядит иначе: в логах Connection refused или Connection closed без всяких Failed password. Боты стучатся - дверь закрыта, разговор не начинается.
Нагрузки от перебора практически нет: SSH-демон отвергает соединение быстро, без попыток подобрать пароль, потому что пароль больше не метод входа.
Один момент, который приходится держать в голове: если потеряешь приватный ключ или рабочую машину без резервной копии ключа - можешь потерять доступ к серверу. Поэтому ключи резервируем. У каждого администратора своя пара, все публичные ключи в authorized_keys. Если один из нас не может войти - другой заходит и разбирается.
Для серверов без физического доступа (арендованные, удалённые площадки) дополнительно держим аварийную консоль - IPMI/iLO решает именно такие ситуации. На случай если что-то пошло совсем не так.
Про fail2ban
Параллельно поставили fail2ban - он смотрит логи и банит IP после нескольких неудачных попыток. С ключами это скорее дополнительный слой, чем необходимость. Но штука полезная: сокращает шум в логах и слегка уменьшает нагрузку на сеть, не пуская особо настойчивых.
Где это не работает без дополнительных шагов
Ключи решают задачу для серверов, где администраторы заходят со своих машин. Сложнее с ситуациями, где надо дать временный доступ подрядчику или зайти с чужого компьютера. Тут либо выдаёшь временный ключ (и потом убираешь из authorized_keys), либо смиряешься с паролем для конкретного пользователя с ограниченными правами.
Для разработчиков в команде клиента отдельная история: не все умеют работать с ключами, приходится объяснять. Но это разовое усилие, потом привыкают.
В целом - решение рабочее, накатывается за час на любое количество серверов, и вопрос брутфорса SSH закрывается полностью. Пятьдесят тысяч попыток в логах всё равно остаются, но они теперь просто статистика, а не угроза.
- Ботнеты: машина не тормозит, просто рассылает спам · 21 марта 2005
- Контроль USB-устройств: как закрыть флешки и не парализовать работу · 19 мая 2005