> ## Content Index
> Fetch the complete content index at: https://mlog.me/llms.txt
> Use this file to discover other available public pages before exploring further.

# 서버 보안 점검 3편: SSH 비밀번호 차단과 root 로그인 정책
- URL: https://mlog.me/server-security-check-ssh-password-root-login/
- Published: 2026-08-24T10:31:07.000Z
- Updated: 2026-09-08T16:02:48.000Z
- Description: SSH 실제 적용 설정을 확인하고 비밀번호 인증, 공개키, root 로그인, 계정 목록을 성공·부분 성공·확인 필요로 나눠 판정합니다.
- Author: mLog
- Tags: 보안, SSH, Linux, Ubuntu

실제 SSH 유효 설정을 확인했을 때 `PasswordAuthentication no`와 `PubkeyAuthentication yes`는 의도한 방향이었다. 그런데 root 설정은 `PermitRootLogin without-password`였으므로 root의 공개키 로그인까지 막힌 상태는 아니었다. 비표준 포트를 쓰고 외부 점검에서 `filtered`가 나왔다는 사실만으로는 드러나지 않는 차이였다.

이 차이를 기준으로 비밀번호 인증 설정, root 직접 로그인, 로그인 가능한 계정을 따로 판정했다. 별도 세션에서의 실제 재접속 성공 기록은 없으므로 공개키 인증이 허용된 설정과 접속 시험 성공도 구분한다. 이 글은 확인한 유효값을 출발점으로, 접속을 잃지 않으면서 다음에 무엇을 검증해야 하는지 정리한 기록이다.

## 세 줄 요약

- `PasswordAuthentication no`와 `PubkeyAuthentication yes`가 확인돼 비밀번호 대신 공개키를 사용하는 기본 방향은 맞았다.
- `PermitRootLogin without-password`는 root 로그인을 차단하는 값이 아니라 **root의 공개키 로그인을 허용**하는 설정이다.
- `MaxAuthTries 6`은 Ubuntu 24.04 문서 기준 기본값이므로 별도 강화 성공으로 계산하지 않았다.

## 실제 점검 결과

공개용 원고에서는 실제 포트, 호스트명과 계정명을 치환했다.

| 항목        | 보존된 설정·결과                        | 판정    | 해석                                  |
| --------- | -------------------------------- | ----- | ----------------------------------- |
| SSH 포트    | 비표준 포트 사용                        | 보조 조치 | 자동 스캔 소음을 줄일 수 있지만 인증 강화는 아님        |
| 외부 관찰     | SSH 경로가 filtered                 | 부분 성공 | 점검 출발지에서 직접 상태를 판별할 수 없었음           |
| 비밀번호 인증   | PasswordAuthentication no        | 성공    | SSH password 인증 비활성화 설정 확인          |
| 공개키 인증    | PubkeyAuthentication yes         | 성공    | 공개키 인증 허용 설정 확인                     |
| root 로그인  | PermitRootLogin without-password | 부분 성공 | root password는 막지만 root key 로그인은 허용 |
| 인증 시도 횟수  | MaxAuthTries 6                   | 기준값   | 기본값이므로 추가 강화로 보지 않음                 |
| 로그인 가능 계정 | 로그인 셸을 가진 계정이 복수                 | 확인 필요 | 각 계정의 필요성·키·잠금 상태 재검토 필요            |
| 실제 재접속 시험 | 보존된 결과 없음                        | 확인 필요 | 설정 확인과 실제 로그인 성공을 혼동하지 않음           |

`without-password`는 현재 OpenSSH 문서에서 `prohibit-password`의 이전 별칭이다. 이 값은 root의 비밀번호와 keyboard-interactive 인증을 막지만 공개키 로그인을 허용한다. root 로그인을 완전히 막으려면 `PermitRootLogin no`가 필요하다.

그러나 원격 서버에서 이 값을 즉시 바꾸는 것은 위험하다. 작동하는 비root sudo 계정과 공개키 접속을 **별도 세션에서 먼저 검증**하지 않으면 스스로 접속을 차단할 수 있다.

## 1\. 설정 파일보다 실제 적용값을 확인한다

Ubuntu의 SSH 구성은 기본 파일 외에 `Include` 파일과 `Match` 블록의 영향을 받을 수 있다. 주석을 검색하는 것보다 `sshd -T`로 유효 구성을 확인한다.

