termal.in

← Блог

ssh-agent в Windows: запустить службу, добавить ключи, исправить ошибки

· Termalin Team sshssh-agentwindowstutorial

Вы поставили на SSH-ключ парольную фразу — и теперь Windows спрашивает её при каждом git push и каждом ssh. Решение — SSH-агент: разблокируйте ключ один раз, и все последующие подключения подписываются молча. Нюанс Windows в том, что агент здесь не один. Их три, они могут работать одновременно, хранят ключи в разных местах, и ключ, загруженный в один, невидим для остальных. Почти любая проблема с агентом из разряда «вчера же работало» в Windows — это на самом деле проблема не того агента. Поэтому гайд сначала их называет, затем запускает каждого, а потом разбирает ошибки, с которыми вы действительно сталкиваетесь.

Три агента и почему они не делятся ключами

АгентПоставляется сГде слушаетКакой ssh его видит
OpenSSH Authentication Agent (служба Windows)штатный OpenSSH в Windowsименованный канал \\.\pipe\openssh-ssh-agentssh.exe из C:\Windows\System32\OpenSSH
Агент MSYS2 (ssh-agent)Git for Windows / Git BashUnix-сокет, имя которого задаётся в SSH_AUTH_SOCKssh, встроенный в Git Bash
Агент Linuxвнутри вашего дистрибутива WSLUnix-сокет внутри этого дистрибутиваssh, запущенный внутри WSL

Вывод из таблицы: ssh-add в Git Bash загружает ключ в агент MSYS2, и штатный ssh.exe в Windows его никогда не увидит — другой эндпоинт, другое хранилище ключей. Выберите один агент, загрузите ключи в него и пользуйтесь соответствующим ssh. Смешивание — корень большинства путаницы ниже. Гайд по ssh-agent и ssh-add (на английском) описывает кроссплатформенную механику; эта страница — её Windows-специфичная половина.

Встроенная служба OpenSSH Authentication Agent

В современных Windows 10 и 11 есть OpenSSH, а вместе с ним — служба Windows, которая запускает агент, но по умолчанию она выключена. Включите её один раз из PowerShell с правами администратора (Запуск от имени администратора):

Set-Service ssh-agent -StartupType Automatic
Start-Service ssh-agent

Automatic запускает её при каждой загрузке, так что настройка разовая. Проверьте результат:

Get-Service ssh-agent | Select-Object Status, StartType

Вам нужны Running и Automatic. С этого момента в обычном PowerShell (не в Git Bash) или cmd команда ssh-add общается именно с этой службой:

ssh-add                                 # load default keys (id_ed25519, id_rsa, …)
ssh-add $env:USERPROFILE\.ssh\id_ed25519  # load a specific key
ssh-add -l                              # list loaded key fingerprints

ssh-add -l — первая диагностика при любом сбое входа: если нужного ключа нет в списке, агент не сможет им подписать, как бы правильно ни выглядело всё остальное.

Чтобы не набирать ssh-add каждый раз, пусть первое подключение само загрузит ключ. Добавьте это в %USERPROFILE%\.ssh\config (тот самый файл ssh_config (на английском), который OpenSSH читает везде):

Host *
    AddKeysToAgent yes

Теперь первый ssh, которому нужна парольная фраза, спросит её один раз и попутно загрузит ключ в службу. А поскольку штатные git и ssh в Windows используют эту же службу, git push тоже начинает работать молча.

Ошибка 1058: «unable to start the ssh-agent service»

Вы выполняете Start-Service ssh-agent и получаете:

Start-Service : Service 'OpenSSH Authentication Agent (ssh-agent)' cannot be started due to the following error:
Cannot start service ssh-agent on computer '.'.
... error 1058 ...

Ошибка 1058 означает, что служба отключена: Windows не запустит службу с типом запуска Disabled, а Start-Service сам этого не меняет. Сначала поправьте тип запуска, затем запустите (PowerShell с правами администратора):

Set-Service ssh-agent -StartupType Manual
Start-Service ssh-agent

Manual достаточно, чтобы запускать её по требованию; используйте Automatic, если хотите, чтобы она поднималась при каждой загрузке. Если вы на управляемой или доменной машине, службу могла отключить групповая политика — тогда, прежде чем это закрепится, её должен разрешить ваш администратор.

«error connecting to agent: No such file or directory»

