Слышал историю, как один админ перестал вводить пароль от ключа, и что из этого вышло? 😄
Ладно, если серьёзно: ssh-agent — штука удобная, но многие используют его, как бог на душу положит, а потом удивляются, почему их сервера взламывают. Сегодня разберем, как работает агент, как им пользоваться без фатальных ошибок и почему ForwardAgent — это как дать ключи от квартиры случайному попутчику.
Проблема: ключи с паролем и бесконечные ssh
Ты сгенерировал ed25519 ключ, задал passphrase (молодец, безопасность превыше всего). Но теперь при каждом подключении к серверу ssh просит пароль. За день открываешь 10 сессий — 10 раз вводишь. Бесит.
Можно, конечно, убрать passphrase, но тогда если ключ украдут — всё пропало. Не вариант.
Решение: ssh-agent
Агент — это такой демон (программа), который запускается у тебя на машине, хранит в памяти твои ключи в расшифрованном виде и отдает их ssh-клиенту по требованию.
Как это работает?
- Ты запускаешь агента.
- Добавляешь в него ключи командой ssh-add (один раз вводишь passphrase).
- Агент держит ключи в памяти.
- Когда ты делаешь ssh user@host, клиент обращается к агенту через специальный сокет (файл), агент отдает ключ — и ты заходишь без пароля.
Запускаем и добавляем ключи:
bash
eval $(ssh-agent) # запускаем агента и устанавливаем переменные окружения
ssh-add ~/.ssh/id_ed25519 # добавляем ключ, вводим passphrase один раз
Теперь все ssh-подключения в этой сессии терминала будут использовать агент. Чтобы проверить, какие ключи в агенте: ssh-add -l.
Автоматизируем запуск: В современных Linux и macOS агент часто запускается автоматически при входе в систему. Тогда достаточно один раз добавить ключ навсегда в keychain (macOS) или в GNOME Keyring. Но если хочешь ручной контроль — правь ~/.profile или используй ssh-add при старте shell'а.
Агент и прыжки через бастион: как не наступить на грабли
Вот тут начинается самое интересное. Допустим, у тебя есть инфраструктура: ты заходишь на bastion-хост, а с него — на внутренние сервера.
Плохой вариант (к сожалению, частый): скопировать свой приватный ключ на bastion. Если bastion взломают — ключ уплывет к злоумышленникам.
Вариант получше: использовать ForwardAgent (опция -A или ForwardAgent yes в конфиге). Что происходит: при подключении к bastion'у твой локальный агент пробрасывается на bastion через SSH-соединение. На bastion'е создается сокет, и все ssh-запросы с bastion'а направляются обратно к твоему агенту.
Ты сидишь на bastion'е, делаешь ssh internal-server — и заходишь, потому что твой локальный ключ подходит. Ключ при этом нигде не хранится, все безопасно? Не совсем.
Риски ForwardAgent:
- Пока ты подключен к bastion'у с форвардингом агента, любой пользователь с правами root на bastion'е (или зловредный процесс) может обратиться к твоему проброшенному сокету и использовать твои ключи для доступа к другим серверам.
- Если bastion скомпрометирован — злоумышленник получит доступ ко всем системам, куда у тебя есть ключи, пока твоя сессия активна.
Почему это реально опасно? Были случаи, когда через форвардженный агент с локальной машины разработчика уходили в прод. Хватило того, что на bastion'е кто-то запустил ssh -A и забыл.
Альтернатива: ProxyJump вместо ForwardAgent
Помнишь мой предыдущий пост про ~/.ssh/config и ProxyJump ? Это не только удобно, но и безопасно. При использовании ProxyJump или -J соединение с конечным сервером устанавливается с твоей локальной машины, а bastion выступает просто как транзитный туннель. Ключи никуда не пробрасываются, агент не форвардится.
Пример конфига:
bash
Host bastion
HostName bastion.mycompany.com
User vasya
Host internal
HostName 10.0.5.10
User deploy
ProxyJump bastion
Теперь ssh internal работает, но ключи на bastion не уходят. Это безопаснее.
Когда же ForwardAgent всё-таки нужен?
Бывают ситуации, когда без него не обойтись:
- Если тебе нужно на bastion'е запускать git-команды, которые тянут репозитории с GitHub/GitLab по ssh (и ключи там твои, а не системные).
- Если внутренние сервера доступны только через цепочку прыжков, и ProxyJump не справляется из-за особенностей сети (хотя современный SSH умеет цепочку через запятую: ProxyJump bastion1,bastion2 ).
Но даже в этих случаях лучше осознавать риски и включать форвардинг только для доверенных промежуточных хостов, которые ты контролируешь. И выключать, как только надобность отпала.
Памятка по безопасности агента
- Не копируй приватные ключи на сервера. Никогда. Используй агент или ProxyJump.
- ForwardAgent включай только по необходимости и только на хостах, которым доверяешь на 100%. Можно прописать в конфиге для конкретного хоста: ForwardAgent yes.
- Используй ssh-add с опцией -t (таймаут), чтобы ключи автоматически удалялись из памяти через заданное время. Например, ssh-add -t 3600 ~/.ssh/id_ed25519 — ключ проживет час.
- Проверяй, какие ключи загружены: ssh-add -l. Если видишь лишнее — сбрось агент (ssh-add -D или перезапусти).
- На bastion'ах лучше использовать ProxyJump, а не ForwardAgent.
Что дальше?
Мы только коснулись темы. На самом деле с агентом можно творить магию: пробрасывать его через несколько хостов, использовать ключи на смарт-картах (YubiKey), интегрировать с системными keyring. Но основа — понимать, как и зачем, чтобы не прострелить себе ногу.
Кстати, на моем курсе «OpenSSH» мы детально разбираем:
- архитектуру агента (чтобы понимать, что за сокет и как с ним работать),
- безопасный проброс агента в сложных сценариях,
- альтернативы (ProxyJump, ProxyCommand),
- настройку PAM для двухфакторки и другие методы харденинга.
Если хочешь прокачаться в SSH до уровня «архитектор», заходи по ссылке на курс OpenSSH от Rebrain.
Пользуйтесь агентом с умом, и пусть ваши ключи всегда будут при вас. 🙌