```bash
sudo sshd -T |
  grep -E '^(port|passwordauthentication|kbdinteractiveauthentication|pubkeyauthentication|permitrootlogin|maxauthtries|allowusers|allowgroups) '

```

`rg`를 쓰는 환경이라면 다음과 같다.

```bash
sudo sshd -T |
  rg '^(port|passwordauthentication|kbdinteractiveauthentication|pubkeyauthentication|permitrootlogin|maxauthtries|allowusers|allowgroups) '

```

공개 글에는 실제 포트와 사용자 목록을 넣지 않고 다음처럼 상태만 남긴다.

```text
port=<SSH_PORT>
passwordauthentication=no
pubkeyauthentication=yes
permitrootlogin=prohibit-password
maxauthtries=6

```

특정 사용자·주소에 적용되는 `Match` 규칙이 있다면 조건을 지정해 확인할 수 있다.

```bash
sudo sshd -T \
  -C user='<ADMIN_USER>',host='<CLIENT_HOSTNAME>',addr='<CLIENT_IP>' |
  grep -E '^(passwordauthentication|kbdinteractiveauthentication|pubkeyauthentication|permitrootlogin) '

```

`host`에는 서버 이름이 아니라 접속 클라이언트의 해석된 호스트명을 넣고, `addr`에는 접속 출발지 IP를 넣는다. 서버의 수신 주소·포트에 따른 `Match` 조건도 검사하려면 `laddr`와 `lport`를 실제 접속 조건으로 함께 지정한다. 실제 사용자와 클라이언트 IP가 포함된 출력은 공개하지 않는다.

## 2\. 비밀번호 인증과 keyboard-interactive를 구분한다

점검에서 `PasswordAuthentication no`는 확인됐다. 이는 중요한 성공이지만 PAM을 사용하는 환경에서는 keyboard-interactive가 비밀번호와 비슷한 인증 경로로 작동할 수 있다. 따라서 다음 항목도 함께 본다.

```bash
sudo sshd -T |
  grep -E '^(passwordauthentication|kbdinteractiveauthentication|usepam) '

```

운영 정책이 공개키 전용이라면 `PasswordAuthentication` 한 줄만으로 “모든 비키 인증이 완전히 차단됐다”고 단정하지 않는다. 실제 클라이언트에서 비밀번호 강제 시험을 하되, 계정 잠금 정책과 운영 영향에 주의한다.

```bash
ssh \
  -o PreferredAuthentications=password \
  -o PubkeyAuthentication=no \
  -p '<SSH_PORT>' \
  '<ADMIN_USER>@<APP_HOST>'

```

기대 결과는 비밀번호 인증이 제공되지 않아 접속이 거부되는 것이다. 이 테스트 결과는 보존된 기록에 없으므로 현재 글에서는 `확인 필요`로 남긴다.

## 3\. root 공개키 로그인을 끄기 전 준비한다

현재 상태를 공개용으로 정리하면 다음과 같다.

```text
root_password_login=blocked
root_public_key_login=allowed

```

더 강한 목표가 root 직접 로그인 전면 차단이라면 다음 절차를 따른다.

1. 비root 관리자 계정에 승인한 공개키가 있는지 확인한다.
2. 새 터미널에서 그 계정으로 실제 SSH 로그인한다.
3. `sudo -v`와 필요한 운영 명령이 정상인지 확인한다.
4. 기존 SSH 세션을 닫지 않은 상태에서 설정을 변경한다.
5. `sshd -t`가 성공한 뒤 reload한다.
6. 또 다른 새 세션에서 재접속을 확인한 뒤 기존 세션을 종료한다.

목표 설정은 다음과 같다.

```text
PermitRootLogin no

```

문법 검사와 reload 예시는 다음과 같다.

```bash
sudo sshd -t
sudo systemctl reload ssh

```

이 글은 변경 명령을 실제로 적용했다고 주장하지 않는다. 보존된 결과는 root key 로그인이 허용된 상태까지이며, 전면 차단은 운영 전제를 검증한 뒤 수행할 후속 조치다.

## 4\. 로그인 가능한 계정을 목록으로 점검한다

로그인 셸을 가진 계정을 확인한다.

```bash
getent passwd |
  awk -F: '$7 !~ /(nologin|false)$/ {print $1 ":" $7}'

```

sudo 그룹도 확인한다.

```bash
getent group sudo

```

