SSH: Permission denied (publickey)
안녕하세요, BlueByte입니다. "Permission denied (publickey)"는 벽처럼 느껴지지만, verbose로 물어보면 SSH가 이유를 정확히 알려줍니다 — 추측할 필요 없습니다. 오늘은 클라이언트가 실제로 무엇을 내밀었고 서버가 뭐라 했는지 읽고, 실패한 그 하나를 고치는 순서로 가보겠습니다.
이 메시지가 뜻하는 것
셸을 받기 전에 연결이 끊깁니다:
git@github.com: Permission denied (publickey).서버가 공개키 인증을 제안했고, 클라이언트가 보낸 키 중 아무것도 받아들여지지 않았으며, 비밀번호 대체가 없었습니다. 셋 중 무엇이 실패했는지가 해결을 결정하니 — 추측하지 말고 SSH에 물어보세요.
보통 실패하는 세 가지
거의 모든 경우가 이 중 하나입니다:
- 키가 에이전트에 로드되지 않음, 또는 키 파일이 SSH가 찾는 위치에 없음.
- 클라이언트가 서버가 신뢰하는 것과 다른 키를 보냄 — 키가 여럿일 때 에이전트가 엉뚱한 걸 먼저 내미는 경우 흔함.
- 서버가 권한 때문에 거부 —
~/.ssh나 개인키 파일을 남이 읽을 수 있어 SSH가 무시함.
SSH에게 어느 쪽인지 묻기
verbose로 연결해 어떤 키를 내밀고 서버가 어떻게 답하는지 읽습니다:
ssh -vT git@github.comOffering public key: ... 뒤 서버 응답을 보세요. 키를 안 내밀면 로드 안 된 것, 내밀었는데 거부되면 엉뚱한 키이거나 서버가 신뢰 안 하는 것, Permissions ... are too open 경고면 파일 모드 문제입니다. verbose 추적이 추측을 없앱니다.
실패한 그 하나를 고치기
- 키를 안 내밀면 — 에이전트에 추가:
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519- 엉뚱한 키를 내밀면 — 호스트별로 올바른 키를 지정:
# ~/.ssh/config
Host github.com
IdentityFile ~/.ssh/id_ed25519
IdentitiesOnly yes- 권한으로 거부되면 — 조입니다; SSH는 남이 읽을 수 있는 키를 무시합니다:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519실제 사례: 에이전트가 옛 키를 내밀다
SSH로 clone하는데 Permission denied (publickey)가 납니다. ssh -vT git@github.com이 옛 키 id_rsa를 내밀고 서버가 거부하며, 더 새로운 id_ed25519엔 닿지도 못하는 걸 보여줍니다. 그러니 키 부재가 아니라 키 선택 문제입니다. Host github.com 블록에 IdentityFile ~/.ssh/id_ed25519와 IdentitiesOnly yes를 추가하고 ssh -vT를 다시 돌리니 이번엔 ed25519 키만 내밀고 서버가 "successfully authenticated"로 받아들입니다. clone이 됩니다.
키가 받아들여지는지 확인
셸을 열지 않고 인증 경로를 테스트:
ssh -T git@github.comHi <user>! You've successfully authenticated 같은 인사(그 뒤 연결을 닫더라도)가 나오면 키가 받아들여진 것입니다.
다시 겪지 않으려면
에이전트가 서버에 모든 키를 던져 시도 한도에 걸리지 않도록 SSH 설정에 IdentitiesOnly yes를 두고, 새 기기의 공개키를 서비스에 한 번 등록하고, ~/.ssh 권한을 조여 dotfiles 동기화가 이를 풀지 않게 하세요.
연결·호스트키 오류와의 구분
Permission denied (publickey)는 연결 후 인증 실패입니다. Connection refused나 Connection timed out은 더 이르게 — 서버 도달 불가나 22번 포트에 리스너 없음 — 이고, Host key verification failed는 서버 키가 바뀐 전혀 다른 문제입니다. publickey 오류를 만나면 ssh -vT부터 돌리세요 — 답은 거의 항상 그 추적에 있습니다.
관련 질문
ssh-add가 'Could not open a connection to your authentication agent'라고 합니다.
이 셸에서 에이전트가 돌고 있지 않습니다. 먼저 eval "$(ssh-agent -s)"로 시작한 뒤 ssh-add 하세요.
제 사용자로는 되는데 sudo로는 안 됩니다. 왜죠?
sudo는 자체 ~/.ssh와 에이전트를 가진 root로 실행됩니다. SSH 명령에 sudo를 쓰지 않거나, root에 키를 따로 설정하세요.
올바른 키를 추가했는데 서버가 계속 거부합니다.
짝이 되는 공개키가 서버나 계정에 등록됐는지, 그리고 HTTPS가 아니라 SSH 리모트 URL(git@host:org/repo.git)을 쓰는지 확인하세요.
IdentitiesOnly가 왜 중요한가요?
없으면 에이전트가 가진 모든 키를 내밉니다. 인증 시도를 제한하는 서버는 올바른 키에 닿기 전에 당신을 막을 수 있습니다. IdentitiesOnly는 설정한 키만 보냅니다.
ssh -vT가 'Too many authentication failures'를 보입니다.
에이전트가 올바른 키 전에 너무 많은 키를 내민 것입니다. IdentitiesOnly yes를 설정하고 IdentityFile을 올바른 키로 지정해 그것만 시도되게 하세요.
참고 자료
Haneul Seo
Infrastructure engineer · 10+ years running Linux fleets
같은 카테고리 다른 글
systemd: Start request repeated too quickly
systemd는 StartLimitIntervalSec(기본 10초) 안에 StartLimitBurst(기본 5회)보다 많이 시작된 유닛의 시작을 거부하며, Restart=도 이 제한에 포함됩니다. 기본 RestartSec 100ms로는 크래시하는 서비스가 1초도 안 되어 다섯 번을 소진합니다. 저널에서 진짜 크래시를 찾아 고치고, reset-failed를 실행한 뒤, RestartSec로 재시작에 여유를 주세요.
SSH: Received disconnect ... Too many authentication failures
agent가 서버가 허용하는 것보다 많은 키를 내밀고 있습니다. sshd가 들여다보는 공개키 하나하나가 MaxAuthTries 시도를 한 번씩 소모하고 — 기본 6회, 하드닝된 호스트에서는 3회인 경우가 많습니다 — 정작 맞는 키는 차례가 오기 전에 연결이 끊깁니다. IdentitiesOnly=yes와 명시적 IdentityFile로 키 하나를 고정하면 시도 횟수가 1로 떨어집니다.
Active Directory: 복제가 error 1722(The RPC server is unavailable)로 실패
RPC는 하위 계층이 연결에 실패했을 때 1722(0x6ba, RPC_S_SERVER_UNAVAILABLE)를 보고합니다. 따라서 진짜 원인은 RPC 자신이 아니라 DNS, 차단된 포트, 두 도메인 컨트롤러 중 한쪽의 호스트 설정입니다. repadmin이 어느 파트너가 실패하는지 알려주고, dcdiag /test:dns가 이름 해석을 배제하며, Test-NetConnection과 동적 포트 범위가 방화벽 문제를 가릅니다. 가장 흔한 실수는 TCP 135만 허용하고 49152–65535는 막아 둔 규칙입니다.
Windows Server RDS: The remote session was disconnected because there are no Remote Desktop License Servers available to provide a license
120일 RD Licensing 유예 기간이 끝났는데 세션 호스트가 쓸 수 있는 라이선스 서버가 없어 세션을 거부하는 상황입니다. GetGracePeriodDays 의 DaysLeft 가 0 이고 SpecifiedLSList 가 비어 있으면 몇 초 만에 확인됩니다. 해결은 활성화된 라이선스 서버와, 호스트 버전을 감당할 만큼 새 CAL 입니다. 2019 CAL 은 2022 세션 호스트를 서비스하지 못합니다. 여기에 배포 또는 Licensing 정책 설정과 두 서버 사이의 RPC 포트 개방이 따라옵니다.
Windows 11: NAS 공유 폴더를 열 때 "조직의 보안 정책이 인증되지 않은 게스트 액세스를 차단" (0x80070035)
Windows 10 Enterprise/Education/Pro for Workstations, Windows 11 Pro, Windows Server 2019 이후의 SMB 클라이언트는 기본적으로 게스트 로그온을 거부하고, Windows 11 24H2 Enterprise/Pro/Education 은 게스트 세션이 할 수 없는 SMB 서명까지 요구합니다. 그래서 게스트 접근만 제공하는 NAS 공유는 'block unauthenticated guest access' 대화상자, Error code 0x80070035, 또는 System error 3227320323 으로 실패하고, SmbClient/Security 로그에 Event ID 31017 'Rejected an insecure guest logon' 이 남습니다. Microsoft 가 권하는 해결은 NAS 에 실제 계정을 만들고 펌웨어에서 서명을 지원하게 하는 것입니다. Set-SmbClientConfiguration -EnableInsecureGuestLogons $true(24H2 는 -RequireSecuritySignature $false 까지)는 비상구이며, 그 클라이언트의 서명과 암호화를 포기하는 대가가 있습니다.
Ubuntu/Debian: E: Could not get lock /var/lib/dpkg/lock-frontend — 누가 쥐고 있고 어떻게 기다리는지
다른 패키지 관리자, 대개 부팅 때 persistent systemd 타이머로 발화한 Ubuntu 의 unattended-upgrades 가 여러분의 apt-get 이 도는 동안 dpkg 프런트엔드 락을 쥐고 있는 것입니다. Ubuntu 는 apt 바이너리에만 binary::apt::DPkg::Lock::Timeout "120" 을 실어 두어서 apt-get 은 즉시 포기하고 apt 는 기다립니다. 메시지의 PID 를 읽고, 실행이 끝나게 두거나 apt-get 에 -o DPkg::Lock::Timeout=<초> 를 주고, dpkg --configure -a 는 실제로 중단된 실행 뒤에만 쓰고, 락 파일은 절대 지우지 마세요. 보유자가 종료하면 커널이 푸는 fcntl 락입니다.