SSH-ключ с 25 точками-правилами безопасности ed25519 SSH KEY 2026 standard 01 PermitRootLogin no 02 PasswordAuthentication no 03 PubkeyAuthentication yes 04 ed25519 keys only 05 MaxAuthTries 3 06 LoginGraceTime 30s 07 AllowUsers strict 08 Banner /etc/issue.net 09 LogLevel VERBOSE 10 X11Forwarding no 11 ClientAliveInterval 300 12 fail2ban + 5/10min 13 Match-blocks per group 14 Port hidden by FW 15 Centralized log → Wazuh 16 ChrootDirectory SFTP 17 ForceCommand internal-sftp 18 ProxyJump bastion 19 sshd -T audit 20 ssh-audit verify 21 Quarterly key rotation 22 No agent-forward home 23 2FA via TOTP 24 Strong KexAlgorithms 25 known_hosts pinning
25 точек безопасности SSH: от ключа ed25519 до квартальной ротации
· 19 мин чтения · Семёнов Е.С., руководитель ITfresh

25 правил SSH, которые ITfresh применяет у каждого клиента — стандарт 2026

К нам обратилась бухгалтерская фирма из ЦАО на 22 рабочих места — после новостей про взлом одного известного провайдера директор задался вопросом, насколько безопасны их собственные серверы. Мы провели аудит и нашли 14 нарушений из нашего внутреннего чек-листа SSH. Ниже — этот чек-лист целиком: 25 правил, которые мы применяем у каждого клиента, начиная с первой настройки сервера. С реальными командами, конфигом sshd_config и тем, что обычно ломается, когда правила применяют не понимая зачем.

Зачем вообще нужен жёсткий стандарт SSH

SSH — это входная дверь сервера. Если она открыта или сделана из картона, можно ставить любой firewall, любые антивирусы, любой WAF — толку не будет. По нашей статистике, 6 из 10 серверов малых компаний, на которые мы заходим в первый раз, имеют как минимум одно из двух нарушений: разрешён логин root по паролю или PasswordAuthentication = yes. Этого хватает, чтобы за 2-3 недели в логах накопилось от 100 000 до 5 миллионов попыток брутфорса от ботов из всех уголков планеты.

Хорошая новость — приведение SSH в порядок занимает у инженера 1-2 часа на сервер. Плохая новость — без чек-листа что-то всегда забывается. Поэтому ниже — наш формализованный список из 25 пунктов, разделённый на 4 группы: ключи и аутентификация, конфиг sshd, сетевая часть, аудит и эксплуатация.

Группа A: ключи и аутентификация (правила 1-7)

Правило 1. Только ed25519, никаких RSA-1024 и DSA

В 2026 году единственный нормальный алгоритм для SSH-ключей — ed25519. Он быстрый, короткий, без бэкдоров. Команда генерации:

ssh-keygen -t ed25519 -C "semenov@itfresh-ws01-2026q2" -f ~/.ssh/id_ed25519
# Обязательно с парольной фразой!
# При вопросе passphrase — вводим длинный пароль из менеджера паролей

RSA-2048 ещё допустим в ситуации совместимости со старым железом (Cisco IOS до 15-й версии, очень древние кастомные SSH-серверы). RSA-1024 и DSA должны быть удалены отовсюду — они формально и фактически взломаны.

Правило 2. PasswordAuthentication no

Никакой аутентификации по паролю. Никаких исключений. В sshd_config:

PasswordAuthentication no
ChallengeResponseAuthentication no
KbdInteractiveAuthentication no
PermitEmptyPasswords no

Если пользователь забыл загрузить ключ перед поездкой в командировку — это его проблема, а не повод открывать пароль. На случай таких ситуаций у нас есть break-glass-процедура — об этом в правиле 7.

Правило 3. PermitRootLogin no

Никакого логина под root. Все инженеры заходят под именными учётками и эскалируются через sudo. Это позволяет в auth.log видеть, кто конкретно что делал.

PermitRootLogin no

Правило 4. AllowUsers и AllowGroups — белый список

Не «всем кроме», а «только этим». В конфиге явно перечисляем разрешённые учётки или группы:

AllowGroups ssh-users itfresh-engineers
# Альтернатива:
AllowUsers semenov ivanov ansible deploy

