Использование ProxyJump и VPN при SSH: настройка безопасного доступа через bastion-хост

Подробное руководство по использованию ProxyJump и VPN при SSH: настройка bastion-хоста, конфигурация клиента, ограничения доступа, журналирование и сравнение с альтернативами.

Зачем нужен bastion-хост и как он связан с VPN

В современной инфраструктуре SSH остаётся основным протоколом для управления серверами. Когда серверов становится много, а сеть делится на публичные и приватные сегменты, возникает необходимость в единой точке входа. Bastion-хост (или jump server) — это выделенный сервер-посредник, через который проходят все административные SSH-сессии к внутренним узлам. Он минималистичен, жёстко укреплён и тщательно логируется.

VPN и bastion-хост решают схожие задачи, но по-разному. VPN создаёт зашифрованный туннель между вашим устройством и сетью, позволяя обращаться к внутренним ресурсам напрямую. Bastion-хост, напротив, остаётся единственной точкой входа, через которую идут все SSH-подключения. На практике эти подходы часто комбинируют: VPN защищает доступ к самому bastion, а bastion управляет доступом к внутренним серверам.

Основные преимущества bastion-хоста: сокращение площади атаки (в интернет открыт только один порт), единая точка применения политик безопасности, централизованное журналирование и упрощённое подключение разработчиков через ProxyJump — встроенную функцию OpenSSH.

Что такое ProxyJump и чем он отличается от ProxyCommand

ProxyJump — это опция OpenSSH, появившаяся в версии 7.3. Она позволяет установить SSH-соединение с целевым сервером через промежуточный хост (bastion) одной командой. Синтаксис прост: ssh -J . Если нужно указать разных пользователей и порты, используйте формат ssh -J user@jump-host:port user@remote-target:port.

ProxyCommand — более старая и гибкая альтернатива. Она работает путём перенаправления стандартного ввода и вывода через промежуточный сервер. Типичная команда выглядит так: ssh -o ProxyCommand="ssh -W %h:%p " . Ключ -W перенаправляет stdin/stdout на удалённый хост (%h) и порт (%p).

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

Настройка клиента SSH для работы через ProxyJump

Чтобы не вводить длинные команды каждый раз, настройте файл ~/.ssh/config. Вот пример конфигурации для одного bastion-хоста:

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

Теперь для подключения к серверу app01.internal достаточно выполнить ssh app01.internal. SSH-клиент автоматически установит соединение через bastion. Аутентификация при этом происходит один раз — на целевом сервере, если ключи настроены правильно.

Для ускорения повторных подключений можно включить мультиплексирование соединений. Добавьте в секцию Host bastion параметры ControlMaster auto, ControlPersist 5m и ControlPath ~/.ssh/controlmasters/%r@%h:%p. Это позволит переиспользовать уже установленное соединение, что особенно полезно при работе с множеством хостов.

Безопасная настройка bastion-хоста: базовые параметры sshd

Bastion-хост должен быть максимально укреплён. Начните с редактирования /etc/ssh/sshd_config. Рекомендуемый минимальный набор параметров:

Port 22
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
AuthenticationMethods publickey
AllowGroups bastion-ssh
MaxAuthTries 3
LoginGraceTime 30
ClientAliveInterval 60
ClientAliveCountMax 3
X11Forwarding no
AllowAgentForwarding no
AllowTcpForwarding no
PermitTunnel no
GatewayPorts no
LogLevel VERBOSE
SyslogFacility AUTHPRIV

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

Если требуется двухфакторная аутентификация, измените строку AuthenticationMethods на publickey,keyboard-interactive и настройте PAM-модуль для TOTP. Важно применять 2FA ко всем административным аккаунтам, а не выборочно.

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

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

На каждом внутреннем сервере настройте файрвол так, чтобы разрешить TCP-порт 22 только с IP-адреса bastion. Например, в nftables:

table inet filter {
    chain input {
        type filter hook input priority 0;
        ct state established,related accept
        iif lo accept
        ip saddr 192.168.10.5 tcp dport 22 accept
        tcp dport 22 drop
    }
}

В sshd_config целевого сервера добавьте AllowUsers admin@192.168.10.5 или используйте секцию Match Address для дополнительной страховки. Также можно ограничить возможности ключей в authorized_keys с помощью опций from="192.168.10.5", no-port-forwarding, no-agent-forwarding, no-pty.

Если требуется разрешить локальные туннели, используйте AllowTcpForwarding local и PermitOpen 127.0.0.1:5432, чтобы ограничить доступ только к конкретным портам.

Защита от перебора и файрвол на bastion

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
    }
}

Дополнительно установите Fail2ban с настройками под ваши журналы. Пример конфигурации /etc/fail2ban/jail.d/sshd.local:

[sshd]
enabled = true
port = 22
filter = sshd
backend = systemd
maxretry = 5
findtime = 10m
bantime = 1h

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

Журналирование и аудит SSH-сессий

Цель журналирования — видеть, кто, когда и откуда подключался, к какому узлу и чем это закончилось. Включите LogLevel VERBOSE и SyslogFacility AUTHPRIV на bastion и внутренних хостах. Это добавит в журнал отпечатки ключей и попытки входа.

Для централизованного сбора логов настройте отправку журналов на отдельный сервер, недоступный пользователям, которые администрируют целевые машины. Это можно сделать через syslog или systemd-journald. Например, в /etc/rsyslog.d/ssh.conf:

authpriv.* @logserver.example.com:514

