fail2ban이 IP를 차단 안 할 때: status 0 banned 5분 진단 가이드
SSH 로그에는 Failed password가 수백 줄씩 쌓이는데, fail2ban-client status sshd를 쳐보면 Banned: 0. "분명히 설치하고 enabled도 했는데 왜 안 막히지?" — 이 글은 바로 그 상황을 위한 5분 진단 매뉴얼입니다. 실무에서 fail2ban이 "안 막히는" 케이스는 거의 항상 아래 6가지 중 하나로 수렴합니다. 명령어를 그대로 복붙하면서 따라오면 됩니다.
1. 먼저 돌려볼 진단 3종 명령어
원인을 추측하기 전에, 어디서 끊겼는지부터 확인합니다. 다음 3개를 순서대로 실행하세요.
# ① 전체 jail 목록 — sshd가 보이는가?
sudo fail2ban-client status
# ② sshd jail의 핵심 수치
sudo fail2ban-client status sshd
# ③ 서비스 상태와 에러/Found 로그
sudo systemctl status fail2ban
sudo journalctl -u fail2ban -estatus sshd 출력에서 봐야 할 두 숫자는 Total failed와 Banned입니다. 해석은 이렇게 갈립니다.
| 증상 | 해석 | 의심 원인 |
|---|---|---|
| Total failed가 오르는데 Banned가 0 | 탐지는 되는데 차단 액션이 안 먹힘 | banaction 불일치(④), ignoreip(⑤), 임계값(⑥) |
| Total failed도 계속 0 | 로그 입력 또는 정규식 단계에서 막힘 | logpath/backend(①), failregex(③) |
status에 sshd가 아예 없음 | jail이 활성화 안 됨 | jail.local 미적용(②) |
이 분기만 머릿속에 넣으면 나머지는 빠릅니다. 위에서 갈린 방향으로 아래 섹션을 짚어가세요.
2. 원인① 로그를 못 읽는 경우 (logpath / systemd 백엔드)
증상: Total failed가 계속 0. journalctl -u fail2ban에 Failed to access socket path 또는 Found no accessible config files for 'logpath' 류 메시지.
가장 흔한 1순위 원인입니다. 특히 Ubuntu 22.04/24.04, RHEL 9 계열은 rsyslog 대신 journald가 기본이라 /var/log/auth.log가 비어 있거나 아예 없습니다. fail2ban이 존재하지 않는 파일을 바라보면 당연히 아무것도 못 읽죠.
진단:
# fail2ban이 실제로 어떤 로그를 보는지
sudo fail2ban-client get sshd logpath
# 배포판별 인증 로그 경로 (둘 중 하나)
ls -l /var/log/auth.log # Debian/Ubuntu
ls -l /var/log/secure # RHEL/CentOS/Rocky
# journald에 SSH 로그가 있는지
sudo journalctl -u ssh -n 50 # Ubuntu (서비스명 ssh)
sudo journalctl -u sshd -n 50 # RHEL (서비스명 sshd)해결: 파일 로그가 비어 있고 journald에만 로그가 있다면 백엔드를 systemd로 바꿉니다.
# /etc/fail2ban/jail.local
[sshd]
enabled = true
backend = systemd전역으로 적용하려면 [DEFAULT] 블록에 backend = systemd를 넣어도 됩니다. 적용 후 검증은 4번 명령어와 동일하게 Total failed가 오르는지로 확인합니다.
3. 원인② jail이 안 도는 경우 (enabled=false / jail.local 미적용)
증상: fail2ban-client status 출력의 jail 목록에 sshd가 없음.
진단 & 해결: 절대 jail.conf를 직접 수정하지 마세요. 패키지 업데이트 시 덮어써집니다. 모든 커스텀 설정은 /etc/fail2ban/jail.local에 둡니다.
# /etc/fail2ban/jail.local
[sshd]
enabled = true# 설정 다시 읽기 (또는 재시작)
sudo fail2ban-client reload
# 안 먹으면
sudo systemctl restart fail2ban
# sshd가 목록에 떴는지 재확인
sudo fail2ban-client statusreload는 가끔 jail 추가/삭제를 반영 못 할 때가 있습니다. enabled를 새로 켰는데도 목록에 안 보이면 미련 없이 restart하세요.
4. 원인③ 탐지가 안 되는 경우 (failregex 불일치)
증상: 로그는 읽는데 Total failed가 0. OpenSSH 8.x→9.x로 올라가며 로그 메시지 포맷이 바뀌어 구버전 filter가 매칭에 실패하는 케이스가 최근 급증했습니다.
진단 — fail2ban-regex로 매칭 줄 수를 직접 셉니다.
# 파일 로그 백엔드일 때
sudo fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf
# systemd 백엔드일 때
sudo fail2ban-regex "journalctl -u ssh -o short-iso" /etc/fail2ban/filter.d/sshd.conf출력 끝의 Lines: ... matched에서 matched가 0이면 정규식이 안 맞는 겁니다.
해결: filter의 mode를 aggressive로 올리거나, fail2ban 패키지 자체를 업그레이드합니다(신버전 filter가 9.x 포맷을 지원).
# /etc/fail2ban/jail.local
[sshd]
enabled = true
mode = aggressive
backend = systemdsudo apt update && sudo apt install --only-upgrade fail2ban # Debian/Ubuntu
sudo dnf upgrade fail2ban # RHEL 계열5. 원인④ 매칭은 되는데 차단이 안 되는 경우 (banaction 불일치)
증상: Total failed도 오르고 Banned도 오르는데, 정작 공격자가 계속 접속을 시도함. 방화벽 백엔드가 어긋난 경우입니다. nftables가 기본인 환경에서 iptables 기반 banaction을 쓰면 규칙이 엉뚱한 곳에 들어가 무력화됩니다.
해결 — 환경에 맞는 banaction을 [DEFAULT]에 지정합니다.
# /etc/fail2ban/jail.local
[DEFAULT]
# firewalld 환경 (RHEL 9 등)
banaction = firewallcmd-rich-rules
# ufw 환경 (Ubuntu)
# banaction = ufw
# 순수 iptables
# banaction = iptables-multiport
# nftables 직접
# banaction = nftables-multiport검증 — 실제 차단 규칙이 들어갔는지 봅니다.
sudo iptables -L -n | grep f2b # iptables
sudo nft list ruleset | grep f2b # nftables
sudo firewall-cmd --list-all # firewalld규칙이 안 보이면 banaction이 안 맞는 것입니다.
6. 원인⑤·⑥ ignoreip 함정과 임계값
원인⑤ ignoreip: 테스트 IP나 사내 대역을 넣다가 0.0.0.0/0 같은 광범위 대역을 적으면 사실상 전부 차단 제외됩니다. 자기 공인 IP를 넣어두고 정작 그 IP로 테스트하면 "안 막힌다"고 오해하죠.
[DEFAULT]
ignoreip = 127.0.0.1/8 ::1 10.0.0.0/8 # 필요한 만큼만, 좁게원인⑥ 임계값: findtime = 10m, maxretry = 5는 "10분 안에 5번 실패해야 차단"이라는 뜻입니다. 공격이 느리게 들어오면 임계에 도달 못 해 안 막힙니다.
[sshd]
findtime = 10m
maxretry = 5
bantime = 1h테스트할 땐 maxretry = 2, bantime = 5m처럼 낮춰 빠르게 검증하세요.
액션 분리 검증 — 탐지와 차단 액션을 분리해 확인하는 최고의 트릭은 수동 차단입니다.
sudo fail2ban-client set sshd banip 1.2.3.4
sudo iptables -L -n | grep 1.2.3.4 # 또는 nft / firewall-cmd수동 banip은 막히는데 자동이 안 막히면 → 탐지(①②③) 문제, 수동조차 안 막히면 → banaction(④) 문제입니다.
실무 한마디: 저는 새 서버를 셋업할 때 항상
set sshd banip로 액션부터 검증합니다. 5분 디버깅의 8할은 "탐지냐 차단이냐"를 가르는 일인데, 수동 banip 한 줄이면 그 절반을 즉시 잘라낼 수 있거든요. Ubuntu 24.04에서backend = systemd를 빼먹어 두 시간 헤맨 경험이 이 습관을 만들었습니다.
7. 완성형 jail.local 예제와 진단 플로우차트
바로 복붙해서 환경에 맞게 주석만 푸세요.
# /etc/fail2ban/jail.local
[DEFAULT]
backend = systemd
ignoreip = 127.0.0.1/8 ::1
findtime = 10m
maxretry = 5
bantime = 1h
# 방화벽 환경에 맞춰 하나만 활성화
banaction = firewallcmd-rich-rules # firewalld
# banaction = ufw # ufw
# banaction = iptables-multiport # 순수 iptables
# banaction = nftables-multiport # nftables
[sshd]
enabled = true
mode = aggressive
backend = systemd
port = ssh6원인 진단 플로우차트
fail2ban-client status sshd
├─ status에 sshd 없음? ─────────→ ② jail.local enabled=true + restart
├─ Total failed = 0 ?
│ ├─ get sshd logpath / journalctl 비었나? → ① backend=systemd
│ └─ fail2ban-regex matched=0 ? → ③ mode=aggressive / 업그레이드
└─ Total failed↑ 인데 Banned=0 또는 안 막힘?
├─ set sshd banip 1.2.3.4 도 안 막힘? → ④ banaction 교체
├─ ignoreip에 내 IP/광범위 대역? → ⑤ ignoreip 정리
└─ 임계 미도달? → ⑥ findtime/maxretry 점검재발 방지 체크리스트: ⬜ backend가 환경(journald 여부)과 일치 ⬜ jail.local에만 설정 ⬜ banaction이 방화벽 백엔드와 일치 ⬜ ignoreip 최소화 ⬜ 패키지 최신 버전 ⬜ 변경 후 fail2ban-regex와 수동 banip으로 검증.
자주 묻는 질문 (FAQ)
Q. Total failed는 오르는데 Banned가 0이에요.
A. 탐지는 정상이고 차단 액션이 어긋난 상태입니다. 원인④(banaction)와 원인⑤(ignoreip), 임계값을 점검하세요. fail2ban-client set sshd banip으로 액션을 분리 검증하면 빠릅니다.
Q. reload했는데 설정이 안 먹어요.
A. reload는 jail 추가/제거를 반영 못 하는 경우가 있습니다. sudo systemctl restart fail2ban으로 완전 재시작하고 fail2ban-client status로 확인하세요.
Q. 차단됐다는데 SSH가 여전히 접속돼요.
A. 두 가지입니다. 이미 맺어진 세션은 방화벽 규칙 추가 후에도 유지됩니다(신규 연결만 차단). 그리고 banaction이 실제 방화벽 백엔드(nftables/firewalld/ufw)와 다르면 규칙이 무력화됩니다. iptables -L -n | grep f2b 등으로 규칙 존재를 확인하세요.
Q. Ubuntu 22.04/24.04에서 auth.log가 비어 있어요.
A. journald 기본화로 /var/log/auth.log가 비거나 사라진 환경입니다. backend = systemd로 전환하고 journalctl -u ssh로 로그가 있는지 확인하면 됩니다.
Q. 재부팅하면 차단이 풀려요.
A. 정상 동작에 가깝습니다. bantime이 지나면 해제되며, 영구 차단이 필요하면 bantime = -1을 쓰거나 점증형 차단(bantime.increment = true)을 활용하세요.
이 글은 AI 에이전트가 1차 초안을 작성한 뒤, 사람 편집자가 사실관계·출처·톤과 맥락을 검토하여 발행했습니다. 오류나 부정확한 내용이 확인되면 24시간 이내에 정정합니다.
댓글
불러오는 중...