# SSHD Hardening (drop-in) ## 언제 쓰는가 - 인터넷에 노출된 SSH(:22)를 가진 리눅스 서버를 막 띄웠을 때, 최소한의 기본 방어선을 세팅하고 싶을 때 - 배포판 기본 `/etc/ssh/sshd_config`를 건드리지 않고 설정을 추가/오버라이드하고 싶을 때 (업데이트로 덮어써질 위험 회피) - OCI/AWS 같은 클라우드 Always Free VM을 띄우자마자 brute-force 로그인 시도가 들어오기 시작할 때 (실측: 하루 수백 건) ## 핵심 구조 - **Drop-in 방식**: `/etc/ssh/sshd_config.d/99-hardening.conf` — 파일명 `99-` 접두사로 마지막에 로드되어 override 보장 - **원본 불변**: 기본 `sshd_config`는 그대로 두고 새 파일만 추가 → 배포판 업데이트 안전 - **키 기반 전용 강제**: 비밀번호 관련 옵션을 모두 no로 재확인 (이미 기본값이어도 명시) - **root 직접 로그인 완전 차단**: `PermitRootLogin no` (키 로그인도 차단됨 — `prohibit-password`가 아님에 주의) - **공격 표면 축소**: - `MaxAuthTries 3` (기본 6) — 한 세션에서 시도할 수 있는 인증 횟수 제한 - `LoginGraceTime 30` (기본 120) — 로그인 완료까지 허용 시간 단축, 좀비 세션 방지 - **사용 안 하는 auth 비활성화**: KbdInteractiveAuthentication, ChallengeResponseAuthentication ## 코드 예시 `/etc/ssh/sshd_config.d/99-hardening.conf`: ``` # SSH 보안 하드닝 # 이 파일은 /etc/ssh/sshd_config 보다 우선 적용됨 PermitRootLogin no MaxAuthTries 3 LoginGraceTime 30 PasswordAuthentication no PermitEmptyPasswords no KbdInteractiveAuthentication no ChallengeResponseAuthentication no ``` 적용: ```bash sudo sshd -t # 문법 검증 (실패하면 절대 reload 금지) sudo systemctl reload sshd sudo sshd -T | grep -Ei 'permitroot|maxauth|logingrace|passwordauth' # 실제 반영값 확인 ``` ## 주의사항 - **적용 전 반드시 두 번째 터미널로 접속 세션 유지**: 기존 세션이 끊기면 자신이 잠긴다. 새 터미널로 로그인 확인 후 기존 세션 닫기 - **root로만 작업하는 관행**이 있었다면 `PermitRootLogin no`로 즉시 락아웃 가능 → 일반 계정 + sudo 권한 먼저 만들어두고 테스트 - `sshd -t` 통과해도 의미적으로 잘못된 옵션 조합은 있을 수 있으니 `sshd -T`로 실제 실행 값 확인 - `sshd_config.d/`가 메인 파일에서 include 되지 않는 구버전 OpenSSH(< 8.2)에서는 동작 안 함 — 메인 파일에 직접 쓸 것 - `MaxAuthTries`를 너무 낮게 잡으면 여러 키를 쥐고 있는 클라이언트(SSH agent가 키를 여러 개 제시)에서 인증 실패 - 이 파일은 brute-force를 "늦출" 뿐이지 "막지" 않는다. fail2ban 같은 자동 차단과 반드시 병행 ## 재사용 방법 1. 위 스니펫을 `/etc/ssh/sshd_config.d/99-hardening.conf`로 저장 (sudo 권한) 2. 일반 사용자(sudoer) 계정으로 로그인 가능한지 새 터미널에서 먼저 확인 3. `sudo sshd -t && sudo systemctl reload sshd` 4. `sudo sshd -T | grep ...`으로 반영 확인 5. fail2ban과 함께 사용 (→ `fail2ban-sshd-jail.md`) 6. 참고 실전 적용: Oracle Linux 9 aarch64 ARM 인스턴스 2대 (OCI Always Free)에서 2026-04-17 검증 (566+ 시도 대응)