ZIM-НИЙ SAAALEЗимние скидки: до −50% на старт и −20% на продление
до 31.01.2026 Подробнее
Выберите продукт

Bastion‑хост для SSH: ProxyJump, ограничения доступа и журналирование

Разбираем, как построить надежный bastion‑хост для SSH: схема доступа, строгие политики на серверах, ProxyJump для удобства, защита ключей, запрет паролей, Fail2ban и централизованное журналирование с аудитом сессий.
Bastion‑хост для SSH: ProxyJump, ограничения доступа и журналирование

В современном периметре инфраструктуры SSH остаётся основным управленческим протоколом. Но когда серверов становится много, а сеть делится на публичные и приватные сегменты, необходим единый входной пункт — bastion‑хост. Через него администраторы и DevOps попадают в внутренние хосты, а безопасность и журналирование сосредоточены в одном месте. В этой статье соберём практический чеклист: настройка ProxyJump, ограничения доступа на целевых серверах, повышение уровня безопасности и работающие варианты журналирования.

Что такое bastion‑хост и зачем он нужен

Bastion — это выделенный сервер-посредник, через который проходят все административные SSH‑сессии к внутренним узлам. Он минималистичен, жёстко укреплён и тщательно логируется. Чаще всего его разворачивают на отдельном VDS в облаке или у провайдера. Такой подход даёт несколько преимуществ: сокращение площади атаки, единая точка применения политик, централизованное журналирование, упрощённое подключение разработчиков через ProxyJump (встроенная функция OpenSSH).

Типовой сценарий: в интернет открыт только SSH на bastion, а целевые серверы доступны по SSH исключительно с адреса bastion (фильтрация брандмауэром). Администратор подключается к bastion, а затем прыжком — к нужному внутреннему хосту. С точки зрения управления доступами легче отозвать ключ, отследить событие в журналах и быстро отключить компрометированный аккаунт.

Идеальный bastion — «скучный»: минимум пакетов, консольный вход только по ключам, запрет паролей, нулевые лишние сервисы и чёткие политики SSH. Всё, что не нужно для администрирования, удаляется.

Сетевой периметр и модель доступа

Сетевую схему лучше продумать заранее. Bastion имеет один публичный интерфейс для входа администраторов и один приватный интерфейс (или маршрутизацию) до внутренних подсетей. На внешнем периметре открыт только порт SSH. На внутренних хостах — SSH доступен только с приватного адреса bastion. Если используется IPv6, правила применяются и к v6‑подсетям, чтобы не оставить «дыры».

  • На границе: разрешить входящие TCP‑22 к bastion, при необходимости ограничить по allow‑list офисных подсетей или VPN.
  • На внутренних серверах: разрешить TCP‑22 только от приватного IP bastion.
  • На самом bastion запретить исходящие, кроме TCP‑22 в приватную сеть (и системных обновлений, если не используете локальный репозиторий).

DNS нужен управляемый: именуйте внутренние хосты предсказуемо, чтобы ProxyJump конфигурации были компактны и не привязывались к устаревшим адресам.

FastFox VDS
Облачный VDS-сервер в России
Аренда виртуальных серверов с моментальным развертыванием инфраструктуры от 195₽ / мес

Политики учётных записей и ключей

Основы безопасности просты и непреклонны. Используйте только ключевую аутентификацию (Ed25519 или ECDSA), запрещайте пароли, отключайте root вход, а привилегии поднимайте через sudo с журналированием I/O. Ключи — персональные, без общих «на всех»; у каждого сотрудника — свой ключ и своя запись в authorized_keys или централизованная выдача через SSH‑сертификаты.

  • Ротация ключей: планируйте регулярную смену, храните ключи с passphrase, защищайте агента, не включайте агент‑форвардинг без необходимости.
  • Принципы наименьших прав: доступ только к нужным серверам и только с тех аккаунтов, что соответствуют роли.
  • Отзыв доступа: процесс удаления ключа и учётной записи должен быть быстрым и документированным.

Подключение по SSH через ProxyJump: клиент — bastion — внутренние серверы

Базовая настройка SSH на bastion

