termal.in

← 블로그

ssh-agent와 ssh-add 실전: 암호구 그만 입력하기

· 업데이트 2026년 10월 24일 · Termalin Team sshssh-agentssh-keystutorial

ssh-agent는 잠금 해제된 개인 키를 메모리에 쥐고 그것으로 인증 챌린지에 서명해 주는 백그라운드 프로그램입니다. 덕분에 연결할 때마다가 아니라 세션당 한 번만 키의 암호구를 입력하게 됩니다. ssh-add는 거기에 키를 로드하는 명령입니다.

올바른 일을 해서 SSH 키에 암호구를 걸어 뒀습니다 — 그런데 점심 전에 벌써 다섯 번째 입력하고 있습니다. 해법은 수십 년 전부터 있었습니다. SSH 에이전트죠. 키를 한 번 잠금 해제하면 그 뒤의 모든 연결이 조용히 인증됩니다. 함정은 “한 번”이 성립하려면 에이전트가 실제로 돌고 있어야 하고, 셸이 그것을 찾을 수 있어야 하며, 키가 로드되어 있어야 한다는 것 — 서로 다른 세 가지이고, 각각 나름의 실패 방식이 있습니다. 이 글은 실전 가이드입니다. OS별로 에이전트를 시작하고, ssh-add로 다루고, 그 전체를 자동으로 만들고, 에이전트 문제의 거의 전부를 차지하는 두 오류를 해독합니다.

에이전트가 무엇인지, 한 단락으로

ssh-agent는 복호화된 개인 키를 메모리에 쥐고 있는 — 디스크에는 결코 두지 않는 — 작은 백그라운드 프로세스입니다. 서버가 챌린지를 걸면 ssh가 그 챌린지를 에이전트에 넘기고, 에이전트가 메모리의 키로 서명하며, 되돌아가는 것은 서명뿐입니다 — 키 자체는 에이전트를 떠나지 않고, 선로에 닿지 않으며, 디스크에서 암호화된 채로 남습니다. 키를 로드하는 암호구 프롬프트 한 번, 그 뒤의 모든 연결은 메모리에서 처리됩니다. 이것이 개념의 전부입니다. 에이전트는 서명 서비스이지, 누군가 꺼내 읽는 키 금고가 아닙니다 — 비밀을 지키면서 서명만 내줍니다. (바로 그 성질이 보안상의 함정이기도 하며, 글 끝에서 따로 다룹니다.)

Windows인가요? Windows 가이드를 먼저 읽으세요

error connecting to agent: No such file or directory를 보고 오셨다면, 그 메시지는 Windows 전용입니다. Git Bash / MSYS2의 ssh에서 나오고, 해법도 마찬가지입니다 — OpenSSH Authentication Agent 서비스, Git Bash 자체 에이전트, 그리고 오류 1058이죠. 모두 Windows의 ssh-agent에 있습니다. 아래 내용은 전부 크로스 플랫폼 ssh-agent와 ssh-add 작업 흐름이며, 거기서 해독하는 오류는 OpenSSH 클라이언트 자체의 것입니다. Could not open a connection to your authentication agent와 The agent has no identities입니다.

OS별 에이전트 시작하기

Linux — eval "$(ssh-agent -s)"

데스크톱 로그인에서는 거의 틀림없이 이미 에이전트가 있습니다 — systemd 사용자 서비스이거나 GNOME Keyring이 그 역할을 맡고 — SSH_AUTH_SOCK이 세션 전체에 export된 상태입니다. ssh-add -l로 테스트하세요. 아무것도 응답하지 않으면(맨 SSH 로그인, 컨테이너, 최소 설치 서버에서 흔합니다) 손으로 하나 시작하세요:

eval "$(ssh-agent -s)"

eval이 핵심입니다. ssh-agent -s는 SSH_AUTH_SOCK과 SSH_AGENT_PID 변수를 출력만 합니다. eval이 그것을 현재 셸에 설정해 주어야 ssh가 소켓을 찾습니다. ssh-agent를 맨손으로 실행해 놓고 왜 아무것도 안 바뀌나 의아해하는 것이, 어떤 도구도 볼 수 없는 에이전트를 “시작”하는 가장 흔한 방식입니다.

macOS — launchd가 대신 돌려 줍니다

launchd가 로그인부터 에이전트를 대신 돌려 줍니다 — 시작할 것이 없습니다. macOS 특유의 이점은 아래의 Keychain 통합입니다.

Windows에서 ssh-agent 시작하기

