SSH Too many authentication failures 해결 방법
SSH 에이전트에 등록된 키가 많아 서버 연결이 끊기는 현상을 해결합니다. ssh -v 명령어로 원인을 진단하고, IdentitiesOnly 설정을 통해 특정 키만 서버에 전달하여 인증 실패 문제를 영구적으로 해결하는 방법을 상세히 설명합니다.
"Too many authentication failures"의 의미
"Too many authentication failures"는 SSH 클라이언트가 서버가 허용하는 개수보다 많은 키를 제시하여, 올바른 키를 시도하기도 전에 서버가 연결을 종료했음을 의미합니다. 이는 거의 항상 클라이언트 측의 문제입니다. 키는 디스크에 있고 서버의 authorized_keys에도 등록되어 있지만, 연결이 너무 일찍 종료되었기 때문에 이러한 사실들은 아무런 도움이 되지 않습니다.
원인은 다음과 같습니다. ssh-agent는 사용자가 로드한 모든 개인 키를 보관합니다. 클라이언트는 어떤 키가 계정에서 허용되는지 알 수 없으므로 서버에 키를 하나씩 제시합니다. 서버는 authorized_keys에 없는 각 키를 거부하며, 거부될 때마다 인증 실패 횟수를 누적합니다. sshd_config의 MaxAuthTries 설정은 한 연결당 허용되는 실패 횟수를 제한합니다. 기본값은 6입니다. 만약 에이전트에 10개의 키가 있고 올바른 키가 8번째에 있다면, 서버는 그 키에 도달하기 전에 연결을 끊어버립니다.
따라서 해결 방법은 클라이언트가 올바른 키 하나만 제시하도록 설정하는 것입니다.
서버가 계산하는 항목과 MaxAuthTries의 역할
공개 키 인증은 추측 게임으로 시작됩니다. 클라이언트는 공개 키를 보내고 해당 키로 생성된 서명을 서버가 수락할지 묻습니다. 서버는 예 또는 아니오로 응답합니다. "아니오"는 잘못된 비밀번호와 마찬가지로 실패한 시도로 간주됩니다.
sshd_config(5) 매뉴얼 페이지는 이 제한을 다음과 같이 설명합니다: "연결당 허용되는 최대 인증 시도 횟수를 지정합니다. 실패 횟수가 이 값의 절반에 도달하면 추가 실패가 기록됩니다. 기본값은 6입니다."
6번의 시도는 비밀번호를 직접 입력하는 사용자에게는 충분합니다. 하지만 10개의 키를 가진 에이전트에게는 부족할 수 있습니다. 실패 횟수가 제한을 초과하면 sshd는 연결을 끊고 시스템 로그에 다음과 같은 줄을 기록합니다:
error: maximum authentication attempts exceeded for deploy from 203.0.113.10 port 51292 ssh2클라이언트는 동일한 이벤트의 나머지 절반을 출력합니다:
Received disconnect from 203.0.113.10 port 22:2: Too many authentication failures
Disconnected from 203.0.113.10 port 22이는 SSH permission denied (publickey) 오류와는 다른 실패 유형입니다. 해당 오류는 서버가 제공된 모든 키를 확인했으나 수락할 수 있는 것이 없을 때 발생합니다. 반면 이 경우는 서버가 확인을 중단한 것입니다. 두 오류를 혼동하면 이미 올바른 키를 다시 복사하느라 오후 시간을 허비하게 됩니다.
동료의 노트북에서는 동일한 키가 작동하는 이유
키나 서버 설정에는 아무런 차이가 없습니다. 동료의 에이전트는 2개의 키를 보유하고 있지만, 귀하의 에이전트는 12개를 보유하고 있기 때문입니다. 동료에게는 첫 번째로 도착한 인증 제안이 귀하에게는 9번째로 도착하며, 그 시점에는 이미 연결이 종료된 상태입니다.
키의 개수는 조용히 늘어납니다. AddKeysToAgent yes의 ~/.ssh/config는 사용하는 모든 키를 에이전트에 추가하고 그대로 유지합니다. Linux의 GNOME Keyring이나 macOS의 login keychain과 같은 데스크톱 키링 에이전트는 로그인 시 별도의 확인 없이 키를 로드합니다. 1년 동안 클라이언트 키, git 호스트 키, 연구실 서버 키 등을 추가하다 보면, 어느 날 갑자기 잘 작동하던 서버가 접속을 거부하기 시작합니다. 서버 측에는 아무런 변화가 없었습니다. 단지 귀하의 에이전트가 더 많은 키로 가득 찼을 뿐입니다.
ssh -v를 사용하여 인증 제안 확인하기
실패하는 연결에 -v 옵션을 추가하여 실행하고 추적 로그를 확인합니다.
ssh -v deploy@203.0.113.10두 가지 종류의 줄이 중요합니다. Will attempt key:은 클라이언트가 구성한 ID 목록을 사용할 순서대로 나열합니다. Offering public key:은 서버로 실제로 전송된 각 키마다 한 번씩 나타납니다.
debug1: Will attempt key: /home/you/.ssh/id_ed25519 ED25519 SHA256:AAAA... agent
debug1: Will attempt key: /home/you/.ssh/id_rsa RSA SHA256:BBBB... agent
debug1: Offering public key: /home/you/.ssh/id_ed25519 ED25519 SHA256:AAAA... agent
debug1: Authentications that can continue: publickey,password
debug1: Offering public key: /home/you/.ssh/id_rsa RSA SHA256:BBBB... agent사용자의 경로, 키 유형, 지문은 다를 수 있습니다. 확인해야 할 것은 연결이 끊기기 전까지 나타나는 Offering public key: 줄의 개수입니다. 제안 목록이 지나가고 의도한 키가 나타나지 않은 채 세션이 종료된다면, 원인은 명확합니다. 줄 끝에 있는 agent이라는 단어는 해당 ID가 ssh-agent에서 가져왔음을 의미합니다. explicit라는 단어는 해당 ID가 IdentityFile 줄이나 명령줄의 -i에서 왔음을 의미합니다.
그런 다음 에이전트가 어떤 키를 보유하고 있는지 확인합니다.
ssh-add -l출력되는 각 줄은 로드된 키 하나를 나타냅니다. 만약 The agent has no identities.가 출력된다면 에이전트에는 문제가 없으므로, 대신 ~/.ssh/config 파일의 IdentityFile 줄을 확인해야 합니다. 만약 Could not open a connection to your authentication agent.이 출력된다면 에이전트가 실행 중이지 않은 것이며, 제안되는 키들은 기본 키 파일에서 가져온 것입니다.
해결책 1: 호스트당 하나의 키만 사용하는 IdentitiesOnly
IdentitiesOnly yes는 설정한 ID만 제공하고 에이전트가 제안하는 추가 ID는 무시하도록 ssh에 지시합니다. 여기에 IdentityFile 줄을 함께 사용하면 클라이언트는 단 하나의 키만 제안합니다.
Host vps
HostName 203.0.113.10
User deploy
IdentityFile ~/.ssh/id_ed25519_vps
IdentitiesOnly yes이 내용을 ~/.ssh/config에 저장한 뒤 chmod 600 ~/.ssh/config를 실행합니다. 그룹이나 다른 사용자가 쓰기 권한을 가진 파일은 ssh가 실행을 거부하며 Bad owner or permissions on /home/you/.ssh/config 오류를 발생시킵니다. 이제 ssh vps는 하나의 키만 제안하며, ssh -v vps를 실행하면 정확히 하나의 Offering public key: 줄이 표시되어야 합니다.
이 과정에서 두 가지 세부 사항이 사용자들을 당황하게 합니다.
IdentitiesOnly yes설정만으로는 "하나의 키"를 의미하지 않습니다. 기본 ID 파일도 설정된 ID로 간주하므로, ssh는 여전히~/.ssh/id_ed25519,~/.ssh/id_rsa및 기타 기본 키를 시도합니다. 따라서IdentityFile줄도 함께 필요합니다.- 서명은 여전히 에이전트가 수행합니다.
IdentitiesOnly은 어떤 키를 제안할지만 제어할 뿐, 누가 서명할지는 결정하지 않습니다.IdentityFile에 지정된 개인 키가 에이전트에 로드되어 있다면 에이전트가 서명을 생성하며, 암호(passphrase)를 묻지 않습니다.IdentityFile을 일치하는.pub파일로 지정할 수도 있는데, 이는 개인 키가 에이전트나 하드웨어 토큰에만 존재할 때 사용하는 방식입니다.
~/.ssh/config의 한 가지 함정이 이 해결책을 조용히 무력화합니다. 대부분의 키워드는 처음 발견된 값을 사용하므로 특정 Host 블록을 Host * 위에 배치해야 합니다. 하지만 IdentityFile은 이 규칙을 따르지 않습니다. 매뉴얼에 따르면 "설정 파일에 여러 ID 파일을 지정할 수 있으며, 모든 ID가 순차적으로 시도됩니다."라고 명시되어 있습니다. Host * 아래에 있는 IdentityFile는 호스트별 설정에 추가될 뿐 대체되지 않으므로, 전역 설정에 남겨둔 줄이 모든 연결에 추가적인 키 제안을 발생시킵니다.
전역 안전망을 원한다면 파일 하단에 플래그만 설정하십시오.
Host *
IdentitiesOnly yes그러면 모든 호스트마다 고유한 IdentityFile이 필요하게 되며, 이는 우리가 의도한 결과입니다. 서버당 하나의 키를 지정하는 것은 나중에 모든 키를 재발급할 필요 없이 특정 장비의 접근 권한만 취소할 수 있게 해주므로, 이 습관을 일찍 들이는 것이 좋습니다. 장비별 SSH 키 관리 방법을 참조하십시오.
해결 방법 2: 에이전트 정리 또는 재시작
아직 설정을 편집할 수 없는 상태라면, 에이전트를 비우고 필요한 항목만 로드하십시오.
ssh-add -l # list what is loaded
ssh-add -d ~/.ssh/id_rsa # remove one key
ssh-add -D # remove every key
ssh-add ~/.ssh/id_ed25519_vps # load the one you needssh-add -D 실행 직후 연결이 정상적으로 작동한다면 에이전트가 원인입니다. 이는 수리가 아닌 테스트로 간주해야 합니다. 데스크톱 키링 에이전트는 다음 로그인 시 키를 다시 로드하므로, 내일이면 문제가 다시 발생합니다. ~/.ssh/config 파일 내의 IdentitiesOnly 줄은 재부팅 후에도 유지되지만, 비어 있는 에이전트는 그렇지 않습니다.
키에 수명을 설정하여 에이전트가 자동으로 키를 삭제하도록 할 수도 있습니다.
ssh-add -t 1800 ~/.ssh/id_ed25519_vps키는 추가된 지 1800초 후에 삭제됩니다. 에이전트를 재시작하는 방법도 있으며, 이는 에이전트를 시작한 방식에 따라 다릅니다. 직접 실행한 ssh-agent는 ssh-agent -k 명령으로 중지할 수 있습니다. 직접 작성한 systemd 사용자 유닛으로 실행 중이라면 systemctl --user restart <unit> 명령으로 해당 유닛을 재시작하십시오. 키링 에이전트는 데스크톱 세션과 함께 재시작됩니다.
해결 방법 3: 일회성 서버 접속을 위한 단일 명령어
설정에 추가하지 않을 호스트의 경우, 명령줄에 동일한 설정을 직접 입력하십시오.
ssh -o IdentitiesOnly=yes -i ~/.ssh/id_ed25519_vps deploy@203.0.113.10-i만 단독으로 사용하는 것은 가장 흔한 잘못된 해결 방식입니다. -i는 ID 목록에 키를 추가할 뿐입니다. 에이전트의 기존 키들을 목록에서 제거하지 않으므로, 다른 모든 키가 사용자의 키보다 먼저 전송되어 결국 제한 횟수 초과로 연결이 끊어집니다. IdentitiesOnly 없이 ssh -v -i ~/.ssh/id_ed25519_vps deploy@203.0.113.10을 실행하면 에이전트 키들이 먼저 제공되는 과정을 확인할 수 있습니다. -i를 사용하려면 반드시 옆에 -o IdentitiesOnly=yes이 함께 있어야 합니다.
단일 연결에서 에이전트를 완전히 배제하려면 다음과 같이 입력하십시오.
ssh -o IdentityAgent=none -i ~/.ssh/id_ed25519_vps deploy@203.0.113.10그러면 ssh는 디스크에서 개인 키를 읽어오며, 암호가 설정되어 있다면 입력을 요구합니다.
ssh 기반의 도구들도 동일한 옵션을 지원합니다.
scp -o IdentitiesOnly=yes -i ~/.ssh/id_ed25519_vps report.tar.gz deploy@203.0.113.10:/tmp/
rsync -av -e "ssh -o IdentitiesOnly=yes -i ~/.ssh/id_ed25519_vps" ./site/ deploy@203.0.113.10:/srv/site/
GIT_SSH_COMMAND="ssh -o IdentitiesOnly=yes -i ~/.ssh/id_ed25519_vps" git clone git@example.com:team/repo.git두 번째 홉에서 오류가 발생하는 이유
ForwardAgent yes를 사용하면 연결된 서버에서 에이전트 소켓을 사용할 수 있게 됩니다. 해당 서버에서 실행되는 ssh 명령은 전달된 소켓을 통해 사용자의 모든 키가 포함된 로컬 에이전트를 사용합니다. 이것이 첫 번째 홉은 정상적으로 작동했음에도 점프 호스트에서 최종 서버로 가는 홉에서 오류가 발생할 수 있는 이유입니다. 중간 장비에서 echo $SSH_AUTH_SOCK을 실행해 보십시오. 소켓 경로가 출력되면 에이전트 전달이 가능한 상태이며, 아무것도 출력되지 않으면 전달된 에이전트가 없는 것입니다.
에이전트 전달에는 또 다른 비용이 따릅니다. 중간 장비의 root 권한을 가진 사람은 세션이 열려 있는 동안 사용자의 에이전트를 사용하여 사용자 본인인 것처럼 인증할 수 있습니다. ProxyJump은 이 두 가지 문제를 모두 방지합니다.
ssh -J deploy@jump.example.com deploy@10.0.0.5ProxyJump은 점프 호스트를 통해 연결을 열고 사용자 본인의 장비에서 최종 서버로 직접 인증을 수행합니다. 따라서 사용자의 로컬 ~/.ssh/config가 IdentitiesOnly을 포함한 모든 홉에 적용됩니다. ForwardAgent을 끄는 것은 SSH 보안 강화를 위한 표준 절차입니다.
서버에서 MaxAuthTries 값을 높여야 합니까?
일반적으로는 그렇지 않습니다. 먼저 현재 값을 확인하십시오:
sudo sshd -T | grep -i maxauthtriessshd -T는 기본값을 포함한 유효 설정을 출력하므로, sshd_config에 명시된 내용이 없더라도 실제 적용 값을 보여줍니다. Match 블록을 사용하는 경우 -C user=deploy,host=example.com,addr=203.0.113.10를 추가하십시오. 해당 블록은 연결마다 평가되므로 생략하면 확인되지 않습니다.
제한을 높이면 오작동하는 클라이언트에게 더 많은 기회를 제공한다는 좁은 의미에서는 효과가 있습니다:
MaxAuthTries 20파일을 검증하고 서비스를 다시 불러오십시오. 이때 두 번째 세션을 열어둔 상태에서 작업하십시오:
sudo sshd -t
sudo systemctl reload ssh # Debian and Ubuntu
sudo systemctl reload sshd # RHEL familyUbuntu 24.04에서 systemctl is-enabled ssh.socket이 enabled을 보고한다면, sshd는 소켓 활성화 상태입니다. 연결마다 새로운 프로세스가 시작되어 sshd_config을 다시 읽으므로, 새로운 연결은 변경 사항을 즉시 반영합니다.
이제 그 변경이 어떤 결과를 초래하는지 살펴보십시오. 클라이언트는 서버가 절대 수락하지 않을 키들을 제시하고 있습니다. 제한을 높이면 서버는 연결될 때마다, 그리고 인터넷상의 모든 비밀번호 추측 공격자에 대해 6번이 아닌 20번의 거부된 시도를 처리해야 합니다. 각 시도는 서버에서 authorized_keys 조회를 유발합니다. 올바른 키가 여전히 마지막 순서라면 본인의 로그인 속도도 느려진 상태로 유지됩니다. 에이전트에 13번째 키를 추가하면 다시 처음으로 돌아가 더 큰 숫자를 요구하게 될 뿐입니다.
정상적인 클라이언트가 실제로 여러 신원을 제시해야 하는 경우에만 값을 높이십시오. 그 외의 모든 경우에는 클라이언트 측을 수정하십시오. 모든 사용자가 설정된 키로 로그인하는 환경이라면 값을 낮추는 것이 합리적인 보안 강화 조치입니다. 숫자가 작을수록 공격자가 연결당 시도할 수 있는 횟수가 줄어들기 때문입니다.
fail2ban이 사용자를 차단하는 이유
기본 로그 수준에서 sshd는 거부된 각 공개 키를 다음과 같이 기록합니다.
Failed publickey for deploy from 203.0.113.10 port 51292 ssh2: ED25519 SHA256:AAAA...전체 에이전트를 사용하는 연결 하나는 1~2초 이내에 동일한 주소에서 위와 같은 로그를 여러 줄 생성합니다. fail2ban의 sshd jail은 sshd 실패 로그를 계산하며, findtime 내에 maxretry에 도달하면 해당 소스 주소를 차단합니다. 기본 설정된 시간 창이 짧기 때문에, 연결 오류로 인한 재시도 두 번만으로도 자신의 주소가 차단될 수 있습니다.
이때 증상이 바뀌는데, 이 부분이 사용자들을 혼란스럽게 합니다. "Too many authentication failures" 메시지가 더 이상 나타나지 않고 아무런 반응이 없게 됩니다. 방화벽이 패킷에 응답하는 대신 폐기하기 때문에 연결이 멈추고 결국 시간 초과가 발생합니다. 오류 메시지가 나오던 상황에서 시간 초과가 발생하는 것이 신호이며, 이러한 차이점은 SSH 연결 거부와 연결 시간 초과의 차이에서 다룹니다.
제공자의 콘솔이나 다른 주소를 사용하여 jail 상태를 확인하고 차단을 해제하십시오.
sudo fail2ban-client status sshd
sudo fail2ban-client set sshd unbanip 203.0.113.10클라이언트 문제를 해결하는 동안 jail.local의 ignoreip에 자신의 주소를 추가하고, 작업이 완료되면 다시 제거하십시오. jail 자체에 대한 설정은 Ubuntu 24.04용 fail2ban 가이드에 설명되어 있습니다.
문제가 재발하지 않도록 한 번에 조치하는 방법
모든 서버에 ~/.ssh/config 내의 고유한 Host 블록을 할당하고, HostName, User, IdentityFile, IdentitiesOnly yes을 설정하십시오. 이렇게 하면 ssh vps 명령어를 짧게 입력할 수 있고, 정확히 하나의 키만 제공하며, 에이전트가 아무리 가득 차더라도 MaxAuthTries 오류가 발생하지 않습니다. 또한 다른 문제가 발생했을 때 확인하기 쉽도록 ssh -v 출력 내용을 간결하게 유지해 줍니다.
FAQ
"Too many authentication failures" 오류를 지금 바로 해결하려면 어떻게 해야 합니까?
모든 키를 제공하는 대신 하나의 키만 사용하도록 설정합니다. 즉시 연결하려면 ssh -o IdentitiesOnly=yes -i ~/.ssh/your_key user@host를 실행하십시오. 영구적인 해결을 위해서는 ~/.ssh/config에 블록을 추가하고, HostName, User, IdentityFile로 해당 키를 지정한 다음, IdentitiesOnly yes를 설정하고 chmod 600 ~/.ssh/config을 적용하십시오. ssh -v로 확인하면 해당 호스트에 대해 하나의 Offering public key: 줄이 표시되어야 합니다.
ssh -i를 사용해도 왜 다른 키들이 계속 제공됩니까?
-i은 목록에 ID를 추가할 뿐, 목록을 제한하지 않기 때문입니다. ssh-agent에 로드된 키들은 여전히 목록에 남아 있으며, 종종 사용자의 키보다 먼저 제공되므로 서버가 사용자의 키에 도달하기 전에 MaxAuthTries 제한에 걸릴 수 있습니다. -o IdentitiesOnly=yes은 ssh가 지정한 ID만 사용하도록 제한하는 옵션입니다. -i과 -o IdentitiesOnly=yes을 함께 사용하거나, 해당 연결에서 에이전트를 완전히 무시하려면 -o IdentityAgent=none를 사용하십시오.
이 문제를 해결하기 위해 서버의 MaxAuthTries 값을 늘려야 합니까?
거의 모든 경우에 아니오입니다. 클라이언트는 서버가 절대 수락하지 않을 키들을 보내고 있으며, 제한을 늘리면 서버는 연결당 더 많은 거부된 키를 평가해야 합니다. 이는 모든 클라이언트와 서버에 도달하는 모든 무차별 대입 공격에 영향을 미칩니다. 또한 에이전트에 키가 하나 더 추가되는 즉시 다시 문제가 발생합니다. 궁금하다면 sudo sshd -T | grep -i maxauthtries으로 유효 값을 확인한 뒤, IdentitiesOnly을 사용하여 클라이언트 측에서 해결하십시오.
지난달까지 잘 작동하던 서버에서 왜 갑자기 이런 문제가 발생합니까?
에이전트가 커졌기 때문입니다. ~/.ssh/config의 AddKeysToAgent yes는 사용하는 모든 키를 로드된 상태로 유지하며, 데스크톱 키링 에이전트도 로그인 시 자동으로 키를 로드합니다. 로드된 키의 개수가 서버의 MaxAuthTries를 초과하면, 키 제공 순서가 뒤에 있는 서버들은 인증에 실패하기 시작합니다. ssh-add -l를 실행하여 키 개수를 확인하고 서버의 제한 값과 비교하십시오.
이 문제로 인해 fail2ban에 의해 IP 주소가 차단될 수 있습니까?
네, 가능합니다. 거부된 각 키는 서버 로그에 Failed publickey for ... 줄을 생성하므로, 하나의 연결만으로도 몇 초 만에 해당 주소에서 여러 번의 실패가 기록될 수 있습니다. fail2ban의 sshd 감옥은 findtime 내에 maxretry에 도달하면 해당 주소를 차단합니다. 패킷이 응답 대신 드롭되면서 오류가 연결 끊김 및 타임아웃으로 변하는 것이 특징입니다. 콘솔에서 sudo fail2ban-client set sshd unbanip <your address>을 사용하여 차단을 해제하고, 다시 연결하기 전에 클라이언트 설정을 수정하십시오.