Харденинг SSH и аутентификация по ключам¶
Каждый сервер Linux, смотрящий в интернет, сканируется на предмет SSH-логинов в течение минут после подключения. Эта статья — о переходе от парольной аутентификации к аутентификации по ключам и об изменениях в sshd_config, которые реально значимо снижают поверхность атаки.
Как это устроено¶
Генерация и развёртывание пары ключей¶
-t ed25519 выбирает алгоритм Ed25519 — ключи меньше и проверка быстрее, чем у RSA, с эквивалентной или лучшей безопасностью в реальных условиях; предпочитайте его, если не нужна поддержка действительно древнего клиента/сервера, который появился раньше него (RSA с ключом 4096 бит, -t rsa -b 4096 — запасной вариант). Это создаёт приватный ключ (~/.ssh/id_ed25519, никогда никому не передавайте) и публичный ключ (~/.ssh/id_ed25519.pub, безопасно передавать — именно он размещается на серверах).
Это дописывает ваш публичный ключ в ~/.ssh/authorized_keys на удалённом сервере (создавая файл и директорию с правильными правами при необходимости). Эквивалент вручную:
cat ~/.ssh/id_ed25519.pub | ssh user@server 'mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys'
Права доступа важны: sshd молча откажется использовать файл authorized_keys (или директорию .ssh), доступный для записи группе или всем, в качестве меры безопасности против вмешательства других локальных пользователей. 700 для ~/.ssh, 600 для authorized_keys и самого приватного ключа.
Харденинг sshd_config¶
Ключевые настройки в /etc/ssh/sshd_config (подтвердите, что ваша версия OpenSSH их поддерживает — они стабильны уже много лет, ssh -V покажет вашу версию):
PasswordAuthentication no
PermitRootLogin no
PubkeyAuthentication yes
MaxAuthTries 3
AllowUsers deploy admin
PasswordAuthentication no— только после подтверждения, что вход по ключу реально работает, в отдельной сессии, прежде чем закрывать текущую. Это самый важный шаг харденинга: он делает перебор паролей против SSH полностью бессмысленным, поскольку угадывать больше нечего.PermitRootLogin no— заставляет даже легитимных админов входить под именованным пользователем и использоватьsudo, что также означает, что каждое привилегированное действие атрибутируется конкретной учётной записи в логах.MaxAuthTries 3— отключает после стольки неудачных попыток в рамках одного соединения (не долговременный бан — для этого смотрите fail2ban ниже). Осторожно: каждый ключ, который предлагает ваш SSH-агент, считается отдельной попыткой, поэтому при нескольких загруженных ключах низкое значение может разорвать соединение раньше, чем будет испробован нужный ключ — укажите ключ явно:ssh -o IdentitiesOnly=yes -i ~/.ssh/id_ed25519 user@server.AllowUsers— явный allowlist того, каким локальным учётным записям вообще разрешено подключаться по SSH, независимо от наличия у них валидных учётных данных. Опечатка или пропущенное имя здесь полностью закрывает этой учётной записи вход по SSH — в том числе вашей.
После любого изменения sshd_config:
sudo sshd -t # проверка синтаксиса ПЕРЕД перезапуском — безопасно ловит опечатки
sudo systemctl restart sshd # Debian/Ubuntu: юнит называется ssh.service (алиас sshd обычно тоже работает)
sshd -t проверяет конфиг, не затрагивая работающий демон — всегда запускайте это перед перезапуском, поскольку синтаксическая ошибка вместе с перезапуском может оставить вас вообще без работающего SSH-демона и без способа вернуться удалённо.
Проверяйте также действующую конфигурацию, а не только файл, который вы правили:
OpenSSH берёт для каждого параметра первое найденное значение, а дистрибутивы подключают файлы из /etc/ssh/sshd_config.d/*.conf в начале sshd_config. Поэтому 50-cloud-init.conf со строкой PasswordAuthentication yes в образе облачного провайдера молча перекрывает ваш PasswordAuthentication no ниже по основному файлу.
Ограничение повторных неудач через fail2ban¶
fail2ban следит за логом аутентификации, и после maxretry неудачных попыток с одного источника в пределах findtime вставляет правило файрвола, банящее этот источник на bantime. Это другой, дополняющий слой по отношению к MaxAuthTries в sshd_config — последний ограничивает попытки на соединение, fail2ban ограничивает попытки (и отдельные соединения) с одного IP-источника за время.
Различия Ubuntu/Debian и RHEL-подобных систем¶
| Ubuntu/Debian | RHEL-подобные | |
|---|---|---|
| Имя сервиса | ssh (юнит ssh.service) | sshd (юнит sshd.service) |
| SELinux | Не в режиме enforcing по умолчанию | Enforcing — ключ/файл в нестандартном месте может потребовать restorecon, чтобы получить правильный SELinux-контекст, прежде чем sshd его использует |
Практическое задание¶
- Сгенерируйте пару ключей Ed25519 и разверните публичный ключ на тестовой VM.
- Убедитесь, что вход по ключу работает, в новом терминальном сеансе, не закрывая текущий.
- Только после подтверждения шага 2: установите
PasswordAuthentication no, выполнитеsshd -t, затем перезапустите, затем откройте ещё одну новую сессию, чтобы убедиться, что парольный вход теперь отклоняется.
Как проверить, что всё сделано правильно¶
ssh -v user@server(подробный вывод) должен показатьAuthentication succeeded (publickey)и никогда не запрашивать пароль.- Попытка
ssh -o PreferredAuthentications=password user@serverпосле харденинга должна быть отклонена сразу, даже не запросив пароль. sudo sshd -T | grep -i passwordauthenticationдолжен вывестиpasswordauthentication no. Если выводитсяyes, хотя в файле стоитno, значение перекрывает drop-in из/etc/ssh/sshd_config.d/.
Типичные ошибки¶
- Отключение парольной аутентификации до подтверждения, что ключ работает. Если ваша единственная активная сессия закроется, а ключ на самом деле не работает — вы заблокированы; всегда сначала тестируйте во второй, независимой сессии.
- Копирование приватного ключа вместо публичного на сервер (файл без
.pub). Это не даёт доступа и обычно ещё и небезопасно оставляет ваш приватный ключ на удалённом хосте. - Забыть
sshd -tперед перезапуском после правки — опечатка вsshd_configможет помешать демону вообще запуститься, и вы узнаете об этом только после того, как он уже не работает.
⚠ Опасные команды¶
- Перезапуск
sshd/ssh.serviceсразу после непроверенного изменения конфига, в вашей единственной активной удалённой сессии, без консоли/доступа вне полосы в качестве запасного варианта. Всегда держите существующую сессию открытой и проверяйте новый конфиг в свежей. chmod -R(рекурсивно) на~/.sshможет изменить права приватного ключа на то, что sshd отклонит — вместо этого задавайте права на директорию и конкретные файлы явно.
Связанные статьи¶
Контрольные вопросы¶
- Почему нужно протестировать вход по ключу во второй сессии, прежде чем отключать парольную аутентификацию?
- В чём разница между тем, что ограничивает
MaxAuthTriesвsshd_config, и тем, что ограничивает fail2ban? - Почему sshd отказывается использовать файл
authorized_keys, доступный на запись группе? - Что именно проверяет
sshd -t, и почему запускать его перед каждым перезапуском?