요즘 Windows에는 OpenSSH Authentication Agent 서비스가 들어 있지만, 수동 시작으로 설정되어 있어 기본적으로 돌지 않습니다. 관리자 권한 PowerShell에서 한 번 활성화하세요:

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

그 뒤로는 ssh-add가 어느 터미널에서든 작동하고(PowerShell, cmd, 또는 Git Bash 아래의 Windows OpenSSH 클라이언트), 에이전트는 재부팅을 견딥니다. 함정 하나: Git for Windows는 자체 ssh와 ssh-agent를 들고 오며, Git Bash 안에서 PATH의 ssh가 그쪽일 수 있어 별도의 에이전트와 대화합니다. ssh-add -l이 Git Bash와 PowerShell에서 서로 다르면, Git이 시스템 클라이언트를 가리키게 해 둘이 하나의 에이전트를 공유하게 하세요:

git config --global core.sshCommand "C:/Windows/System32/OpenSSH/ssh.exe"

전체 안내 — 서비스, Git Bash, 로그인 시 키 로드 — 는 Windows의 ssh-agent에 있습니다.

ssh-add로 다루기

키 로드하기: ssh-add ~/.ssh/id_ed25519

ssh-add                          # 기본 키 로드 (id_ed25519, id_rsa, …)
ssh-add ~/.ssh/id_ed25519        # 특정 키 로드 (암호구를 한 번 묻습니다)

경로 없이 쓰면 ssh-add는 ~/.ssh의 기본 키 이름들을 로드하고, 경로를 주면 특정 키를 로드합니다. 어느 쪽이든 암호구를 한 번 묻고 복호화된 키를 메모리에 쥡니다.

로드된 것 보기: ssh-add -l

ssh-add -l                       # 로드된 키의 지문 나열
ssh-add -L                       # 전체 공개 키 출력
ssh-add -d ~/.ssh/id_ed25519     # 키 하나 제거
ssh-add -D                       # 모든 키 제거

ssh-add -l은 모든 인증 문제의 첫 진단입니다. 기대하는 키가 그 목록에 없으면, 다른 게 아무리 멀쩡해 보여도 에이전트는 그것으로 서명할 수 없습니다.

ssh-agent 타임아웃 설정: ssh-add -t

습관으로 삼을 만한 플래그 둘:

  • -t는 수명을 정합니다. ssh-add -t 3600 ~/.ssh/id_ed25519는 키를 한 시간 동안 로드하고, 그 뒤에는 에이전트가 잊어버려 다음 사용 때 다시 묻습니다. 3주 가동 내내 메모리에 잠금 해제된 채 있는 키는, 내가 신경을 끈 지 한참 뒤에도 쓸 수 있는 키입니다.
  • -c는 확인을 요구합니다. 서명 요청마다 에이전트가 답하기 전에 로컬 프롬프트가 뜹니다. 살짝 성가시지만, 가치가 높은 키에는 딱 맞습니다.

자동화하기: AddKeysToAgent

손으로 하는 ssh-add 의식은 ~/.ssh/config(영어)의 한 줄로 사라집니다:

Host *
    AddKeysToAgent yes

이제 키가 필요한 첫 ssh가 암호구를 한 번 묻고, 부수 효과로 키를 에이전트에 로드합니다. 따로 기억할 명령이 없습니다 — 프롬프트가 그저 반복을 멈춥니다. 수명도 함께 설정해(AddKeysToAgent 1h) 플래그 없이 -t 동작을 얻을 수 있습니다.

macOS: Keychain으로 재부팅을 넘기기. 기본적으로 에이전트는 재시작하면 키를 잊습니다. macOS는 암호구를 로그인 Keychain에 저장해, 다시 입력하지 않고 키가 다시 로드되게 할 수 있습니다:

ssh-add --apple-use-keychain ~/.ssh/id_ed25519

그리고 ~/.ssh/config에:

Host *
    AddKeysToAgent yes
    UseKeychain yes

그 뒤로는 암호구 질문에 로그인 때 Keychain이 답하고, 다시는 보이지 않습니다 — 디스크의 키 파일은 암호화된 채로 남고요.

누구나 겪는 두 가지 오류