Ниже — стартовый набор параметров /etc/ssh/sshd_config, от которого можно плясать. Он выключает пароли, корневой вход, форвардинги и повышает детализацию журналов. Не забывайте перезагружать службу и проверять синтаксис.

Port 22
AddressFamily any
ListenAddress 0.0.0.0
ListenAddress ::
Protocol 2
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
ChallengeResponseAuthentication no
PubkeyAuthentication yes
AuthenticationMethods publickey
UsePAM yes
AllowGroups bastion-ssh
MaxAuthTries 3
LoginGraceTime 30
ClientAliveInterval 60
ClientAliveCountMax 3
X11Forwarding no
AllowAgentForwarding no
AllowTcpForwarding no
PermitTunnel no
GatewayPorts no
PermitUserEnvironment no
LogLevel VERBOSE
SyslogFacility AUTHPRIV
Banner /etc/issue.net
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com
HostKeyAlgorithms ssh-ed25519,ecdsa-sha2-nistp256

Группа bastion-ssh упрощает контроль доступа: в неё включаем только тех, кому разрешён вход. Фича LogLevel VERBOSE заставляет sshd писать в журнал отпечатки публичных ключей и дополнительные события, полезные для расследований.

Если нужна двухфакторная аутентификация (TOTP), можно включить схему publickey + keyboard-interactive, а в PAM добавить модуль одноразовых кодов. В этом случае в sshd_config меняем строку:

AuthenticationMethods publickey,keyboard-interactive

Дальше настройка модулей в /etc/pam.d/sshd (конкретные параметры зависят от выбранного PAM‑модуля). Важно: двухфакторную проверку включайте как требование ко всем административным аккаунтам, а не выборочно.

Файрвол и защита от перебора

На bastion включите агрессивную фильтрацию соединений и ограничение скорости. Если используете nftables, минимальный набор выглядит так:

table inet filter {
  chain input {
    type filter hook input priority 0;
    ct state established,related accept
    iif lo accept
    tcp dport 22 ct state new limit rate 30/minute accept
    tcp dport 22 drop
    counter reject with icmpx type admin-prohibited
  }
}

Добавьте Fail2ban с тюнингом под Ваши журналы, чтобы банить повторные неуспешные попытки аутентификации.

# /etc/fail2ban/jail.d/sshd.local
[sshd]
enabled = true
port = 22
filter = sshd
backend = systemd
maxretry = 5
findtime = 10m
bantime = 1h

ProxyJump на стороне клиента

ProxyJump — современная альтернатива ProxyCommand. С ней не нужно прописывать цепочки nc или сложных команд. Одноразовый заход выглядит так:

ssh -J admin@bastion.internal admin@app01.internal

Чтобы не повторяться, опишите шаблон в ~/.ssh/config:

Host bastion
  HostName bastion.internal
  User admin
  IdentityFile ~/.ssh/id_ed25519
  ForwardAgent no
  ServerAliveInterval 30
  ServerAliveCountMax 3

Host *.internal
  User admin
  IdentityFile ~/.ssh/id_ed25519
  ProxyJump bastion
  StrictHostKeyChecking yes
  ForwardAgent no
  Compression yes

Файлы и SFTP тоже работают через прыжок:

scp -o ProxyJump=bastion backup.sql admin@app01.internal:/srv/backups/
sftp -o ProxyJump=bastion admin@app01.internal

Чтобы ускорить повторные сеансы, включите мультиплексирование: на «bastion» добавьте ControlMaster auto, ControlPersist 5m, ControlPath с безопасным путём в домашнем каталоге пользователя. Это сократит время обвязки, особенно при гонках по многим хостам.

Ограничения доступа на целевых серверах

Даже с bastion центральная идея — целевые хосты не принимают SSH с интернета. Ограничение реализуется на двух уровнях: брандмауэр и SSH‑конфигурация.

  • Брандмауэр: на каждом внутреннем сервере правило «разрешить TCP‑22 только от IP bastion». Остальное — дроп. Не забывайте про IPv6.
  • sshd_config: использование AllowUsers с шаблонами user@ip или секции Match Address для дополнительной страховки.
