Жёсткая защита SSH: ключи, белые списки, запрет root и двухфакторная аутентификация

Быстрые ссылки
- Не разрешать вход по паролю — использовать SSH-ключи
- Блокировать атакующих с помощью denyhosts
- Белый список для доступа по SSH
- Запрет входа root
- Настроить двухфакторную аутентификацию
Введение
SSH (Secure Shell) предоставляет защищённый доступ к серверу, но при стандартных настройках часто включена простая парольная аутентификация без дополнительных ограничений. Это делает сервер уязвимым к атаке подбором паролей и брутфорсу. В этой статье описаны практические шаги по укреплению SSH: от генерации ключей до продвинутых мер — прокси, 2FA, процедуры восстановления и тесты для приёмки.
Important: Перед изменением конфигурации SSH убедитесь, что у вас есть альтернативный способ доступа (консоль провайдера, облачная панель или физический доступ), иначе ошибка конфигурации может заблокировать вас.
Не разрешать вход по паролю — использовать SSH-ключи
Ключевая рекомендация — полностью отключить аутентификацию по паролю и перейти на SSH-ключи. SSH-ключи используют криптографию с открытым ключом: у вас есть публичный ключ (аналог логина) и приватный ключ (аналог пароля, но гораздо длиннее и безопаснее). Приватный ключ хранится на вашем диске и защищён фразой-паролем и ssh-agent.
Даже если вы уже используете ключи, обязательно отключите парольную аутентификацию — обе опции могут быть включены одновременно.
Генерация SSH-ключей
На большинстве Unix-систем установлен утилитный набор OpenSSH, включающий ssh-keygen. Для создания пары ключей выполните:
ssh-keygenУтилита попросит фразу-пароль для шифрования локального приватного ключа. Эта фраза не используется сервером при входе, но её стоит хранить в секрете.
По умолчанию приватный ключ сохраняется в ~/.ssh/id_rsa, а публичный в ~/.ssh/id_rsa.pub. Приватный ключ остаётся на вашей машине; публичный ключ нужно скопировать на сервер, чтобы сервер мог подтверждать вашу личность.
Сервер хранит список разрешённых ключей в ~/.ssh/authorized_keys. Вы можете добавить ключ вручную или использовать ssh-copy-id:
ssh-copy-id -i ~/.ssh/id_rsa.pub user@hostЗамените user@host на имя пользователя и адрес сервера. Вас попросят один раз ввести пароль, после чего вход по ключу должен работать.
Отключение входа по паролю
После того как вход по ключу подтверждён, можно отключать парольную аутентификацию. На сервере откройте /etc/ssh/sshd_config в удобном редакторе и найдите строку:
#PasswordAuthenticationУберите символ # и задайте значение no:
PasswordAuthentication noПерезапустите службу sshd:
systemctl restart sshdПосле перезапуска вы будете вынуждены использовать ключи; неверный ключ приведёт к отказу в подключении без запроса пароля.
Дополнительно можно принудительно требовать только публичную аутентификацию, заблокировав остальные методы. Добавьте в /etc/ssh/sshd_config:
AuthenticationMethods publickey
PubkeyAuthentication yesи перезапустите sshd.
Important: Не вносите изменения удалённо без тестирования — держите второе соединение открытым при применении, чтобы откатить, если нужно.
Lock Out Attackers with denyhosts
denyhosts — утилита для автоматической блокировки повторных неудачных попыток входа по SSH. Она похожа по принципу на то, как телефон блокирует попытки после нескольких неверных вводов.
Для Debian-подобных систем установка выглядит так:
sudo apt-get install denyhosts -yВключите службу:
sudo systemctl enable denyhostsWhitelist вашего IP обязательно, чтобы не заблокировать себя:
Откройте /etc/hosts.allow и добавьте в конец:
sshd: your-ip-addressПо умолчанию denyhosts блокирует после одной неудачной попытки для root и пяти — для других пользователей. Эти параметры можно изменить в /etc/denyhosts.conf.
Если себя заблокировали, остановите denyhosts и удалите ваш IP из следующих файлов:
- /etc/hosts.deny
- /var/lib/denyhosts/hosts
- /var/lib/denyhosts/hosts-restricted
- /var/lib/denyhosts/hosts-root
- /var/lib/denyhosts/hosts-valid
- /var/lib/denyhosts/users-hosts
Затем перезапустите denyhosts.
Важно: denyhosts полезен на одиночных серверах, но при масштабируемых средах и балансировщиках стоит использовать централизованные решения (firewall, fail2ban, WAF).
Белый список доступа по SSH
Принудительное использование ключей и denyhosts часто достаточно, но можно пойти дальше и ограничить доступ по IP-адресам.
Большинство облачных провайдеров позволяет настроить правила входящего трафика через веб-интерфейс. Если это возможно — предпочтительнее настраивать белый список у провайдера: это даёт доступ к панели управления при ошибках и упрощает откат.

