환경 OpenSSH (sshd StrictModes 기본 yes) · Ubuntu·RHEL 계열 · 2026-10-16 확인
authorized_keys 에 키를 분명히 붙여 넣었는데 접속이 계속 거부된다면 키보다 권한을 먼저 의심해 볼 만합니다. sshd 는 홈이나 .ssh 에 그룹 쓰기 권한 하나만 열려 있어도 키 파일을 읽지 않거든요. ssh -v 로 키가 나가는지 보고, 서버 로그에서 거부 사유를 찾아 권한을 고치는 순서대로 짚어 봅니다.
목표와 시작 전에 확보해 둘 것
목표는 공개키 로그인이 왜 거부되는지 서버가 남긴 이유를 찾고, 그 이유만 정확히 고치는 것이다. 권한을 이것저것 바꿔 보다 우연히 되는 식으로 끝내면 다음에 같은 일로 또 헤맨다.
먼저 서버에 들어갈 다른 길이 하나 있어야 한다. 비밀번호 로그인이든, 다른 sudo 계정이든, 클라우드 콘솔의 직렬 콘솔이든 상관없다. 서버 로그를 읽고 권한을 고치려면 결국 안에 들어가야 한다. 지금 열려 있는 세션이 있다면 끝날 때까지 닫지 말자.
클라이언트 쪽에서는 어떤 키 파일로 붙으려는지 알아 둔다. 기본 키(id_ed25519, id_rsa 등)인지, ~/.ssh/config 에 IdentityFile 로 따로 적은 키인지에 따라 확인할 곳이 다르다.
# 클라이언트: 어떤 키를 쓰는지
ssh -G deploy@server.example.com | grep -i identityfile
# 서버(다른 경로로 접속해서): 대상 계정과 홈 위치
getent passwd deploy
들어갈 다른 길과, 클라이언트가 쓰는 키부터 확인한다
ssh -v 로 키가 서버까지 가는지 본다
첫 단계는 문제가 클라이언트에 있는지 서버에 있는지 가르는 일이다. ssh 에 -v 를 붙이면 인증 과정이 한 줄씩 찍힌다. 여기서 Offering public key 줄이 보이는지를 본다.
Offering public key 줄이 아예 없다면 키가 서버로 나가지도 않은 것이다. 이때는 서버를 볼 필요가 없다. 개인키 파일 권한이 너무 열려 있으면 ssh 는 그 키를 그냥 건너뛴다. 남이 읽을 수 있는 개인키는 쓰지 않는다는 게 ssh 의 동작이다. chmod 600 으로 잠그고 다시 해 본다.
키를 제안했는데 Authentications that can continue: publickey 가 다시 나오고 끝난다면, 서버가 그 키를 받아 주지 않은 것이다. 이제부터는 서버 쪽 이야기다. 서버는 거절 이유를 클라이언트에게 알려 주지 않는다. 이유는 서버 로그에만 남는다.
ssh -v deploy@server.example.com 2>&1 | grep -E 'Offering|Authentications that|denied'
# 키가 아예 안 나간다면 개인키 권한부터
ls -l ~/.ssh/id_ed25519
chmod 600 ~/.ssh/id_ed25519
Offering public key 가 있으면 서버 쪽, 없으면 클라이언트 쪽 문제다
서버는 거절 이유를 클라이언트에 말해 주지 않는다. 이유는 서버 로그에만 있다.
서버 로그에서 거부 사유를 찾는다
다른 경로로 서버에 들어가서 sshd 로그를 본다. 우분투·데비안은 ssh, RHEL 계열은 sshd 라는 이름으로 남는다. 파일로 보는 서버라면 각각 /var/log/auth.log 와 /var/log/secure 다. 접속을 한 번 더 시도한 직후에 보면 찾기 쉽다.
권한 문제라면 Authentication refused: bad ownership or modes for directory /home/deploy 같은 줄이 있다. directory 뒤에 나오는 경로가 바로 고칠 곳이다. file 로 나오면 authorized_keys 자체가 문제다.
이 줄이 안 보이면 다른 원인이다. 사용자 이름이 틀렸거나, AllowUsers 같은 설정에서 막혔거나, 키 줄이 중간에 줄바꿈으로 잘린 경우가 흔하다. sshd -T 로 지금 적용된 설정값을 뽑아 보면 AuthorizedKeysFile 위치와 StrictModes 값을 한 번에 볼 수 있다.
sudo journalctl -u ssh -u sshd --since '10 min ago' | grep -iE 'refused|bad ownership|invalid user'
# 파일 로그라면
sudo grep -i 'refused' /var/log/auth.log # RHEL 계열은 /var/log/secure
# 실제 적용 중인 설정
sudo sshd -T | grep -iE 'strictmodes|authorizedkeysfile|pubkeyauthentication'
bad ownership or modes 뒤의 경로가 고칠 자리다
StrictModes 가 무엇을 보는지 알고 고친다
sshd 의 StrictModes 는 기본값이 yes 다. 로그인을 받기 전에 사용자의 파일과 홈 디렉터리의 소유자와 권한을 검사한다. authorized_keys, 그걸 담은 .ssh, 그리고 홈 디렉터리 중 하나라도 다른 사용자가 쓸 수 있으면 그 파일을 쓰지 않는다. 남이 키를 끼워 넣을 수 있는 파일은 믿지 않겠다는 뜻이다.
기준은 쓰기 권한이다. 그룹이나 기타 사용자에게 w 가 하나라도 있으면 걸린다. 반대로 읽기는 상관없다. 홈이 755 이고 authorized_keys 가 644 여도 통과하지만, 홈이 775 면 막힌다. useradd 나 배포 스크립트가 그룹 쓰기를 열어 두는 경우가 많아서 생각보다 자주 터진다. 소유자도 본다. 해당 사용자나 root 가 아닌 계정이 주인이면 마찬가지로 거부한다.
고칠 때는 로그에 찍힌 경로를 기준으로, 위에서부터 차례로 잡는다. 홈은 그룹·기타의 쓰기만 빼고, .ssh 는 700, authorized_keys 는 600 으로 둔다. root 로 키를 붙여 넣었다면 소유자가 root 로 남아 있을 수 있으니 chown 도 같이 한다.
# 홈부터 파일까지 소유자·권한을 한 번에
namei -l /home/deploy/.ssh/authorized_keys
sudo chmod go-w /home/deploy
sudo chmod 700 /home/deploy/.ssh
sudo chmod 600 /home/deploy/.ssh/authorized_keys
sudo chown -R deploy:deploy /home/deploy/.ssh
쓰기 권한만 닫고, 소유자를 그 사용자로 맞춘다
StrictModes 는 읽기가 아니라 쓰기를 본다. 그룹 쓰기 하나만 열려 있어도 키 파일을 통째로 무시한다.
다시 붙어서 확인한다
권한을 고쳤다고 sshd 를 재시작할 필요는 없다. StrictModes 검사는 접속할 때마다 새로 하기 때문이다. 바로 클라이언트에서 다시 붙어 본다.
-v 출력에 Server accepts key 가 나오고 셸이 열리면 끝이다. 서버 로그에도 Accepted publickey for deploy 줄이 남는다. 이 두 가지를 같이 봐 두면 나중에 같은 증상이 왔을 때 어디까지 정상이었는지 바로 가늠한다.
여러 계정이 같은 문제를 겪는다면 계정을 만드는 쪽을 고쳐야 한다. 홈을 만들 때 쓰는 umask 나 스크립트의 chmod 줄을 찾아서, 다음 계정부터는 처음부터 맞는 권한으로 생기게 한다.
ssh -v deploy@server.example.com 2>&1 | grep -E 'Server accepts key|Authenticated'
# 서버 쪽
sudo journalctl -u ssh -u sshd --since '5 min ago' | grep 'Accepted publickey'
클라이언트와 서버 양쪽에서 성공 줄을 확인한다
자주 헛짚는 자리
가장 흔한 실수는 StrictModes no 로 바꿔서 끝내는 것이다. 접속은 되지만 다른 사용자가 키를 바꿔 끼울 수 있는 상태를 그대로 열어 두는 셈이다. 검사를 끌 게 아니라 권한을 고쳐야 한다.
홈을 700 으로 막아 버리는 것도 조심한다. sshd 는 통과하지만, 웹 서버가 그 계정 아래 파일을 읽어야 하는 구성이라면 사이트가 깨진다. 고칠 건 그룹·기타의 쓰기 권한이지 읽기와 실행이 아니다. chmod go-w 로 쓰기만 빼는 이유가 여기 있다.
RHEL 계열에서 권한이 다 맞는데도 계속 막힌다면 SELinux 컨텍스트를 의심한다. 다른 곳에서 복사해 온 .ssh 는 컨텍스트가 어긋나 있을 수 있고, restorecon 으로 기본값을 되돌리면 풀린다. 이 경우 sshd 로그엔 권한 메시지가 안 나오고 감사 로그 쪽에 거부 기록이 남는다.
# RHEL 계열, 권한은 맞는데 계속 막힐 때
ls -Z /home/deploy/.ssh/authorized_keys
sudo restorecon -R -v /home/deploy/.ssh
SELinux 를 쓰는 서버라면 컨텍스트까지 확인한다
조치 후 확인할 것
- ssh -v 출력에 Offering public key 다음으로 Server accepts key 가 나온다
- namei -l 로 본 홈·.ssh·authorized_keys 어디에도 그룹·기타 쓰기(w)가 없다
- .ssh 는 700, authorized_keys 는 600, 소유자는 그 계정이다
- sshd -T 의 strictmodes 가 yes 그대로다
- 서버 로그에 Accepted publickey 줄이 남는다
Permission denied (publickey) 는 키가 틀렸다는 말처럼 보여서 키부터 다시 만들기 쉽다. 그런데 이 메시지는 서버가 이유를 감춘 채 거절했다는 뜻일 뿐이다. ssh -v 로 키가 나갔는지 보고, 서버 로그에서 bad ownership or modes 를 찾고, 거기 찍힌 경로의 쓰기 권한만 닫는다. 이 순서로 가면 키를 새로 만들 일도, StrictModes 를 끌 일도 없다.
'복사금지 블로그 짜증나서 만든 개발문서' 카테고리의 다른 글
| 도커 서버 디스크가 꽉 찼다면, 컨테이너 로그가 무제한으로 쌓이고 있을 수 있습니다 (0) | 2026.10.02 |
|---|---|
| sudo 만 붙이면 command not found, 환경변수까지 사라질 때 — sudo 질문 6가지 (0) | 2026.09.25 |
| cron 배치가 겹쳐 돌아 알림이 세 번 나갔던 밤, flock 한 줄이 없어서 (0) | 2026.09.18 |
| 재부팅하면 서비스가 안 올라오는 서버, 내리기 전에 훑는 목록 (0) | 2026.09.08 |
| 리눅스 load average 정리 — CPU 사용률이 아니라 줄 선 프로세스 수입니다 (0) | 2026.09.05 |