Риски проброса SSH-агента
- title
- Риски проброса SSH-агента
- type
- concept
- summary
- Почему ssh -A (и ForwardAgent) дают целевому хосту возможность аутентифицироваться от вашего имени везде, куда есть доступ у загруженных ключей
- tags
- ssh, security, lateral-movement
- sources
- ssh-cheatsheet-grahamhelton
- created
- 2026-05-21
- updated
- 2026-05-21
- lang
- ru
- translation_of
- ssh-agent-forwarding-risk
- source_updated
- 2026-05-21
- translated
- 2026-09-01
- translator
- lllm/antigravity/gemini-3.7-flash-medium
ssh-agent - это локальный демон, который хранит расшифрованные закрытые ключи после ssh-add. SSH-клиент обращается к нему через доменный сокет Unix ($SSH_AUTH_SOCK) для подписи проверочных запросов при аутентификации. Проброс агента (флаг -A или ForwardAgent yes в ~/.ssh/config) транслирует этот сокет на SSH-сервер: теперь удалённый хост может запрашивать у локального агента подпись проверок от своего имени.
Это удобно - цепочка ssh user@hop, а затем ssh user@next работает без копирования закрытых ключей по промежуточным узлам - и опасно: root на целевом хосте (или любой, у кого есть доступ к файлу проброшенного сокета) может использовать агент для аутентификации на любом ресурсе, куда дают доступ загруженные ключи оператора. Сами закрытые ключи злоумышленник не видит, но ему это и не требуется: достаточно по требованию просить агент поставить подпись.
Схема атаки
- Оператор выполняет
ssh -A user@target, имеяid_rsa_prod, загруженный в агент. - Атакующий с правами root на
targetперебирает сокеты/tmp/ssh-*/agent.*и находит сокет оператора. - Задаёт
SSH_AUTH_SOCKна этот путь и выполняетssh-add -l, чтобы увидеть список загруженных ключей. - Выбирает хост назначения (
ssh-add -lпоказывает комментарии к ключам, где часто указаны имена хостов) и выполняетssh prod-bastion.corp- агент подписывает запрос, аутентификация проходит успешно.
Оператор этого не видит. Проброшенный сокет живёт ровно столько, сколько длится SSH-сессия, но этого времени более чем достаточно. У Хелтона есть подробный разбор в Zero Effort Private Key Compromise, для этой вики ещё не изученный.
Почему операторы всё равно это делают
Без -A работа через цепочку хостов вынуждает копировать ключи на каждый промежуточный узел. Это ещё хуже: постоянные файлы ключей оседают на машинах, которые оператор не контролирует. Проброс агента оказывается меньшим из двух зол, если альтернатива - разбрасывать ключи.
Более безопасные альтернативы
-J/ProxyJump- для типичного сценария "мне нужно попасть на внутренний хост, а не работать на промежуточном". Прокладывает маршрут через промежуточный узел, вообще не раскрывая на нём ключи. Аутентификация на каждом участке по-прежнему происходит на стороне клиента, но сокет агента остаётся локальным. Именно для этого чаще всего ошибочно используют-A.- Отдельные пары ключей под каждый хост - ломают предположение, что "один ключ открывает всё". Скомпрометированный агент даёт доступ только к тем ключам, которые загружены прямо сейчас.
- Запрос подтверждения (
ssh-add -c) - заставляет агент запрашивать подтверждение перед каждой операцией подписи. Неудобно, но исключает скрытое неконтролируемое использование. - Ключи с ограниченным сроком действия (
ssh-add -t <seconds>) - ключи автоматически выгружаются из агента по истечении времени; в сочетании с-cдают эшелонированную защиту. - ephemeral-credentials - короткоживущие SSH-сертификаты от CA (Vault, smallstep, EC2 Instance Connect) полностью снимают проблему долгоживущих ключей.
Обнаружение
Директива Match в ~/.ssh/config позволяет ограничить ForwardAgent yes только теми конкретными хостами, где границы доверия действительно проверены оператором, оставляя значение по умолчанию no для всех остальных. Смена поведения по умолчанию - включение по явному разрешению (opt-in вместо opt-out) - самый дешёвый способ снизить риски.
См. также
- ssh-port-forwarding - ортогональные режимы
-L/-R/-D/-J, которые работают с трафиком, а не с учётными данными - ssh-port-forwarding-cheatsheet - шпаргалка Хелтона для red team, где описан этот риск
- ephemeral-credentials - структурное решение проблемы долгоживущих SSH-ключей
- long-lived-keys - аргументация Людвига о том, почему ротация ключей не решает проблему
- credential-compartmentalization - тот же принцип применительно к разным типам учётных данных