Если провайдера нет или вы на физическом сервере, можно вручную настроить /etc/hosts.allow и /etc/hosts.deny.
Добавьте в /etc/hosts.allow:
sshd: your-ip-addressЗатем можно запретить все остальные соединения:
echo 'sshd: ALL' >> /etc/hosts.denyПерезапустите sshd и проверьте доступ.
Note: Если ваш провайдер не даёт статический IP, белый список может вас заблокировать при изменении адреса. Рассмотрите добавление резервных адресов, использование динамического DNS или отказ от белого списка.
Альтернатива: прокси перед SSH
Если нужно доступаться с разных адресов, но вы не хотите открывать SSH в интернет, можно поставить прокси-сервер (bastion/jump host). Настройте основной SSH-сервер принимать соединения только от прокси, а прокси — принимать соединения откуда угодно. Варианты реализации:
- Bastion host в облаке с ограничением доступа по ключам
- SSH jump через другую виртуальную машину
- Обратный SSH туннель или упрощённый netcat-прокси для полевой работы
Минус: прокси становится единой точкой отказа — организуйте резервный маршрут.
Не разрешать вход под root
Вместо прямого входа под root создавайте отдельного пользователя с правами sudo. Это уменьшает площадь атаки — злоумышленнику нужно знать имя пользователя, и дополнительно вы получите более читабельные логи.
Создание пользователя:
adduser myfancyusername
passwd myfancyusernameДобавление в sudoers:
echo 'myfancyusername ALL=(ALL) ALL' >> /etc/sudoersПроверьте переключение:
su myfancyusername
sudo suЧтобы запретить вход root, отредактируйте /etc/ssh/sshd_config и найдите:
#PermitRootLogin yesИзмените на:
PermitRootLogin noПерезапустите sshd.
Совет: можно разрешить root вход только с публичного ключа, указав PermitRootLogin prohibit-password или without-password (в новых версиях — prohibit-password эквивалентно запрету паролей для root и допускает ключи).
Настройка двухфакторной аутентификации
Если вы опасаетесь компрометации приватного ключа, добавьте второй фактор. Самый популярный и простой вариант — Google Authenticator (TOTP) для мобильных устройств. Процесс общий:
- Установите пакет для PAM, например libpam-google-authenticator.
- Запустите google-authenticator на сервере для каждого пользователя и получите QR-код и резервные коды.
- Настройте PAM и sshd для запроса и проверки одноразовых кодов.
Важно: Не храните резервные коды на той же машине, иначе фактор не будет независимым.
Практические шаблоны конфигурации
Пример минимально безопасного /etc/ssh/sshd_config (урезано для ключевых опций):
Port 22
Protocol 2
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
AuthenticationMethods publickey
PermitEmptyPasswords no
ChallengeResponseAuthentication yes
UsePAM yes
X11Forwarding no
AllowTcpForwarding no
LoginGraceTime 30
MaxAuthTries 3Добавьте правила firewall (пример для UFW):
ufw allow from your-ip-address to any port 22 proto tcp
ufw enableМодель принятия решений
Если вы не уверены, какая стратегия подходит, используйте эту простую методику:
- Нужен доступ из множества динамических адресов? — Используйте bastion/proxy.
- Есть стабильный набор клиентских IP? — Белый список на уровне провайдера или UFW.
- Хотите максимальную защиту для небольшой команды? — SSH-ключи + 2FA + запрет root + denyhosts/fail2ban.
Mermaid диаграмма принятия решения:
flowchart TD
A[Нужно подключаться к серверу?] --> B{Много IP или мало?}
B -->|Мало/статичные| C[Белый список на провайдере]
B -->|Много/динамичные| D[Использовать bastion/proxy]
C --> E[Отключить пароли, включить ключи]
D --> E
E --> F{Требуется 2FA?}
F -->|Да| G[Добавить TOTP]
F -->|Нет| H[denyhosts/fail2ban + мониторинг]План действий на случай блокировки (инцидент)
- Оставьте одно SSH-соединение открытым пока тестируете настройки.
- Если заблокированы — доступ через облачную консоль, IPMI или панель провайдера.
- Откатьте изменения /etc/ssh/sshd_config или временно включите PasswordAuthentication yes.
- Удалите IP из hosts.deny и файлов denyhosts, если применимо.
- Перезапустите службы: sshd, denyhosts.
- Проведите аудит: логи /var/log/auth.log, проверьте /var/log/secure.
Критерии приёмки
- Вход по паролю невозможен для всех пользователей.
- Вход по ключу работает для тестовой учётной записи.
- Прямой вход под root запрещён.
- denyhosts/fail2ban блокирует повторяющиеся попытки.
- Наличие плана восстановления и доступ к консоли провайдера.
Роль-зависимые чеклисты
Администратор:
- Сгенерировал ключи и настроил ssh-agent.
- Проверил работу ssh-copy-id для всех пользователей.
- Обновил /etc/ssh/sshd_config и перезапустил sshd.
- Настроил резервный доступ (консоль провайдера).
- Настроил denyhosts или fail2ban.
DevOps:
- Интегрировал изменения в конфигурацию инфраструктуры (Ansible/CloudInit/Terraform).
- Настроил bastion host и аудит логов.
- Прописал правила firewall и проверил их тестами.
Конечный пользователь:
- Сохраняет приватный ключ в защищённом месте.
- Использует фразу-пароль для приватного ключа.
- Настроил двухфакторную аутентификацию, если требуется.
Тесты и сценарии приёмки
- Попытка входа с отключёнными ключами: ожидание — доступ запрещён.
- Попытка входа с правильным ключом: ожидание — успешное соединение.
- Попытка входа под root: ожидание — отказ.
- Множественные неудачные попытки с одного IP: ожидание — IP блокируется (denyhosts/fail2ban).
- Удаление IP из белого списка: ожидание — потеря доступа (проверить откат через панель провайдера).
Частые ошибки и когда методы не сработают
- Использование паролей и ключей одновременно: если вы отключите пароли без настройki ключей — заблокируете себя.
- Динамический IP клиента при белом списке: ваш IP может измениться, и вы потеряете доступ.
- Централизованные машины в масштабе: denyhosts на каждой машине плохо масштабируется — используйте fail2ban или сетевые ACL.
- Прокси как единая точка отказа: без резервного доступа вы можете потерять возможность подключиться.
Короткая методология внедрения (минимальный набор)
- Сгенерировать SSH-ключ и проверить вход по ключу.
- Забелить свой IP в /etc/hosts.allow (опционально).
- Отключить PasswordAuthentication и перезапустить sshd.
- Добавить пользователя с sudo и запретить root.
- Установить denyhosts/fail2ban.
- Настроить резервный доступ и протестировать откат.
Краткий словарь
- SSH-ключ: пара криптографических ключей (приватный + публичный) для аутентификации.
- Public key: публичная часть, загружается на сервер.
- Private key: приватная часть, хранится локально и защищается фразой-паролем.
- Bastion: промежуточный сервер для доступа к внутренним ресурсам.
- 2FA / TOTP: одноразовые коды, генерируемые приложением (например, Google Authenticator).
Итог
Защита SSH — это сочетание простых правил и процедур: используйте SSH-ключи вместо паролей, запретите вход под root, применяйте автоматическую блокировку подозрительных попыток и ограничьте доступ с помощью белых списков или bastion. Всегда имейте план восстановления и тестируйте изменения в контролируемой среде.
Заметки
- Для больших инфраструктур рассмотрите централизованные решения: Vault для управления ключами, централизованные ACL на LB, SIEM для анализа попыток доступа.
- Регулярно пересматривайте и вращайте ключи, особенно для сервисных аккаунтов.
Похожие материалы
Миграция Philips Hue на новый мост
Первая рассылка на Substack: пошагово
Что рядом со мной? — карта статей Википедии
Как записать звук в Audacity — Windows и Mac
Как настроить и использовать Apple Watch