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

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, мы переносим SSH на нестандартный порт только ради того, чтобы обеспечить тишину в логах, а не ради какой-то реальной безопасности.

Можно ли разрешить вход 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

Подпишитесь на рассылку ITfresh

Раз в неделю — практические гайды для руководителя IT и сисадмина: безопасность, 1С, миграции, резервные копии, лайфхаки из реальных проектов.

Реквизиты оператора персональных данных

ООО «АЙТИ-ФРЕШ», ИНН 7719418495, КПП 771901001. Юридический адрес: 105523, г. Москва, Щёлковское шоссе, д. 92, корп. 7. Контакт: info@itfresh.ru, +7 903 729-62-41. Оператор обрабатывает e-mail подписчика в целях рассылки информационных и рекламных материалов до момента отзыва согласия.