ProxyJump и bastion-хосты через ~/.ssh/config
Иногда сервер живет в приватной сети, без публичного IP. Единственная точка входа — bastion host с белым адресом. Руками набирать ssh -J user@bastion user@private каждый раз — лишняя боль. Разберу, как настроить всё через ~/.ssh/config, чтобы ходить в приватные сети в одно касание.
Зачем нужен bastion host
Bastion (jump host, jump box) — промежуточный сервер с публичным доступом, через который проксируются соединения к инфраструктуре без внешних адресов. Типичная схема:
Bastion не обязан быть «защищенным как Форт-Нокс» — он просто открытый узел. Весь access control держится на ключах и, при необходимости, на security groups / firewall.
Bastion-хост не терминальная точка — он только проксирует трафик. На нем не нужно поднимать VPN или дополнительные сервисы.
ProxyJump — современный синтаксис
-J (ProxyJump) появился в OpenSSH 7.3. Параметр принимает хост в формате [user@]host[:port] и поднимает SOCKS5-прокси через указанный узел.
Базовый вызов:
Аутентификация на обоих хостах по ключам. Если пользователь совпадает, указывать его не обязательно:
С портом, отличным от 22:
Через конфиг то же самое описывается компактно:
После этого ssh private-server подключается через bastion автоматически.
ProxyCommand — классический подход
ProxyJump — обертка над ProxyCommand. Если нужно больше контроля или работа с более старым OpenSSH, используй ProxyCommand напрямую.
-W пробрасывает stdin/stdout на целевой хост. В конфиге:
Разница с ProxyJump минимальна, но ProxyCommand позволяет подставить переменные, условия и цепочки команд.
Несколько хопов подряд
Цепочка из двух bastion-хостов:
В конфиге:
OpenSSH соединяет хосты последовательно: laptop → bastion1 → bastion2 → private-server. Проверь, что ключи есть на каждом узле.
Для сложных сценариев ProxyCommand с nc (netcat) дает больше гибкости:
Цепочка работает, но каждый хоп добавляет задержку. Для интерактивной работы больше двух хопов — признак проблемы в архитектуре сети.
Полный пример конфига
ForwardAgent yes на bastion позволяет агенту пробросить ключи дальше. Не включать, если не доверяешь bastion-машине.
LocalForward в примере пробрасывает порт PostgreSQL с приватного сервера на локальный localhost:5433. Удобно для подключения IDE или psql.
Проверить, что конфиг читается без ошибок:
Если видишь правильные значения — конфиг подхватился.
Типичные ошибки и решения
Connection timeout при ProxyJump
Проверь, что bastion доступен напрямую:
Если не проходит — проблема в сети, не в конфиге.
Permission denied (publickey) на bastion
Убедись, что ключ добавлен в ssh-agent:
Если агент пустой — добавь ключ и проверь ssh -vT bastion.
Работает в одну сторону, не работает в другую
ProxyJump туннелирует TCP. ICMP (ping) не пройдет. Проверяй соединение через nc -zv host port или ssh -v.
Agent refused operation при пробросе агента
Проверь переменную SSH_AUTH_SOCK:
Если пусто — запусти агент:
Медленное подключение через цепочку
Проверь MTU. Иногда MTU в VPN/LAN меньше, чем нужно для TCP-over-TCP. Добавь в конфиг:
Для совсем медленных каналов попробуй сжатие:
ProxyJump покрывает 90% случаев. Если нужна визуализация или UI-менеджер — смотри в сторону sssh-config или Terminator, но для консольной работы ~/.ssh/config с ProxyJump достаточно.