Если пользователь не в этом списке — даже с правильным ключом он не зайдёт. Защищает от ситуации, когда осталась забытая учётка с непонятным ключом.

Правило 5. Парольная фраза на каждом приватном ключе

Приватный ключ без парольной фразы — это пароль, лежащий в открытом виде. Если ноутбук украдут — сразу станут админом всех серверов. Поэтому каждый ключ — с длинной парольной фразой из менеджера паролей. Чтобы не вводить её каждый раз, используем ssh-agent или 1Password CLI:

# macOS / Linux
eval $(ssh-agent)
ssh-add ~/.ssh/id_ed25519

# Windows 11 — встроенный OpenSSH agent
Set-Service -Name ssh-agent -StartupType Automatic
Start-Service ssh-agent
ssh-add $env:USERPROFILE\.ssh\id_ed25519

Правило 6. Один ключ — одна цель

У каждого инженера ITfresh не один общий ключ, а отдельные ключи под класс задач: один для административных серверов клиентов, другой для собственных production-сервисов, третий для GitHub. Это позволяет в случае компрометации одного ключа изолированно сменить его и не паниковать на всю инфраструктуру.

# ~/.ssh/config
Host clients-*
    IdentityFile ~/.ssh/id_ed25519_clients
    IdentitiesOnly yes

Host github.com
    IdentityFile ~/.ssh/id_ed25519_github
    IdentitiesOnly yes

Host production-*
    IdentityFile ~/.ssh/id_ed25519_prod
    IdentitiesOnly yes

Правило 7. Break-glass-учётка с физическим хранением ключа

Одна учётка break-glass с длинным паролем, ключ к которой лежит на USB-токене в сейфе у директора заказчика. Логин разрешён только с консоли (через VPN или через iLO/iDRAC). Используется в ситуациях, когда отвалилось всё остальное.

Группа B: конфигурация sshd (правила 8-15)

Правило 8. MaxAuthTries 3 и LoginGraceTime 30s

Не давать боту бесконечно перебирать ключи и паузой не давать висеть полу-открытым соединениям:

MaxAuthTries 3
MaxStartups 10:30:60
LoginGraceTime 30
ClientAliveInterval 300
ClientAliveCountMax 2

MaxStartups 10:30:60 — после 10 одновременных не аутентифицированных попыток новые соединения отбрасываются с вероятностью 30%, после 60 — все. Это защита от DoS.

Правило 9. LogLevel VERBOSE

Дефолтный INFO мало что показывает. VERBOSE логирует попытки аутентификации с указанием fingerprint ключа — это критично для расследования инцидента:

LogLevel VERBOSE
SyslogFacility AUTH

Правило 10. Match-блоки для разных групп пользователей

Не все пользователи равны. Разработчику нужен полный shell, бухгалтеру — только SFTP к конкретной папке, бэкап-скрипту — только rsync. Match-блоки решают это элегантно:

Match Group sftp-only
    ChrootDirectory %h
    ForceCommand internal-sftp -l VERBOSE
    AllowTcpForwarding no
    X11Forwarding no
    PermitTunnel no

Match Group backup-only
    ForceCommand /usr/local/bin/rrsync -ro /backup/source
    AllowTcpForwarding no
    X11Forwarding no

Match User semenov,ivanov
    PermitTTY yes
    AllowAgentForwarding yes

Правило 11. Запрет X11/TCP-форвардинга по умолчанию

Если не нужен X11 — отключаем глобально. Если нужен туннелированный доступ к внутренним сервисам — разрешаем точечно через Match-блок:

X11Forwarding no
AllowTcpForwarding no
GatewayPorts no
PermitTunnel no
AllowAgentForwarding no

Правило 12. Современные KexAlgorithms, Ciphers, MACs

Старые алгоритмы шифрования и обмена ключами нужно явно отключать. В 2026 году актуальный набор:

KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org,sntrup761x25519-sha512@openssh.com,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes128-ctr
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com
HostKeyAlgorithms ssh-ed25519,ssh-ed25519-cert-v01@openssh.com,rsa-sha2-512,rsa-sha2-256
PubkeyAcceptedAlgorithms ssh-ed25519,ssh-ed25519-cert-v01@openssh.com,rsa-sha2-512,rsa-sha2-256

Проверяем результат через ssh-audit (об этом в правиле 19).

Правило 13. Только ed25519 и rsa-2048+ host keys

