OpenSSH без паролей: ввели политику и забыли про словарные атаки
Brute-force на SSH превратился в фоновый шум 2009 года. Перевели клиентов на ключи, закрыли root-вход, сменили порты - записи об отказах в логах упали на 99%.
Рост числа brute-force атак на SSH-серверы с открытыми портами в 2009 году
Если у вас есть Linux-сервер с SSH на 22-м порту и белым IP - с очень высокой вероятностью прямо сейчас кто-то пробует к нему подключиться. Не целенаправленно, просто боты сканируют весь адресный диапазон подряд и подбирают пароли. В этом году такой трафик стал настолько обыденным, что auth.log превратился в помойку: тысячи строк Failed password for root from, среди которых трудно заметить что-то реально важное.
Мы перестали воспринимать это как фоновый шум и сделали небольшой обход по клиентским серверам - посмотреть, у кого как. Картина оказалась предсказуемой и местами неприятной.
Что нашли
На нескольких серверах SSH торчал на стандартном порту с парольной аутентификацией, root-вход был разрешён. Пароли у root - у кого посложнее, у кого не очень. Ни у одного клиента не было настроен автоматический бан после серии неудачных попыток. Логи росли, никто их не читал.
Проблема не в том, что какой-то конкретный злоумышленник ломится к конкретному серверу. Проблема в том, что при таком уровне атак достаточно одного слабого пароля где-нибудь в инфраструктуре - у root, у технического пользователя, у кого-то кто поставил changeme и забыл. Боты перебирают миллионы комбинаций без устали, и рано или поздно что-то найдут.
Что сделали
Мы сформулировали обязательный минимум и прошлись по всем серверам в рамках сопровождения инфраструктуры. Три правила, которые закрывают большую часть проблемы.
Правило первое - только ключи. Парольная аутентификация выключается полностью. В /etc/ssh/sshd_config:
PasswordAuthentication no
ChallengeResponseAuthentication no
UsePAM no
Перед этим - само собой - нужно убедиться, что у всех нужных пользователей ключи уже лежат в authorized_keys. Порядок важен: сначала ключи, потом отключение паролей. Иначе можно выпилить самому себя с сервера, что несмешно.
Ключи генерируем RSA 2048 бит - этого вполне достаточно. Приватный ключ хранится у администратора на рабочей машине, на сервер уходит только публичная часть. Если нужен доступ для нескольких человек - каждый генерирует свой ключ, все публичные добавляются в authorized_keys. Никакого «одного ключа на всех» - иначе при увольнении сотрудника придётся перекручивать ключ на всех серверах сразу.
Правило второе - root не заходит по SSH никогда. PermitRootLogin no - и точка. Для административных задач есть непривилегированный пользователь плюс sudo. Это ещё и аудит: в логах видно, кто и под каким именем зашёл, прежде чем получил root-права, а не просто анонимный root непонятно откуда.
Правило третье - нестандартный порт. Это не безопасность в строгом смысле - кто хочет найти SSH на другом порту, тот найдёт через nmap. Но от 99% автоматизированного мусора это спасает: боты сканируют 22-й порт, получают Connection refused и уходят дальше. Выбрали порты из диапазона 10000-65000 - ничего особенного, просто не 22.
Дополнительно включили fail2ban там, где его ещё не было: пять неудачных попыток - бан IP на час. Это второй эшелон, но с ключевой аутентификацией он работает скорее как индикатор сканирования, чем как реальная защита.
Что изменилось
Результат заметен сразу. Там, где раньше auth.log писал по несколько тысяч строк в сутки об отказах аутентификации, после перехода на ключи и смены порта эти записи практически исчезли. Падение - порядка 99%, что хорошо совпадает с тем, что коллеги описывают в других местах.
Это не значит, что серверы стали неуязвимы. Это значит, что логи снова читаемы. Если там вдруг появится подозрительная активность - её теперь видно, а не зашумлено тысячей ботов с подбором паролей.
Был один неприятный момент в процессе: на одном сервере обнаружили, что root уже пытались взломать и несколько попыток с одного IP повторялись каждые несколько минут на протяжении нескольких часов. Пароль устоял, но осадок остался. Именно этот сервер перевели в первую очередь.
Что ещё стоит сделать
Три пункта выше - минимум. Если идти дальше:
AllowUsersилиAllowGroups- явный список пользователей, которым разрешён SSH. Все остальные отклоняются ещё до проверки ключа.ClientAliveIntervalиClientAliveCountMax- разрыв зависших сессий, которые висят без активности. Мелочь, но дисциплинирует.- Отдельный SSH-ключ для каждого сервера или группы серверов - компрометация одного ключа не открывает всё сразу. Чуть сложнее в управлении, но оправдано для критичных машин.
Всё это описывается в политике, которую мы теперь применяем к новым серверам сразу при вводе в эксплуатацию - не «потом настроим», а сразу как часть приёмки. Переделывать работающий сервер всегда дороже и нервознее, чем настроить правильно с первого раза.
Главное наблюдение по итогам: большинство атак на SSH - это не атаки на вас, это автоматизированный перебор всего интернета подряд. Перейти на ключи несложно и занимает час на сервер. Зато потом не нужно выискивать реальные инциденты среди тысяч строк мусора в логах.
- DDoS Twitter и Facebook: что это значит для нас · 9 июля 2009
- ARP-спуфинг в LAN: закрываем дыру на коммутаторе, а не на хостах · 26 февраля 2009