대상 OS: Rocky Linux 9
인터넷에 노출된 SSH는 ‘언젠가’가 아니라 ‘항상’ 공격을 받습니다. 포트를 바꾸는 정도로는 충분하지 않고, (1) 인증정책(키 기반), (2) 접근대상 제한(사용자/그룹), (3) 네트워크 레벨 제한(IP allowlist), (4) 반복 실패 차단(fail2ban)을 같이 묶어야 운영에서 체감 효과가 납니다.
1) 현재 상태부터 기록(변경 전 스냅샷)
# SSH 실제 적용값(런타임)
sudo sshd -T | egrep -i 'port|permitrootlogin|passwordauthentication|kbdinteractiveauthentication|pubkeyauthentication|allowusers|allowgroups|maxauthtries|loglevel'
# 리스닝 포트/프로세스
sudo ss -lntp | egrep 'sshd|:22'
# 방화벽/존
sudo firewall-cmd --get-default-zone
sudo firewall-cmd --get-active-zones
sudo firewall-cmd --list-all
2) SSH 인증정책: 비밀번호 로그인 차단 + root 직접 로그인 금지
운영에서 가장 중요한 2개는 `PasswordAuthentication no`와 `PermitRootLogin no` 입니다.
sudo cp -a /etc/ssh/sshd_config /etc/ssh/sshd_config.bak.$(date +%F_%H%M)
sudoedit /etc/ssh/sshd_config
# 권장 최소값(환경에 맞게 조정)
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
MaxAuthTries 3
LoginGraceTime 20
LogLevel VERBOSE
적용 전 문법 검증은 필수:
sudo sshd -t
sudo systemctl reload sshd
sudo systemctl status sshd --no-pager
3) 접근 대상 제한: AllowGroups로 SSH 로그인 그룹만 허용
계정이 늘어날수록 `AllowUsers`보다 `AllowGroups`가 관리가 쉽습니다.
# ssh 로그인 허용 그룹 생성
sudo groupadd -f sshlogin
# 허용할 사용자만 그룹에 추가
sudo usermod -aG sshlogin rocky
# sudo usermod -aG sshlogin admin
# sshd_config에 추가
sudoedit /etc/ssh/sshd_config
AllowGroups sshlogin
sudo sshd -t && sudo systemctl reload sshd
4) 네트워크 레벨 제한: firewalld rich rule로 ‘특정 IP만’ SSH 허용
SSH는 가능하면 전 세계 오픈을 피하고, 관리자 고정 IP(또는 VPN 대역)만 허용하세요.
# 예: 203.0.113.10/32만 SSH 허용
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="203.0.113.10/32" service name="ssh" accept'
# 기본 ssh 서비스가 열려 있으면 제거(전 세계 허용 방지)
sudo firewall-cmd --permanent --remove-service=ssh || true
sudo firewall-cmd --reload
sudo firewall-cmd --list-all
운영 팁: 클라우드 환경이면 “보안그룹/방화벽”도 같이 닫아야 진짜로 막힙니다(이중 방어).
5) Fail2ban으로 반복 실패 차단(보조 완화)
키 인증을 강제해도 스캔/시도는 계속 오므로, 노이즈/자원 소모를 줄이기 위해 fail2ban을 붙입니다.
sudo dnf install -y epel-release
sudo dnf install -y fail2ban
sudo systemctl enable --now fail2ban
sudoedit /etc/fail2ban/jail.d/sshd.local
[sshd]
enabled = true
maxretry = 4
findtime = 10m
bantime = 2h
sudo systemctl restart fail2ban
sudo fail2ban-client status sshd
6) 트러블슈팅(증상→원인→해결)
1) 설정 후 SSH 접속이 안 됨
- 원인: 방화벽에서 ssh 서비스 제거했는데 rich rule 소스 IP가 틀림
- 해결: 콘솔 접근을 확보한 뒤 IP를 수정하고 reload
2) 키가 있는데도 비밀번호를 물어봄
- 원인: 클라이언트가 다른 키를 쓰거나 서버 권한이 잘못됨
- 해결:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
sudo ls -ld ~/.ssh ~/.ssh/authorized_keys
3) AllowGroups 적용 후 특정 계정만 접속 불가
- 원인: 사용자가 그룹에 미가입, 또는 세션이 갱신되지 않음
- 해결: `id 사용자`로 그룹 확인 후 재로그인
4) Fail2ban이 차단을 안 하는 것 같음
- 원인: 로그 소스(journald/audit)와 필터가 환경에 맞지 않음
- 해결: `sudo journalctl -u sshd`로 실제 로그를 보고, jail 설정을 조정
7) 사례(현장에서 자주 겪는 상황)
1) “편의상” PasswordAuthentication을 켜둔 테스트 서버가 결국 운영망에 남아 침해됨
2) 포트만 바꾸고(2222) 나머지는 그대로라서, 스캔이 포트만 찾아내고 공격 재개
3) AllowGroups 없이 계정이 계속 늘어나 퇴사자/외주 계정이 SSH에 그대로 노출
결론적으로, SSH 하드닝은 ‘한 가지 조치’가 아니라 “정책 묶음”입니다. 위 4개(키 강제/대상 제한/IP 제한/fail2ban)를 동시에 적용하면 공격면이 크게 줄어듭니다.