SSH 키에 암호구를 걸었더니 이제 Windows가 git push 때마다, ssh 때마다 그걸 물어봅니다. 해결책은 SSH 에이전트입니다. 키를 한 번 잠금 해제하면 그 뒤의 모든 연결은 조용히 서명됩니다. Windows에서의 반전은 에이전트가 하나가 아니라는 점입니다. 동시에 돌아갈 수 있는 에이전트가 셋이고, 저마다 다른 곳에 키를 보관하며, 한쪽에 올린 키는 다른 쪽에서 보이지 않습니다. Windows에서 ‘어제는 됐는데’ 하는 에이전트 문제는 거의 전부 사실 엉뚱한 에이전트 문제입니다. 그래서 이 안내는 먼저 셋의 이름을 짚고, 각각을 띄운 다음, 실제로 마주치는 오류를 풀어 줍니다.
에이전트 셋, 그리고 왜 키를 공유하지 않는가
| 에이전트 | 함께 제공되는 것 | 어디서 수신하나 | 어느 ssh가 보나 |
|---|---|---|---|
| OpenSSH Authentication Agent (Windows 서비스) | Windows 네이티브 OpenSSH | 명명된 파이프 \\.\pipe\openssh-ssh-agent | C:\Windows\System32\OpenSSH의 ssh.exe |
MSYS2 에이전트 (ssh-agent) | Git for Windows / Git Bash | SSH_AUTH_SOCK로 지정된 Unix 스타일 소켓 | Git Bash에 번들된 ssh |
| Linux 에이전트 | WSL 배포판 안 | 그 배포판 안의 Unix 소켓 | WSL 안에서 도는 ssh |
표에서 얻는 교훈: Git Bash에서 ssh-add를 하면 키가 MSYS2 에이전트에 올라가고, 네이티브 Windows ssh.exe는 그 키를 영영 보지 못합니다. 엔드포인트가 다르고 키 저장소가 다르기 때문입니다. 에이전트 하나를 고르고, 거기에 키를 올리고, 거기에 맞는 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이면 됩니다. 그 뒤로는 일반(Git Bash가 아닌) PowerShell이나 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에 넣으세요(OpenSSH가 어디서나 읽는 바로 그 ssh_config 파일(영어)입니다):
Host *
AddKeysToAgent yes
이제 암호구가 필요한 첫 ssh가 한 번 묻고, 부수 효과로 키를 서비스에 올립니다. 네이티브 Windows git과 ssh가 모두 이 서비스를 쓰므로 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”
이 오류는 Windows 서비스가 아니라 Git Bash / MSYS2의 ssh에서 나옵니다. ssh가 SSH_AUTH_SOCK을 통해 에이전트 소켓을 어디서 찾을지 전달받았는데 거기에 아무것도 없다는 뜻입니다. 흔한 원인 두 가지:
-
이 셸에서 에이전트가 돌고 있지 않습니다. Git Bash는 에이전트를 대신 띄워 주지 않습니다. 지금 쓰는 셸에서 직접 시작하세요:
eval "$(ssh-agent -s)" ssh-add ~/.ssh/id_ed25519eval이 중요합니다.ssh-agent -s는 변수를 출력만 하고,eval이 그 변수를 설정해ssh가 소켓을 찾을 수 있게 합니다.ssh-agent를 그냥 실행해 놓고 왜 아무것도 안 바뀌나 의아해하는 게 전형적인 실수입니다. -
SSH_AUTH_SOCK이 낡았습니다. 이전 세션, 로그인 프로파일, 또는 다른 도구가 설정한 변수가 더 이상 존재하지 않는 소켓을 가리킵니다.echo $SSH_AUTH_SOCK로 확인한 다음, 그 변수를 해제하고 새 에이전트를 시작하거나, 살아 있는 소켓을 가리키도록 고치세요.
Git Bash 안에서 Windows 서비스를 쓰고 싶다면, PATH에 있는 MSYS2 ssh 대신 네이티브 바이너리를 직접 호출하세요 — /c/Windows/System32/OpenSSH/ssh.exe. 그러면 Git Bash가 서비스에 올린 바로 그 키에 닿고, SSH_AUTH_SOCK은 더 이상 중요하지 않게 됩니다.
WSL 안의 키
WSL은 별도의 Linux 시스템이라, 자체 에이전트, 자체 ~/.ssh, 자체 SSH_AUTH_SOCK을 갖습니다. Windows 쪽에 올린 키는 배포판 안에서 보이지 않고, 그 반대도 마찬가지입니다. 솔직한 선택지는 두 가지입니다:
- WSL 안에서 에이전트를 돌리기 — 평범한 Linux 방식으로,
eval "$(ssh-agent -s)"와ssh-add, 또는 배포판의~/.ssh/config에AddKeysToAgent yes. 단순하고, 완전히 격리되며, ssh-add 안내(영어)에서 다룹니다. - Windows 에이전트로 다리를 놓기 — 두 세계가 키 저장소 하나를 공유하도록. 흔한 방법은
npiperelay.exe와socat을 함께 써서 Windows 명명된 파이프를 WSL의SSH_AUTH_SOCK이 가리키는 Unix 소켓으로 흘려보내는 것입니다. 한 번 설정하면 잘 돌아가지만 움직이는 부품이 늘어납니다. 양쪽에서 정말로 같은 키가 필요할 때만 꺼내 쓰세요.
무엇을 고르든, WSL 안의 ssh-add -l은 PowerShell의 ssh-add -l과 다른 질문이라는 점을 기억하세요. 디버깅할 때는 맞는 쪽에 물어보세요.
에이전트는 멀쩡한데 로그인은 여전히 실패할 때
ssh-add -l이 키를 보여 주는데도 서버가 여전히 Permission denied (publickey)라고 한다면, 에이전트는 제 몫을 다한 것입니다. 문제는 하류로 넘어가 서버의 authorized_keys, 잘못된 사용자, 또는 엉뚱한 키가 제시된 것 쪽에 있습니다. 그건 별도의 체크리스트입니다: Permission denied (publickey), 순서대로 해결하기(영어). 그리고 ssh -A로 원격 머신에 에이전트를 포워딩하기 전에, 에이전트 포워딩이 편리하면서도 위험한 이유(영어)를 읽어 보세요. 그건 반대편에서 내 키가 실시간으로 쓰이도록 노출하는 것입니다.
Termalin은 Windows에서 이걸 어떻게 처리하나
서비스, 소켓, 키 저장소 셋을 저글링하는 게 생각하고 싶은 것보다 과하다면, 그게 바로 Termalin이 기본으로 담은 작업 흐름입니다. Termalin은 Windows 명명된 파이프 \\.\pipe\termalin-ssh-agent에서 자체 키 에이전트를 돌리고, 앱에서 이미 잠금 해제한 키를 표준 ssh-agent 프로토콜로 제공합니다. 그래서 그 프로토콜을 쓰는 도구는 켤 OS 서비스도, eval 줄도, 수동 ssh-add도 없이 이 에이전트를 거쳐 서명할 수 있습니다. 개인 키는 실행 중인 앱 안에 머물고 디스크에 기록되지 않습니다. 이 에이전트의 핵심은 Termalin의 MCP 서버가 키 자체를 결코 쥐지 않고 내 키로 서버에 인증하게 하는 것입니다. 에이전트가 서명하고, 호출자는 비밀을 보지 못합니다. OpenSSH 서비스와 똑같은 한 번 잠금 해제 개념이되, Windows 설정 수고는 덜어 줍니다.
Termalin은 무료 크로스 플랫폼 SSH 클라이언트로, 내장 에이전트가 키를 한 번 잠금 해제하고 사용자를 대신해 서명합니다. 다운로드하거나, 키를 안전하게 다루는 방식을 읽어 보세요.