Эта ошибка приходит от ssh из Git Bash / MSYS2, а не от службы Windows. Она означает, что ssh сказали, где искать сокет агента — через SSH_AUTH_SOCK, — а там ничего нет. Две частые причины:

  • В этой оболочке не запущен агент. Git Bash его за вас не запускает. Запустите его в той оболочке, которой пользуетесь:

    eval "$(ssh-agent -s)"
    ssh-add ~/.ssh/id_ed25519

    eval здесь важен: ssh-agent -s только печатает переменные, а eval их устанавливает, чтобы ssh нашёл сокет. Запустить ssh-agent без обёртки и недоумевать, почему ничего не изменилось, — классическая ошибка.

  • SSH_AUTH_SOCK устарел. Переменная, выставленная прошлой сессией, профилем входа или другим инструментом, указывает на сокет, которого больше нет. Проверьте её через echo $SSH_AUTH_SOCK, а затем либо сбросьте её и запустите свежий агент, либо исправьте, чтобы она указывала на живой.

Если вы предпочитаете пользоваться службой Windows из Git Bash, вызывайте штатный бинарник напрямую — /c/Windows/System32/OpenSSH/ssh.exe — вместо ssh из MSYS2 в вашем PATH. Тогда Git Bash доберётся до тех же ключей, что вы загрузили в службу, и SSH_AUTH_SOCK перестанет иметь значение.

Ключи в WSL

WSL — это отдельная система Linux, поэтому у неё свой агент, свой ~/.ssh и свой SSH_AUTH_SOCK. Ключи, загруженные на стороне Windows, не видны внутри вашего дистрибутива, и наоборот. Есть два честных варианта:

  • Запустить агент внутри WSL обычным для Linux способом — eval "$(ssh-agent -s)" и ssh-add, либо AddKeysToAgent yes в ~/.ssh/config дистрибутива. Просто, полностью изолированно и описано в гайде по ssh-add (на английском).
  • Связать с агентом Windows, чтобы оба мира использовали одно хранилище ключей. Обычный рецепт перенаправляет именованный канал Windows в Unix-сокет, на который указывает SSH_AUTH_SOCK в WSL, с помощью npiperelay.exe вместе с socat. После настройки работает хорошо, но это лишние движущиеся части — беритесь за это, только если вам действительно нужен один и тот же ключ по обе стороны.

Что бы вы ни выбрали, помните: ssh-add -l внутри WSL — это другой вопрос, чем ssh-add -l в PowerShell. При отладке задавайте правильный.

Когда агент в порядке, а вход всё равно не проходит

Если ssh-add -l показывает ваш ключ, а сервер всё равно отвечает Permission denied (publickey), агент своё дело сделал — проблема ушла дальше, к серверному authorized_keys, не тому пользователю или не тому предлагаемому ключу. Это отдельный чек-лист: Permission denied (publickey): исправляем по порядку (на английском). А прежде чем пробрасывать агент на удалённую машину через ssh -A, прочитайте, почему проброс агента удобен и опасен (на английском): он открывает живое использование ваших ключей на дальнем конце.

Как Termalin решает это в Windows

Если возиться со службами, сокетами и тремя хранилищами ключей — это больше, чем вам хочется держать в голове, то именно такой рабочий процесс встроен в Termalin. Он запускает собственный ключ-агент на именованном канале Windows, \\.\pipe\termalin-ssh-agent, и отдаёт ключи, которые вы уже разблокировали в приложении, по стандартному протоколу ssh-agent — так что любой инструмент, говорящий на этом протоколе, может подписывать через него без включения службы ОС, без строки eval и без ручного ssh-add. Приватные ключи остаются в работающем приложении и никогда не пишутся на диск. Смысл этого агента в том, чтобы собственный MCP-сервер Termalin аутентифицировался на ваших серверах вашими ключами, ни разу не держа сам ключевой материал: агент подписывает, а вызывающая сторона никогда не видит секрет. Та же идея «одной разблокировки», что и у службы OpenSSH, но настройку в Windows с вас снимают.


Termalin — бесплатный кроссплатформенный SSH-клиент, встроенный агент которого разблокирует ваши ключи один раз и подписывает от вашего имени — скачайте его или прочитайте, как он безопасно обращается с ключами.

Попробуйте на одном хосте.

Termalin — быстрый SSH-клиент для вас и ваших агентов.

Бесплатный тариф · 14 дней Pro бесплатно · цены