Для аудита команд, выполняемых пользователями, можно использовать модуль pam_tty_audit или записывать сессии с помощью script и scriptreplay. Teleport, альтернативный SSH-сервер, предоставляет встроенную запись и воспроизведение сессий, что упрощает аудит.

SSH-сертификаты как альтернатива управлению ключами

Если пользователей и ключей много, управление authorized_keys становится сложным. SSH-сертификаты OpenSSH решают эту проблему. Модель проста: у вас есть ключ центра сертификации (CA), которым подписываются пользовательские ключи с коротким сроком действия и атрибутами (principals).

На серверах достаточно добавить публичный ключ CA в TrustedUserCAKeys /etc/ssh/ca.pub. После этого не нужно разворачивать authorized_keys по всем хостам — доступ контролируется сроками сертификатов и списком principals.

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

Teleport как альтернатива классическому bastion

Teleport — это SSH-сервер с открытым исходным кодом, выпущенный в 2016 году. Он ориентирован на работу с кластерами и большим количеством узлов. В отличие от традиционного SSH, Teleport использует сертификаты вместо ключей, что упрощает управление доступом.

Teleport предлагает веб-интерфейс для подключения к SSH через браузер, автоматическое обнаружение серверов, запись и воспроизведение сессий, а также поддержку других протоколов (Kubernetes, HTTP). Он не полагается на пользователей Linux для аутентификации, а интегрируется с внешними провайдерами (GitHub, Okta, Active Directory).

Выбор между OpenSSH и Teleport зависит от масштаба. Для небольших команд и быстрой настройки подойдёт OpenSSH. Если парк серверов растёт и нужны расширенные функции аудита, Teleport — лучший выбор.

Практические примеры и типичные ошибки

Рассмотрим несколько практических сценариев. Для копирования файлов через bastion используйте scp -o ProxyJump=bastion backup.sql admin@app01.internal:/srv/backups/. Для SFTP: sftp -o ProxyJump=bastion admin@app01.internal.

Типичные ошибки:

  • Забывают ограничить доступ на целевых серверах, оставляя SSH открытым из интернета.
  • Используют пароли вместо ключей, что увеличивает риск перебора.
  • Не включают LogLevel VERBOSE, из-за чего журналы не содержат отпечатков ключей.
  • Разрешают агент-форвардинг без необходимости, что может привести к компрометации ключей.
  • Не проверяют синтаксис sshd_config перед перезагрузкой службы.

Чтобы избежать ошибок, всегда тестируйте конфигурацию с помощью sshd -t и проверяйте доступность с разных клиентов.

Вопросы и ответы

В чём разница между ProxyJump и ProxyCommand?

ProxyJump — это современная опция OpenSSH (начиная с версии 7.3), которая позволяет подключиться к целевому серверу через промежуточный хост одной командой ssh -J. ProxyCommand — более старая и гибкая техника, использующая перенаправление stdin/stdout через -W %h:%p. ProxyJump проще в использовании и лучше интегрируется с ~/.ssh/config, но ProxyCommand может быть полезен в нестандартных сценариях, например, при необходимости использовать дополнительные опции или цепочки хостов.

Нужен ли VPN, если уже есть bastion-хост?

VPN и bastion-хост решают разные задачи. VPN создаёт зашифрованный туннель до сети, позволяя обращаться к внутренним ресурсам напрямую. Bastion-хост — это единая точка входа для SSH-подключений. Их можно комбинировать: VPN защищает доступ к самому bastion, а bastion управляет доступом к внутренним серверам. Если у вас уже есть bastion, VPN может быть избыточен, но он добавляет дополнительный уровень безопасности и удобства для других протоколов.

Как настроить ProxyJump в ~/.ssh/config?

Добавьте в файл ~/.ssh/config секции для bastion и целевых хостов. Например:

Host bastion
    HostName bastion.internal
    User admin
    IdentityFile ~/.ssh/id_ed25519

Host *.internal
    User admin
    ProxyJump bastion

После этого подключение к app01.internal автоматически пойдёт через bastion. Убедитесь, что ключи настроены на обоих серверах.

Какие параметры sshd_config обязательны для bastion-хоста?

Обязательные параметры: PermitRootLogin no, PasswordAuthentication no, PubkeyAuthentication yes, AllowGroups bastion-ssh (или аналогичное ограничение), LogLevel VERBOSE, X11Forwarding no, AllowAgentForwarding no, AllowTcpForwarding no. Эти настройки отключают пароли, запрещают root-вход и лишние форвардинги, а также улучшают журналирование.

Как защитить bastion-хост от перебора паролей?

Используйте только ключевую аутентификацию (отключите пароли), настройте файрвол с ограничением частоты соединений (например, через nftables) и установите Fail2ban. Пример правила nftables: tcp dport 22 ct state new limit rate 30/minute accept. Fail2ban банит IP после нескольких неудачных попыток.

Что такое SSH-сертификаты и когда их использовать?

SSH-сертификаты — это способ подписи пользовательских ключей центральным CA. Они позволяют не разворачивать authorized_keys на каждом сервере, а контролировать доступ через срок действия и principals. Используйте их, когда пользователей и серверов много, чтобы упростить управление доступом и ускорить отзыв ключей.

Можно ли использовать ProxyJump для scp и sftp?

Да, ProxyJump работает и для scp, и для sftp. Пример для scp: scp -o ProxyJump=bastion backup.sql admin@app01.internal:/srv/backups/. Для sftp: sftp -o ProxyJump=bastion admin@app01.internal. Это удобно, когда нужно передавать файлы на внутренние серверы через bastion.