# На внутреннем сервере, /etc/ssh/sshd_config
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
AllowUsers admin@192.168.10.5
X11Forwarding no
AllowAgentForwarding no
AllowTcpForwarding local
PermitOpen 127.0.0.1:5432

Пара AllowTcpForwarding и PermitOpen позволяет избирательно разрешать локальные туннели лишь к конкретным портам на localhost, если это действительно требуется для работы. В authorized_keys можно дополнительно ограничить ключи опциями from="192.168.10.5", no-port-forwarding, no-agent-forwarding, no-pty — это даст ещё один уровень защиты на уровне конкретной записи.

SSH‑сертификаты (по желанию)

Если пользователей и ключей много, используйте SSH‑сертификаты OpenSSH. Модель простая: у вас есть офлайн‑или защищённый ключ центра (CA), которым подписываются пользовательские ключи с коротким сроком действия и атрибутами (principals). На серверах достаточно добавить публичный ключ CA в TrustedUserCAKeys, после чего не нужно разворачивать authorized_keys по всем хостам — доступ контролируется сроками сертификатов и списком principals.

# На серверах
TrustedUserCAKeys /etc/ssh/ca.pub

Преимущества: быстрый отзыв, минимизация «мусора» в authorized_keys, привязка личности, а также лучшее журналирование — в логах будут отпечатки не только ключей, но и сертификатов.

Журналирование и аудит

Цель — видеть, кто, когда и откуда подключился, к какому узлу, и чем это закончилось. В идеале — хранить логи на отдельном журнал‑сервере, недоступном пользователям, которые администрируют целевые машины. Начнём с усиления логов SSH.

Расширенные логи OpenSSH

На bastion и внутренних хостах включите LogLevel VERBOSE и SyslogFacility AUTHPRIV. Так в журнал попадут отпечатки ключей, попытки входа, начало и конец сессий, SFTP‑операции. Убедитесь, что журналы хранятся достаточно долго, а ротация настроена корректно.

# Пример фрагмента /etc/ssh/sshd_config
SyslogFacility AUTHPRIV
LogLevel VERBOSE

Централизованная отправка журналов

Собирайте логи с bastion и всех целевых хостов на отдельный узел. Простейший способ — rsyslog с TCP‑доставкой. На клиентах:

# /etc/rsyslog.d/90-remote.conf
module(load="imjournal")
action(type="omfwd" target="10.0.0.5" port="514" protocol="tcp" action.resumeRetryCount="-1")

А на журнал‑сервере — приём TCP и разложение по файлам. Для чувствительных данных используйте надстройки с подтверждением доставки и шифрованием, а также разграничивайте доступ к каталогам с AUTHPRIV.

Централизованное журналирование: потоки rsyslog с bastion и серверов на лог‑узел

Аудит команд и действий

Три уровня, которые хорошо работают вместе:

  • Логи sshd: факт входа, ключ, источник, длительность — базовый слой.
  • Sudo I/O logging: запись интерактивных действий при повышении привилегий. Это даёт воспроизводимость.
  • Auditd: события execve, изменения критичных файлов конфигурации.

Включим I/O‑журналы sudo на внутренних серверах и на bastion (если там выполняются административные команды):

# /etc/sudoers.d/iolog
Defaults use_pty
Defaults log_output
Defaults iolog_dir="/var/log/sudo-io"

Auditd пригодится для отслеживания изменений конфигураций SSH и запуска критичных утилит. Пример правил:

# /etc/audit/rules.d/ssh.rules
-w /etc/ssh/sshd_config -p wa -k sshd_cfg
-w /etc/ssh/ -p wa -k ssh_keys
-a always,exit -F arch=b64 -S execve -F auid>=1000 -F uid>=1000 -k exec_user
-a always,exit -F arch=b32 -S execve -F auid>=1000 -F uid>=1000 -k exec_user

Не перегружайте аудит: начните с ключевых артефактов и расширяйте покрытие по мере необходимости. Выделите ротацию и срок хранения отдельно от обычных системных журналов.

Практика ограничений форвардингов