Удаляем дефолтные ключи DSA и ECDSA, оставляем только ed25519 и RSA:

cd /etc/ssh
rm -f ssh_host_dsa_key* ssh_host_ecdsa_key*
ssh-keygen -t ed25519 -f ssh_host_ed25519_key -N "" < /dev/null
ssh-keygen -t rsa -b 4096 -f ssh_host_rsa_key -N "" < /dev/null

# В sshd_config
HostKey /etc/ssh/ssh_host_ed25519_key
HostKey /etc/ssh/ssh_host_rsa_key
# DSA и ECDSA hostkey-строки убираем

Правило 14. Banner и legal-предупреждение

Не для красоты, а для юридической чистоты. Если потом будет инцидент с попыткой несанкционированного доступа, banner — это юридическое уведомление о том, что система частная и попытки попасть на неё являются нарушением:

# /etc/issue.net
*****************************************************************
   ВНИМАНИЕ! Это закрытая система ITfresh.
   Доступ только для авторизованных лиц.
   Все действия логируются и могут быть переданы
   в правоохранительные органы.
*****************************************************************

# В sshd_config
Banner /etc/issue.net

Правило 15. UseDNS no и StrictModes yes

UseDNS no                 # быстрее логин, нет зависимости от DNS
StrictModes yes           # проверка прав на authorized_keys
PermitUserEnvironment no  # запрет на ~/.ssh/environment
AcceptEnv LANG LC_*       # только нужные переменные среды

Группа C: сеть и обвязка (правила 16-21)

Правило 16. fail2ban с агрессивными правилами

fail2ban — необязательный, но полезный плюс к ключевой аутентификации. Конкретно для SSH:

# /etc/fail2ban/jail.d/sshd.local
[sshd]
enabled = true
port = 22
filter = sshd
logpath = /var/log/auth.log
backend = systemd
maxretry = 3
findtime = 600
bantime = 86400
bantime.increment = true
bantime.factor = 2
bantime.maxtime = 1209600
ignoreip = 127.0.0.1/8 10.0.0.0/8 192.168.0.0/16

Параметр bantime.increment двойной: первая блокировка — 24 часа, вторая для того же IP — 48 часов, потом 96 и так до максимума 14 дней. Это эффективно «выжигает» спамеров из логов.

Правило 17. Бастион-хост и ProxyJump

Серверы продакшена не торчат напрямую в интернет — они доступны только через jump-host (бастион). На стороне клиента в ~/.ssh/config:

Host bastion
    HostName bastion.client.ru
    User semenov
    IdentityFile ~/.ssh/id_ed25519_clients
    IdentitiesOnly yes

Host prod-*
    User semenov
    IdentityFile ~/.ssh/id_ed25519_clients
    IdentitiesOnly yes
    ProxyJump bastion

Команда ssh prod-app01 подключается через бастион автоматически. На бастионе нет производственных данных — только логи всех проходов.

Правило 18. Файрвол с белым списком IP

На клиентском сервере SSH открыт только для:

ufw default deny incoming
ufw allow from 10.20.0.0/16 to any port 22
ufw allow from 91.218.245.10 to any port 22  # ITfresh VPN exit
ufw allow from 91.218.245.11 to any port 22  # ITfresh standby
ufw enable

Правило 19. Регулярный аудит через ssh-audit

Раз в квартал я гоняю по всем клиентским серверам утилиту ssh-audit:

pip install ssh-audit
ssh-audit prod.client.ru -p 22

# Ожидаемый результат: общая оценка A или A+
# Если ниже B — есть критические замечания, чинить

Утилита проверяет криптографические настройки и сравнивает с актуальной базой уязвимостей. Очень полезна, потому что иногда мы упускаем смену алгоритма и без неё узнали бы только из новостей.

Правило 20. Квартальная ротация ключей пользователей

Раз в три месяца каждый инженер ITfresh перевыпускает свой клиентский ключ и обновляет authorized_keys на всех серверах через Ansible. Это длинный процесс, но он гарантирует, что даже если ключ незаметно скомпрометирован — он не работает дольше 3 месяцев.

Правило 21. Pin known_hosts на всех клиентских машинах

HashKnownHosts yes — это защита от случайного раскрытия списка серверов, к которым ходит инженер. Плюс не игнорировать предупреждения «host key changed» — это либо MITM, либо переустановка сервера, и в любом случае требует разбора:

