# fail2ban sshd Jail (점증 bantime) ## 언제 쓰는가 - SSH 브루트포스 시도가 쏟아지는 VM(OCI/AWS/GCP Always Free 포함)에서 자동 차단이 필요할 때 - 같은 IP가 반복해서 시도하면 차단 시간을 기하급수적으로 늘려 "첫 번째는 1시간, 두 번째는 2시간, … 최대 1주" 처럼 처벌하고 싶을 때 - Oracle Linux 9 / RHEL 계열의 firewalld + systemd journal 환경에서 바로 적용 가능한 구성을 찾을 때 - 메모리 2GB 이상 VM (1GB 이하는 fail2ban 설치 중 load spike 발생으로 비권장) ## 핵심 구조 - **단일 설정 파일**: `/etc/fail2ban/jail.local` — 패키지가 덮어쓰지 않음 (`jail.conf`는 절대 건드리지 않기) - **backend = systemd**: journald에서 sshd 로그를 바로 읽음 (Oracle Linux 9 등 journald 기본 환경에서 추가 설정 불필요) - **차단 엔진 = firewalld rich-rules**: nftables/iptables 직접 건드리지 않고 firewalld와 통합. 재부팅 후에도 유지됨 - **점증 차단(bantime.increment)**: 같은 IP가 다시 걸릴 때마다 `bantime *= factor` 로 차단 시간 증가, `bantime.maxtime`에서 상한 - **화이트리스트**: 본인 IP와 관리 네트워크는 `ignoreip`에 필수 등록 (실수로 본인이 차단되면 ARM 인스턴스는 복구가 번거로움) - **aggressive 모드**: `mode = aggressive`로 sshd filter가 실패 이벤트를 더 적극적으로 매칭 (preauth 차단 포함) ## 코드 예시 `/etc/fail2ban/jail.local`: ```ini [DEFAULT] bantime = 1h findtime = 10m maxretry = 3 ignoreip = 127.0.0.1/8 ::1 <본인 IP> <백업 IP> backend = systemd banaction = firewallcmd-rich-rules[actiontype=] banaction_allports = firewallcmd-rich-rules[actiontype=] # 반복 위반 시 bantime 점증 bantime.increment = true bantime.factor = 2 bantime.maxtime = 1w [sshd] enabled = true mode = aggressive port = ssh ``` 설치 + 가동 (Oracle Linux 9): ```bash sudo dnf install -y fail2ban fail2ban-firewalld fail2ban-systemd sudo systemctl enable --now fail2ban sudo fail2ban-client status sshd # 상태/차단 IP 확인 sudo fail2ban-client set sshd unbanip # 수동 해제 ``` 확인: ```bash sudo fail2ban-client status sshd # Status for the jail: sshd # |- Filter # | |- Currently failed: N # | |- Total failed: N # | `- Journal matches: _SYSTEMD_UNIT=sshd.service ... # `- Actions # |- Currently banned: M # |- Total banned: M # `- Banned IP list: ... ``` ## 주의사항 - **`jail.local`만 편집**. `jail.conf`는 패키지 업데이트로 덮어써지므로 절대 수정 금지 - **`ignoreip`에 본인 IP 추가 필수**. 특히 `findtime` 10분 동안 SSH 테스트 중 키 교환 실패를 3회 이상 만들 수 있음 - **fail2ban-firewalld 패키지 없이 사용**하면 `banaction = iptables-multiport` 기본값이 적용되어 firewalld와 충돌할 수 있음 - **1GB 이하 VM에서는 설치 시점에 load spike**(경험상 `load 27+`까지 튐) → OOM/스왑 폭주 위험. 이런 서버는 sshd 하드닝 + 키 전용 인증으로 대체 권장 - **`bantime.increment`는 fail2ban 0.11+** 필요. 이전 버전은 옵션 무시됨 - **점증은 DB 기반**: `/var/lib/fail2ban/fail2ban.sqlite3`에 히스토리 저장. 이 파일 삭제 시 점증 리셋됨 - **IPv6 차단도 포함**: `banaction`이 rich-rules이면 v4/v6 모두 차단 - **시크릿 주입 아님**: `<본인 IP>`는 예시이므로 실제 고정 IP로 교체할 것. 동적 IP면 대역으로 지정하거나 SSH jump host 사용 ## 재사용 방법 1. 위 `jail.local`을 `/etc/fail2ban/` 에 저장, `ignoreip` 값만 환경에 맞게 치환 2. `dnf install -y fail2ban fail2ban-firewalld fail2ban-systemd` (RHEL 계열) / `apt install fail2ban` (Debian 계열은 firewalld 패키지 조합 달라짐) 3. `systemctl enable --now fail2ban` 4. 10분 이상 경과 후 `fail2ban-client status sshd`로 동작 확인 5. sshd 하드닝(`sshd-hardening.md`)과 반드시 함께 적용 6. 참고 실전 지표: OCI A1.Flex ARM 2 OCPU / 12GB × 2대에 2026-04-17 적용 후 누적 차단 IP 27개, 총 실패 566회 기록 (1시간 단위)