Многие инциденты связаны не с прямым входом, а с боковыми каналами. По умолчанию на bastion и серверах отключайте всё, что не требуется: агент‑форвардинг (AllowAgentForwarding no), X11, туннели. Если локальные туннели нужны для работы, ограничивайте через PermitOpen конкретными целями и портами. На уровне authorized_keys это можно дублировать опциями ключа.

Если вы используете инструменты вроде Ansible, не включайте агент‑форвардинг как «на всякий случай». Лучше хранить деплой‑ключи на отдельном CI‑хосте и подключаться из него через bastion.

Тестирование и отладка

Проверьте базовые сценарии до выката в продакшн. Подключение в один прыжок, копирование файлов, SFTP, повторные попытки в режиме деградации сети. Ведение журналов: чтобы события с всех хостов доходили до централизованного узла и правильно размечались временем (синхронизируйте NTP).

  • Быстрая проверка: ssh -J bastion internal-host uptime.
  • Диагностика: ssh -v -J bastion internal-host для детального вывода.
  • Обновление ключей хоста при замене: ssh-keygen -R internal-host и повторное подключение с проверкой отпечатка.

Типичные ошибки и как их избежать

  • Открыт SSH на внутренних хостах в интернет. Решение: правила файрвола на каждом сервере + периодические сканы сегмента.
  • Разрешён парольный вход. Решение: PasswordAuthentication no, ключи с passphrase, ротация.
  • Забытый IPv6. Решение: продублировать фильтры для v6, проверить слушающие адреса.
  • Логи только локально. Решение: централизованная доставка, разграничение прав, увеличенный срок хранения критичных событий.
  • Слабые форвардинги. Решение: запрет по умолчанию, точечное разрешение через PermitOpen и опции ключей.
  • Нет процесса онбординга/оффбординга. Решение: регламент, автоматизированные чеклисты, оповещения в таск‑трекере.

Чеклист внедрения bastion‑хоста

  1. Выделить сервер под bastion (например, на VDS), минимальная ОС, обновления, только SSH.
  2. Жёстко настроить sshd_config: ключи, запрет паролей и root, LogLevel VERBOSE.
  3. Включить Fail2ban и ограничение скорости на файрволе.
  4. На внутренних хостах — разрешить SSH только с IP bastion, отключить пароли.
  5. Настроить ProxyJump в ~/.ssh/config и протестировать цепочки.
  6. Включить централизованную отправку логов и проверить доставку.
  7. Внедрить I/O‑журналы sudo и базовые правила auditd.
  8. Оформить регламент управления ключами, ротации и отзыва доступа.
  9. Периодически пересматривать политики, проводить сканы и тесты восстановления.

Итого: bastion‑хост — это не просто «ещё один сервер с SSH», а узел политики и доверия. При правильной настройке он упрощает жизнь администраторам и повышает уровень безопасности, обеспечивая контролируемый доступ, удобный ProxyJump и воспроизводимое журналирование для расследований.

Поделиться статьей

Вам будет интересно

MySQL: EXPLAIN ANALYZE и optimizer_trace — читаем план, считаем время, находим узкие места OpenAI Статья написана AI (GPT 5)

MySQL: EXPLAIN ANALYZE и optimizer_trace — читаем план, считаем время, находим узкие места

Разберём диагностику медленных запросов в MySQL 8.0 с помощью EXPLAIN ANALYZE и optimizer_trace: где найти узел, который съел врем ...
Canary-выкатка и ротация PEM Let’s Encrypt без простоя в Nginx и Apache OpenAI Статья написана AI (GPT 5)

Canary-выкатка и ротация PEM Let’s Encrypt без простоя в Nginx и Apache

Пошаговый план обновления PEM-сертификатов Let’s Encrypt без обрывов: атомарная замена через симлинки или mv, canary-выкатка на од ...
IPv6 ACL ::/0 для reverse proxy: как не открыть админку всему миру OpenAI Статья написана AI (GPT 5)

IPv6 ACL ::/0 для reverse proxy: как не открыть админку всему миру

IPv6 нередко включён по умолчанию, а доступ к админке ограничивают только для IPv4. В режиме dual stack это превращается в «дыру»: ...