# ~/.ssh/config
Host *
    HashKnownHosts yes
    StrictHostKeyChecking ask
    VerifyHostKeyDNS no

Группа D: аудит и эксплуатация (правила 22-25)

Правило 22. Централизованный auth.log в Wazuh/Graylog

На каждом сервере rsyslog шлёт auth.log в наш центральный SIEM (Wazuh для большинства клиентов, Graylog для крупных). Там настроены правила:

cat > /etc/rsyslog.d/50-auth-to-wazuh.conf <<EOF
auth.*  @@10.20.99.5:514
EOF
systemctl restart rsyslog

Правило 23. 2FA через TOTP для критичных серверов

На бастион-хосте и серверах с боевой бухгалтерией дополнительно к ключу — TOTP-код через Google Authenticator или Aegis. Pluggable модуль libpam-google-authenticator:

apt install libpam-google-authenticator

# В /etc/pam.d/sshd
auth required pam_google_authenticator.so

# В /etc/ssh/sshd_config
ChallengeResponseAuthentication yes
AuthenticationMethods publickey,keyboard-interactive

# Для каждого пользователя — настройка
google-authenticator -t -d -f -r 3 -R 30 -W

Получается: ключ + код из приложения. Брутфорсить такой стек практически бесполезно.

Правило 24. Sudo с записью команд через io-log

Сам по себе sudo пишет в auth.log только факт «вызвал sudo с командой X». Реальный shell-сеанс под sudo -i не пишется. Чтобы записать абсолютно всё, что делал инженер с правами root — включаем sudo io-log:

# /etc/sudoers.d/log-everything
Defaults log_input, log_output
Defaults iolog_dir=/var/log/sudo-io
Defaults iolog_user=root:root
Defaults iolog_group=root

Логи бьются по сессиям, потом проигрываются через sudoreplay. Бывает критично при разборе инцидента «кто удалил production-таблицу в 14:32».

Правило 25. Регулярная проверка sshd -T в CI

Финальное правило — автоматизация. Раз в день Ansible идёт по всем клиентским серверам и собирает sshd -T (выдача актуального состояния конфига), сравнивает с эталоном. Если что-то отличается — алерт.

# Снимок конфига
ssh prod-app01 "sudo sshd -T" | sort > /tmp/actual.txt
diff /opt/itfresh/baseline/sshd-prod-app01.txt /tmp/actual.txt

# Отрабатывает в Ansible через checksum-модуль
- name: Validate sshd live config
  command: sshd -T
  register: live_sshd
- assert:
    that:
      - "'permitrootlogin no' in live_sshd.stdout|lower"
      - "'passwordauthentication no' in live_sshd.stdout|lower"
      - "'pubkeyauthentication yes' in live_sshd.stdout|lower"

Полный sshd_config «по уму»

Чтобы не собирать конфиг по кусочкам, вот наш референсный sshd_config 2026 года для клиентских Ubuntu/Debian-серверов:

# /etc/ssh/sshd_config — ITfresh standard 2026
Port 22
AddressFamily inet
ListenAddress 0.0.0.0

HostKey /etc/ssh/ssh_host_ed25519_key
HostKey /etc/ssh/ssh_host_rsa_key

# Crypto
KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org,sntrup761x25519-sha512@openssh.com,diffie-hellman-group16-sha512
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com
HostKeyAlgorithms ssh-ed25519,rsa-sha2-512,rsa-sha2-256
PubkeyAcceptedAlgorithms ssh-ed25519,rsa-sha2-512,rsa-sha2-256

# Auth
PermitRootLogin no
PubkeyAuthentication yes
PasswordAuthentication no
ChallengeResponseAuthentication no
KbdInteractiveAuthentication no
PermitEmptyPasswords no
MaxAuthTries 3
MaxSessions 5
MaxStartups 10:30:60
LoginGraceTime 30
AuthorizedKeysFile .ssh/authorized_keys
AuthenticationMethods publickey

# Allow lists
AllowGroups itfresh-engineers app-deploy sftp-only

# Behaviour
AllowTcpForwarding no
X11Forwarding no
PermitTunnel no
AllowAgentForwarding no
GatewayPorts no
PrintLastLog yes
TCPKeepAlive no
ClientAliveInterval 300
ClientAliveCountMax 2
UseDNS no
StrictModes yes
PermitUserEnvironment no
AcceptEnv LANG LC_*
Subsystem sftp internal-sftp