Could not open a connection to your authentication agent (인증 에이전트에 연결할 수 없음) — ssh-add가 에이전트를 찾지 못합니다. 아예 돌고 있지 않거나, 하나는 돌지만 이 셸에 SSH_AUTH_SOCK이 설정되어 있지 않습니다. 해법은 위의 OS별 시작입니다. Linux에서는 eval "$(ssh-agent -s)" 줄(먼저 데스크톱 세션이 이미 하나 제공하는지 확인하세요 — 터미널마다 둘째 에이전트를 시작하면 로드된 키가 프로세스마다 흩어집니다), Windows에서는 서비스 시작이요. 로그인 세션이 변수를 export하지 않은 cron 작업과 CI에서도 이걸 만납니다.

The agent has no identities. (에이전트에 자격 증명이 없음) — 반대 문제입니다. 에이전트는 멀쩡한데 아무것도 로드되지 않았습니다. 키를 ssh-add 하세요. 로드되었다가 사라졌다면 -t 수명이 만료됐거나 에이전트가 재시작한 것 — 바로 그걸 위해 AddKeysToAgent yes와 macOS Keychain이 있습니다.

그리고 세 번째 경우: 에이전트는 완벽해 보이고 — ssh-add -l이 키를 보여 주는데 — 서버는 여전히 Permission denied (publickey)라고 합니다. 이건 더 이상 에이전트 문제가 아닙니다. publickey 체크리스트를 짚어 보세요 — 틀린 사용자, 잘못 제시된 키, authorized_keys 권한 말입니다.

잠금 해제된 에이전트는 살아 있는 자격 증명입니다

에이전트는 키를 결코 흘리지 않습니다 — 하지만 소켓은 서명 오라클입니다. 닿을 수 있는 누구를 위해서든 서명하고, 누가 요청하는지 묻지 않습니다. 내 머신에서는 괜찮습니다 — 소켓은 나만 읽을 수 있는 사용자별 전용 디렉터리에 있으니까요. 위험은 혼동된 대리인(confused deputy) 모양입니다. 소켓이 내가 의도하지 않은 무언가의 손에 닿을 때 — 공유 배스천에 포워딩된 에이전트나, 내가 신뢰하지 않는 내 사용자 권한 프로세스 — 그것이 키를 한 번도 보지 않고도 내 키가 닿는 모든 서버에 나로서 인증할 수 있습니다. 키가 새지 않는다는 것은 보장의 절반일 뿐이고, 누가 그것을 쓸 수 있는지 통제하는 것이 나머지 절반입니다. 그래서 적은 수고의 에이전트 위생이 값어치가 있습니다.

  • 키에 수명을 주세요(-t, 또는 AddKeysToAgent의 수명). 유휴 에이전트가 스스로 식게요.
  • 자리를 뜰 때 에이전트를 잠그세요: ssh-add -x는 비밀번호로 잠그고, ssh-add -X는 풉니다. ssh-add -D는 그냥 전부 비웁니다.
  • 프로덕션에 닿는 키에는 -c를 쓰세요.
  • 에이전트를 기본으로 포워딩하지 마세요. ssh -A — ssh 에이전트 포워딩 — 는 원격 호스트에 내 키의 실사용을 노출하므로, 거기서 root를 가진 누구나 내 세션이 열려 있는 동안 나로서 서명할 수 있습니다. 이건 따로 읽어 볼 가치가 있습니다: ssh 에이전트 포워딩은 편하고 위험하다(영어).

Termalin은 이걸 어떻게 다루나

Termalin은 이 작업 흐름 전체를 날카로운 모서리를 깎아 내장합니다. 키 에이전트가 키를 한 번 잠금 해제하고 나를 대신해 서명합니다 — 활성화할 OS 서비스도, eval 줄도, 셸마다 잃어버릴 소켓도 없습니다. 암호구 캐싱은 기본으로 재잠금 타임아웃과 함께 옵니다. ssh-add -t 습관을 내가 기억하는 대신 대신 강제해 주는 셈이죠. 그리고 표준 ssh-agent 프로토콜을 말하므로 git과 기존 CLI 도구가 그대로 그것을 통해 서명합니다 — 도구 체인이 아니라 의식을 대체하는 겁니다.


Termalin은 내장 에이전트가 키를 한 번 잠금 해제하고 타이머로 다시 잠그는 무료 크로스 플랫폼 SSH 클라이언트입니다 — 다운로드하거나, 키를 안전하게 다루는 방식을 읽어 보세요.

호스트 한 대에서 먼저 써 보세요.

Termalin은 여러분과 여러분의 에이전트를 위한 빠른 SSH 클라이언트입니다.

무료 요금제 · Pro 14일 무료 체험 · 요금

Google에서 Termalin을 선호 소스로 추가