SSH "Too many authentication failures" 5분 해결 — IdentitiesOnly로 끝내기
어제까지 멀쩡하게 잘 붙던 서버가, 오늘 갑자기 이렇게 끊깁니다.
Received disconnect from 203.0.113.10 port 22:2: Too many authentication failures
Disconnected from 203.0.113.10 port 22비밀번호도 안 물어보고 그냥 끊어버리니 당황스럽죠. 결론부터 말하면, 이건 키가 틀려서가 아닙니다. 오히려 "맞는 키도 가지고 있는데, 그 키 차례가 오기 전에 엉뚱한 키들을 줄줄이 던지다가 서버 한도를 초과해서" 강제 종료되는 상황입니다. ~/.ssh/config 한 줄이면 5분 안에 영구 해결됩니다.
Permission denied와는 완전히 다른 에러다
가장 먼저 못 박고 시작하겠습니다. 많은 분들이 이 에러를 보고 Permission denied (publickey) 해결법을 검색해서 키를 다시 만들고 서버에 또 등록하지만, 방향이 정반대입니다.
| 구분 | Permission denied (publickey) | Too many authentication failures |
|---|---|---|
| 의미 | 인증할 올바른 키가 없음/등록 안 됨 | 인증할 키는 있는데 너무 많이 던져서 한도 초과 |
| 해야 할 일 | 키 생성·서버에 공개키 등록 | 던지는 키 개수를 줄이기 |
| 키 추가하면? | 해결될 수 있음 | 오히려 악화됨 |
즉 이 에러를 보고 키를 더 추가하면 상황이 더 나빠집니다. 우리가 할 일은 정반대로, 던지는 키를 줄이는 것입니다.
왜 끊기는가 — ssh-agent와 MaxAuthTries의 충돌
메커니즘을 이해하면 해결책이 자연스럽게 보입니다.
① 클라이언트는 ssh-agent에 로드된 키를 "순서대로 전부" 던진다. GitHub 개인키, 회사키, 서버 A키, 서버 B키, 클라우드 인스턴스키… 이렇게 ssh-agent에 키가 잔뜩 로드돼 있으면, SSH는 접속할 때 이 키들을 하나씩 순서대로 서버에 제시(offer)합니다. 서버가 "그 키 아니야"라고 하면 다음 키로 넘어갑니다.
② 서버 sshd에는 MaxAuthTries라는 시도 한도가 있다 (기본값 6).
한 번의 TCP 연결 안에서 인증 시도 1개당 카운트가 1씩 올라갑니다. 이 카운트가 MaxAuthTries를 넘는 순간 서버는 연결을 끊어버립니다.
③ 그래서 agent에 키가 6개를 넘으면, 맞는 키 차례가 오기 전에 끊긴다. 예를 들어 진짜 맞는 키가 8번째에 있는데, 서버 기본 한도가 6이면? 앞의 6개를 던지는 순간 한도 초과로 disconnect됩니다. 정작 맞는 키는 꺼내보지도 못한 거죠.
요즘은 1Password SSH-agent 통합, 멀티 GitHub 계정(개인+회사), 클라우드 인스턴스 다수 운영 등으로 키가 폭증하기 쉽습니다. 그래서 이 에러를 만나는 빈도도 부쩍 늘었습니다.
진단: ssh -v로 키가 던져지는 순서를 눈으로 본다
추측하지 말고 직접 봅시다. -v(verbose)를 붙이면 어떤 키를, 어떤 순서로 던지는지 다 보입니다.
ssh -v [email protected]출력에서 핵심 라인만 추리면 이렇습니다.
debug1: Offering public key: /Users/me/.ssh/id_rsa_github # ← (1) 엉뚱한 키 던짐 (카운트1)
debug1: Authentications that can continue: publickey # 서버: "그거 아님, 계속해"
debug1: Offering public key: /Users/me/.ssh/id_rsa_work # ← (2) 또 엉뚱한 키 (카운트2)
debug1: Authentications that can continue: publickey
debug1: Offering public key: /Users/me/.ssh/id_ed25519_aws # ← (3) 또 엉뚱한 키 (카운트3)
...
debug1: Offering public key: /Users/me/.ssh/id_ecdsa_old # ← (6) 6번째, 한도 도달
Received disconnect from 203.0.113.10 port 22:2: Too many authentication failuresOffering public key: 라인 하나가 "키 한 번 던짐 = 카운트 +1"입니다. 위 출력은 맞는 키에 도달하기도 전에 6번을 다 써버리고 disconnect된 전형적인 모습입니다.
이제 agent에 키가 몇 개 로드돼 있는지 확인합니다.
ssh-add -l # 에이전트에 로드된 키 목록 (개수 확인)여기서 나오는 키 개수가 서버 MaxAuthTries(보통 6)보다 많다면 원인 확정입니다. 급하면 일단 비웠다가 필요한 키만 다시 넣어도 됩니다.
ssh-add -D # 에이전트의 모든 키 제거
ssh-add ~/.ssh/id_ed25519 # 필요한 키만 다시 등록서버에 접근 권한이 있다면 서버측 한도도 확인할 수 있습니다.
grep MaxAuthTries /etc/ssh/sshd_config해결: IdentitiesOnly=yes로 호스트별 키를 한정한다
근본 해결책은 "이 호스트엔 이 키만 던져"라고 명시하는 것입니다. 핵심은 IdentitiesOnly yes입니다. 이 옵션이 없으면 SSH는 IdentityFile을 지정해도 agent에 있는 다른 키들까지 추가로 다 던집니다. IdentitiesOnly yes를 켜야 "지정한 키만" 시도하도록 강제됩니다.
(a) 단일 호스트 키 한정 — 복붙용
# ~/.ssh/config
Host myserver
HostName 203.0.113.10
User deploy
IdentityFile ~/.ssh/id_ed25519_myserver
IdentitiesOnly yes이제 ssh myserver만 치면 됩니다. 키 1개만 던지므로 한도 초과가 절대 일어나지 않습니다.
(b) 다중 계정 패턴 — GitHub 개인/회사 + 사내 서버
멀티 계정 환경에서 강력 추천하는 패턴입니다.
# ~/.ssh/config
# GitHub 개인 계정
Host github.com
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519_personal
IdentitiesOnly yes
# GitHub 회사 계정 (clone 시 git@github-work:org/repo.git 형태로 사용)
Host github-work
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519_work
IdentitiesOnly yes
# 사내 서버
Host company-server
HostName 10.0.1.20
User devops
IdentityFile ~/.ssh/id_ed25519_company
IdentitiesOnly yes회사 레포는 git clone git@github-work:org/repo.git처럼 github-work 호스트 별칭을 써서 클론하면 회사 키로만 인증됩니다.
임시 해결 (config 손대기 전 급할 때)
ssh -o IdentitiesOnly=yes -i ~/.ssh/id_ed25519_myserver [email protected]이 명령은 agent의 다른 키를 무시하고 -i로 지정한 키 하나만 던집니다. 다만 매번 치긴 번거로우니, 결국 config로 옮기는 걸 권장합니다.
클라이언트 원인 vs 서버 원인 구분
| 항목 | 클라이언트 문제 | 서버 문제 |
|---|---|---|
| 증상 | 내 PC에서만, 특정 호스트에서 발생 | 모든 사용자가 키 몇 개만 넘어도 발생 |
| 원인 | agent에 키가 너무 많음 | MaxAuthTries가 비정상적으로 낮음(예: 2) |
| 확인 | ssh-add -l 개수 ↑ | grep MaxAuthTries /etc/ssh/sshd_config |
| 해결 | IdentitiesOnly yes + IdentityFile | 한도를 합리적 값으로 (단, 신중히) |
서버 운영자 주의: MaxAuthTries를 무작정 크게 올리는 건 위험합니다. 이 값이 클수록 한 연결에서 공격자가 시도할 수 있는 인증 횟수가 늘어 브루트포스 노출이 커집니다. 진짜 문제는 거의 항상 클라이언트의 키 과다이므로, 서버 한도를 올리기 전에 config부터 정리하세요.
실무 한마디 — agent는 "지갑"이 아니다
여러 클라우드 인스턴스를 운영하다 보면 새 키가 생길 때마다 무심코 ssh-add로 agent에 다 밀어넣게 됩니다. 저도 인스턴스가 10개를 넘어가던 시점에 이 에러를 만났습니다. 교훈은 명확합니다. agent는 "지금 쓰는 키"만 담는 작업 공간이지, 모든 키를 보관하는 지갑이 아닙니다. 키 관리는 agent가 아니라 ~/.ssh/config로 하세요. 그래야 어떤 호스트에 어떤 키가 쓰이는지 한눈에 보이고, 이 에러도 영구히 사라집니다. 새 키는 ed25519로 만드는 걸 권장합니다(ssh-keygen -t ed25519).
안티패턴 경고
- ❌ agent에 모든 키 때려넣기 → 키가 6개 넘으면 이 에러의 직행 티켓
- ❌ config 없이 매번
-i로 때우기 → 임시방편, 협업·CI에서 재현 안 됨 - ❌ 서버
MaxAuthTries를 무작정 크게 → 브루트포스 공격 표면 확대 - ✅
~/.ssh/config+IdentitiesOnly yes로 호스트별 키 1:1 매핑
자주 묻는 질문 (FAQ)
Q. IdentitiesOnly yes를 켜면 다른 서버 접속이 막히지 않나요?
A. 아니요. config의 Host 블록은 호스트별로 따로 적용되므로, 각 호스트에 지정한 IdentityFile만 사용합니다. 호스트마다 맞는 키를 지정해두면 모든 접속이 정상 동작합니다.
Q. ssh-add -D로 키를 다 지우면 다른 작업에 지장 없나요?
A. agent의 메모리에서만 제거될 뿐, 디스크의 키 파일(~/.ssh/*)은 그대로입니다. 필요할 때 ssh-add로 다시 올리거나, config에 IdentityFile을 지정해두면 agent 없이도 접속됩니다.
Q. 서버 운영자인데 사용자들이 자꾸 이 에러를 만납니다. MaxAuthTries를 올려야 하나요?
A. 권장하지 않습니다. 근본 원인은 사용자 클라이언트의 키 과다이므로, 사용자에게 IdentitiesOnly yes + IdentityFile config 설정을 안내하는 것이 보안상 훨씬 안전합니다.
오늘 바로 적용하는 3줄 체크리스트
ssh-add -l # 1. agent에 키가 몇 개인지 확인 (6개 넘으면 의심)
ssh -v user@host 2>&1 | grep "Offering" # 2. 어떤 키가 던져지는지 순서 확인
# 3. ~/.ssh/config에 해당 Host 블록 + IdentityFile + IdentitiesOnly yes 추가 → 끝이 글은 AI 에이전트가 1차 초안을 작성한 뒤, 사람 편집자가 사실관계·출처·톤과 맥락을 검토하여 발행했습니다. 오류나 부정확한 내용이 확인되면 24시간 이내에 정정합니다.
댓글
불러오는 중...