# Logging
LogLevel VERBOSE
SyslogFacility AUTH

# Banner
Banner /etc/issue.net

# Match blocks
Match Group sftp-only
    ChrootDirectory %h
    ForceCommand internal-sftp -l VERBOSE
    AllowTcpForwarding no
    X11Forwarding no

Match Group itfresh-engineers
    AllowAgentForwarding yes
    AllowTcpForwarding yes

Контр-нарратив: где SSH-харденинг — это перебор

Скажу непопулярное. Если у вас один dev-сервер для разработчика, на котором крутится тестовый WordPress — городить TOTP, бастион-хост и SIEM с алертами на изменение sshd_config бессмысленно. Главное на dev-сервере — отключить пароль и разрешить только ключи. Всё остальное добавляет операционных накладных и ничего не приносит, потому что сервер а) неинтересен злоумышленнику, б) если зайдёт — переразвернётся за 20 минут из git.

Реально жёсткие меры (пункты 22-25) нужны там, где компрометация SSH означает потерю боевых данных или денежные потери. Серверы с базой 1С, серверы с эквайрингом, серверы с медицинскими данными — да. Тестовая VM для разработчика — нет.

FAQ: что чаще всего спрашивают клиенты

Реально ли менять стандартный порт SSH с 22 на нестандартный?

Это вопрос религиозных войн. Я ставлю на 22 и закрываю всё через файрвол + ключи + fail2ban. Перенос на 2222 даёт минус 99% автоматических ботов в логах, но не повышает безопасность по существу — целевой атакующий просканирует все порты за 30 секунд через nmap. Для клиентских серверов с публичным IP мы переносим на нестандартный порт ради тишины в логах, не ради безопасности.

Можно ли разрешить вход root по SSH, если ключ длинный?

Нет. PermitRootLogin no — это не про длину ключа, а про разделение ответственности. На сервере должна быть учётка инженера (например semenov), которая через sudo получает права root по запросу — с записью в auth.log. Если 10 инженеров заходят под одной root-учёткой, никто не отвечает за конкретное действие. Регламент security audit для любой нормальной компании требует именно так.

Какой ключ выбрать — RSA 4096, ECDSA или ed25519?

Только ed25519, если у вас нет жёстких требований совместимости с допотопными системами. RSA 4096 — медленный и большой по размеру, ECDSA — на NIST-кривых, к которым у части аудиторов есть исторические претензии. Ed25519 — современный, быстрый, маленький, открытая криптография без бэкдоров. Все наши клиентские серверы 2024-2026 годов — на ed25519.

Что делать, если не работает SSH-агент-форвардинг через jump-host?

Использовать ProxyJump в ~/.ssh/config вместо ForwardAgent, который небезопасен и часто ломается на промежуточных хостах. ProxyJump устанавливает прозрачный туннель: ssh client подключается к jump-host, через него к target — и аутентификация идёт ключом локального компьютера, а не ключом, переданным через цепочку. Это и безопаснее, и стабильнее.

Сколько стоит у ITfresh аудит SSH-настроек серверов?

Для парка 5-15 серверов — 25-40 тысяч рублей за 1-2 дня инженера: проверка sshd_config по 25 пунктам, аудит ~/.ssh/authorized_keys на каждом сервере, проверка fail2ban, настройка централизованного auth.log в Wazuh/Graylog, выдача отчёта с приоритезированными уязвимостями. Если параллельно делаем харденинг — это ещё 1-2 дня, итого 50-80 тысяч.

Итог

SSH — не место для творчества. 25 правил выше — это выкристаллизованный за 15 лет работы стандарт, который мы применяем у каждого клиента. Бухгалтерская фирма из ЦАО за 1 рабочий день инженера получила 14 закрытых уязвимостей и снижение количества попыток брутфорса в логах с 18 000 в сутки до 30. Если вам нужен такой же аудит — напишите, пришлю чек-лист и оценку работ.

Похожая задача в вашей компании?

Расскажите, что у вас сейчас — пришлю план работ и оценку в течение рабочего дня.

Написать в Telegram  или  +7 903 729-62-41

Семёнов Е.С., руководитель ITfresh