실제 점검에서는 root, 클라우드 이미지 기본 계정, 배포·관리 계정 등 복수 계정이 확인됐다. 공개 글에는 실명을 적지 않고 다음 질문만 남긴다.

- 이 계정은 현재 운영에 필요한가
- 홈 디렉터리의 `authorized_keys`는 승인된 키만 포함하는가
- 사용하지 않는 기본 계정은 잠겨 있는가
- sudo 권한이 꼭 필요한 계정에만 있는가
- 퇴역한 노트북·자동화의 키가 남아 있지 않은가

키 전문과 fingerprint는 게시하지 않는다. 운영자 로컬에서는 fingerprint만 비교할 수 있다.

```bash
find /home -xdev -path '*/.ssh/authorized_keys' -type f -print

```

이 명령의 출력도 실제 사용자명과 홈 경로를 노출하므로 공개하지 않는다.

## 5\. 리스닝 주소와 방화벽을 다시 대조한다

SSH가 어느 주소에 바인딩됐는지 확인한다.

```bash
sudo ss -lntp |
  grep -E 'sshd|:<SSH_PORT>[[:space:]]'

```

실제 셸에서는 `<SSH_PORT>`를 운영값으로 바꾼다. 공용망 SSH가 필요 없다면 사설 오버레이 주소에만 바인딩하거나, 클라우드·호스트 방화벽에서 승인한 소스만 허용하는 방안을 검토한다.

외부 스캔의 `filtered` 결과는 공격 표면 축소에 긍정적이지만 다음을 증명하지는 않는다.

- 다른 출발 네트워크에서도 같은지
- IPv6에도 같은 규칙이 적용되는지
- 클라우드 방화벽과 호스트 방화벽 중 어느 계층이 차단했는지
- SSH daemon이 내부에서 모든 인터페이스에 리스닝 중인지

## 6\. 로그는 IP 대신 이벤트 개수만 공개한다

SSH 로그에는 사용자명과 원격 IP가 포함된다. 공개용 점검에서는 원문 대신 이벤트 종류를 집계한다.

```bash
sudo journalctl -u ssh \
  --since '24 hours ago' \
  --no-pager |
  grep -Eo 'Failed password|Invalid user|Accepted publickey' |
  sort |
  uniq -c

```

이 집계는 공격 여부를 확정하는 증거가 아니라 변화 추세를 보는 자료다. 정확한 원인 분석은 운영자 로컬에서 시간대, 소스 주소, 대상 계정과 방화벽 기록을 대조해야 한다.

## 이번 점검의 결론

비밀번호 인증 비활성화와 공개키 인증 활성화는 성공으로 판정할 수 있다. 외부에서 SSH 경로가 직접 관측되지 않은 점도 공격 표면 축소에는 긍정적이다.

하지만 다음 이유로 “SSH 완전 강화 완료”라고 하지는 않는다.

- root 공개키 로그인이 여전히 허용됨
- `MaxAuthTries 6`은 추가 강화가 아닌 기본 수준
- 로그인 셸을 가진 복수 계정의 필요성·키 상태가 미확인
- 별도 세션을 이용한 공개키 재접속 성공 기록이 보존되지 않음
- keyboard-interactive와 IPv6 경로의 최종 결과가 없음

후속 작업의 우선순위는 비root sudo 접속 검증, 불필요 계정 정리, root 직접 로그인 차단 검토, 방화벽 소스 제한, 재접속 시험 순서다.

## 다음 글

- 이전 편: **[서버 보안 점검 2편: Nginx Proxy Manager와 Authelia 접근 제어](https://mlog.me/server-security-check-npm-authelia-access-control/)**
- 다음 편: **[서버 보안 점검 4편: Portainer·Agent·Docker 관리면](https://mlog.me/portainer-docker-management-security-check/)**
- 함께 읽기: **[Ubuntu에서 ESM·kept back을 해석하는 방법](https://mlog.me/ubuntu-apt-upgrade-esm-phased-kept-back/)**

## 공식 문서

- [Ubuntu 24.04 sshd\_config(5)](https://manpages.ubuntu.com/manpages/noble/man5/sshd%5Fconfig.5.html?ref=mlog.me)
- [Ubuntu 24.04 sshd(8)](https://manpages.ubuntu.com/manpages/noble/man8/sshd.8.html?ref=mlog.me)
- [Nmap Port Scanning Basics](https://nmap.org/book/man-port-scanning-basics.html?ref=mlog.me)