Fail2ban 설치 및 사용 가이드

Fail2ban 개요

Fail2ban은 로그 파일을 모니터링하여 악의적인 활동(무차별 대입 공격, 포트 스캔 등)을 탐지하고 자동으로 차단하는 침입 방지 소프트웨어입니다.

주요 기능

  • 로그 파일 실시간 모니터링
  • 정규표현식 기반 패턴 매칭
  • 자동 IP 차단 (iptables, firewalld, ufw 등)
  • 시간 기반 자동 차단 해제
  • 이메일 알림 기능
  • 다양한 서비스 지원 (SSH, Apache, Nginx, MySQL 등)

작동 원리

  1. 로그 모니터링: Fail2ban은 지정된 로그 파일을 실시간으로 감시합니다.
  2. 패턴 매칭: 설정된 정규표현식 패턴(filter)과 로그를 비교합니다.
  3. 실패 횟수 카운트: 특정 IP에서 실패가 발생할 때마다 카운트를 증가시킵니다.
  4. 차단 실행: 설정된 임계값(maxretry)을 초과하면 해당 IP를 차단합니다.
  5. 자동 해제: 설정된 시간(bantime) 후 자동으로 차단을 해제합니다.

1. 설치

Ubuntu/Debian

# 패키지 업데이트
sudo apt update

# Fail2ban 설치
sudo apt install fail2ban -y

# 서비스 시작 및 자동 시작 설정
sudo systemctl start fail2ban
sudo systemctl enable fail2ban
# 상태 확인
sudo systemctl status fail2ban

CentOS/RHEL

# EPEL 저장소 활성화
sudo yum install epel-release -y

# Fail2ban 설치
sudo yum install fail2ban fail2ban-systemd -y

# 서비스 시작 및 자동 시작 설정
sudo systemctl start fail2ban
sudo systemctl enable fail2ban

# 상태 확인
sudo systemctl status fail2ban

상태 확인

> sudo systemctl status fail2ban

● fail2ban.service - Fail2Ban Service
Loaded: loaded (/usr/lib/systemd/system/fail2ban.service; enabled; preset: enabled)
Active: active (running) since Thu 2025-10-30 23:11:05 KST; 1 month 29 days ago
Docs: man:fail2ban(1)
Main PID: 1267 (fail2ban-server)
Tasks: 5 (limit: 37661)
Memory: 48.9M (peak: 79.8M)
CPU: 44min 41.012s
CGroup: /system.slice/fail2ban.service
└─1267 /usr/bin/python3 /usr/bin/fail2ban-server -xf start

버전 확인

fail2ban-server --version

2. 기본 설정

설정 파일 구조

/etc/fail2ban/
├── fail2ban.conf # Fail2ban 데몬 설정 (수정 X)
├── fail2ban.local # fail2ban.conf 오버라이드용
├── jail.conf # Jail 기본 설정 (수정 X)
├── jail.local # jail.conf 오버라이드용 (주요 설정 파일)
├── jail.d/ # 개별 jail 설정 디렉토리
├── filter.d/ # 필터 정의 파일들
├── action.d/ # 액션 정의 파일들
└── fail2ban.d/ # fail2ban 추가 설정

jail.local 생성

Fail2ban의 기본 설정 파일은 /etc/fail2ban/jail.conf 에 있습니다. 그러나 기본 파일을 직접 수정하는 것은 업데이트 시 덮어쓰여질 수 있으므로, 로컬 설정 파일/etc/fail2ban/jail.local을 만들어 사용자 설정을 오버라이드하는 것이 좋습니다.

# 원본 설정 파일을 직접 수정하지 않고 `.local` 파일을 생성하여 설정을 오버라이드합니다.
# jail.conf를 복사하여 jail.local 생성
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

# 또는 직접 생성
sudo vim /etc/fail2ban/jail.local

기본 설정 예시

[DEFAULT]
# 무시할 IP 목록 (쉼표 또는 공백으로 구분)
ignoreip = 127.0.0.1/8 ::1 192.168.1.0/24

# 기본 차단 시간 (초) - 10분
bantime = 10m

# 차단 전 관찰 시간 (초) - 10분
findtime = 10m

# 최대 재시도 횟수
maxretry = 5

# 관리자 이메일 (알림 받을 주소)
destemail = admin@example.com
sender = fail2ban@example.com

# 이메일 알림 액션
action = %(action_mwl)s

# 차단 방법 (iptables, firewalld 등)
banaction = iptables-multiport

주요 파라미터 설명

  • bantime: IP 차단 유지 시간 (예: 10m, 1h, 1d, -1은 영구)
  • findtime: 실패 횟수를 세는 기간
  • maxretry: findtime 동안 허용되는 최대 실패 횟수
  • ignoreip: 차단하지 않을 IP 주소 또는 대역
  • destemail: 알림을 받을 이메일 주소
  • action: 차단 시 실행할 액션

3. Jail 설정

Jail은 특정 서비스에 대한 보호 규칙을 정의합니다.

SSH 보호 설정

[sshd]
enabled = true
port = ssh,22
filter = sshd
logpath = /var/log/auth.log # Ubuntu/Debian
# logpath = /var/log/secure # CentOS/RHEL
maxretry = 5
findtime = 10m
bantime = 1h

Apache 보호 설정

[apache-auth]
enabled = true
port = http,https
filter = apache-auth
logpath = /var/log/apache2/error.log
maxretry = 3
bantime = 1h

[apache-badbots]
enabled = true
port = http,https
filter = apache-badbots
logpath = /var/log/apache2/access.log
maxretry = 2
bantime = 24h

[apache-noscript]
enabled = true
port = http,https
filter = apache-noscript
logpath = /var/log/apache2/error.log
maxretry = 3
bantime = 1h

Nginx 보호 설정

[nginx-http-auth]
enabled = true
port = http,https
filter = nginx-http-auth
logpath = /var/log/nginx/error.log
maxretry = 3
bantime = 1h

[nginx-limit-req]
enabled = true
port = http,https
filter = nginx-limit-req
logpath = /var/log/nginx/error.log
maxretry = 10
findtime = 60
bantime = 1h

[nginx-botsearch]
enabled = true
port = http,https
filter = nginx-botsearch
logpath = /var/log/nginx/access.log
maxretry = 2
bantime = 24h

MySQL 보호 설정

[mysqld-auth]
enabled = true
port = 3306
filter = mysqld-auth
logpath = /var/log/mysql/error.log
maxretry = 5
bantime = 1h

개별 Jail 파일 생성

# jail.d 디렉토리에 개별 설정 생성
sudo vim /etc/fail2ban/jail.d/sshd.local
[sshd]
enabled = true
port = 2222 # 사용자 정의 SSH 포트
maxretry = 3
bantime = 24h
findtime = 10m

4. 필터 (Filter) 설정

필터는 로그에서 실패를 감지하는 정규표현식 패턴을 정의합니다.

기본 제공 필터 확인

ls /etc/fail2ban/filter.d/

사용자 정의 필터 생성

sudo vim /etc/fail2ban/filter.d/custom-app.conf
[Definition]
# 실패 패턴 정의
failregex = ^<HOST> .* "POST /login HTTP.*" 401
^<HOST> .* "Authentication failed for user"

# 성공 패턴 정의 (선택사항)
ignoreregex =

필터 테스트

# 필터가 로그와 매칭되는지 테스트
fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf

# 사용자 정의 패턴 테스트
fail2ban-regex /var/log/myapp.log /etc/fail2ban/filter.d/custom-app.conf

5. 액션 (Action) 설정

액션은 차단 시 실행할 동작을 정의합니다.

기본 제공 액션 확인

ls /etc/fail2ban/action.d/

주요 액션

  • iptables-multiport: 여러 포트를 한 번에 차단
  • iptables-allports: 모든 포트 차단
  • firewalld-cmd: firewalld 사용
  • sendmail-whois: 이메일 알림 + WHOIS 정보

이메일 알림 설정

[DEFAULT]
# 이메일 액션 선택
# action_: 차단만 실행
# action_mw: 차단 + 이메일 알림
# action_mwl: 차단 + 이메일 알림 + 로그 포함

action = %(action_mwl)s

destemail = admin@example.com
sender = fail2ban@hostname
mta = sendmail

사용자 정의 액션 생성

sudo vim /etc/fail2ban/action.d/custom-notify.conf
[Definition]
# 차단 시 실행할 명령
actionban = curl -X POST https://api.example.com/alert \
-d "ip=<ip>&service=<name>"

# 차단 해제 시 실행할 명령
actionunban = curl -X POST https://api.example.com/unblock \
-d "ip=<ip>&service=<name>"

[Init]
# 초기화 파라미터
name = default

6. 관리 명령어

서비스 관리

# 서비스 시작
sudo systemctl start fail2ban

# 서비스 중지
sudo systemctl stop fail2ban

# 서비스 재시작
sudo systemctl restart fail2ban

# 서비스 상태 확인
sudo systemctl status fail2ban

# 설정 다시 로드
sudo systemctl reload fail2ban
sudo fail2ban-client reload

fail2ban-client 명령어

# 전체 상태 확인
sudo fail2ban-client status

# 특정 jail 상태 확인
sudo fail2ban-client status sshd

# 활성화된 jail 목록
sudo fail2ban-client status

# jail 시작/중지
sudo fail2ban-client start sshd
sudo fail2ban-client stop sshd

# jail 다시 로드
sudo fail2ban-client reload sshd

# 설정 확인
sudo fail2ban-client get sshd bantime
sudo fail2ban-client get sshd maxretry

IP 차단 관리

# 현재 차단된 IP 확인
sudo fail2ban-client status sshd

# 수동으로 IP 차단
sudo fail2ban-client set sshd banip 192.168.1.100

# IP 차단 해제
sudo fail2ban-client set sshd unbanip 192.168.1.100

# 모든 IP 차단 해제
sudo fail2ban-client unban --all

# 특정 jail의 모든 IP 차단 해제
sudo fail2ban-client set sshd unbanip --all

로그 확인

# Fail2ban 로그 확인
sudo tail -f /var/log/fail2ban.log

# 차단 이벤트만 확인
sudo grep "Ban" /var/log/fail2ban.log

# 특정 IP 관련 로그
sudo grep "192.168.1.100" /var/log/fail2ban.log

# 최근 차단된 IP 목록
sudo grep "Ban" /var/log/fail2ban.log | tail -20

# journalctl 사용 (systemd)
sudo journalctl -u fail2ban -f
sudo journalctl -u fail2ban --since "1 hour ago"

7. iptables/방화벽 확인

iptables로 차단 규칙 확인

# Fail2ban 체인 확인
sudo iptables -L fail2ban-sshd -v -n

# 전체 iptables 규칙
sudo iptables -L -n -v

# 차단된 IP 확인
sudo iptables -L -n | grep -i reject

firewalld 사용 시

# Rich rules 확인
sudo firewall-cmd --list-rich-rules

# Fail2ban zone 확인
sudo firewall-cmd --zone=drop --list-sources

8. 모니터링 및 통계

차단 통계 확인

# jail별 차단된 IP 수 확인
sudo fail2ban-client status | grep "Jail list"
sudo fail2ban-client status sshd | grep "Currently banned"

# 로그에서 차단 통계 추출
sudo grep "Ban" /var/log/fail2ban.log | awk '{print $NF}' | sort | uniq -c | sort -rn | head -10

# 가장 많이 차단된 IP Top 10
sudo grep "Ban" /var/log/fail2ban.log | grep -oP '\d+\.\d+\.\d+\.\d+' | sort | uniq -c | sort -rn | head -10

# 날짜별 차단 통계
sudo grep "Ban" /var/log/fail2ban.log | awk '{print $1}' | sort | uniq -c

실시간 모니터링 스크립트

#!/bin/bash
# fail2ban-monitor.sh

echo "=== Fail2ban Status ==="
sudo fail2ban-client status

echo -e "\n=== Currently Banned IPs (sshd) ==="
sudo fail2ban-client status sshd | grep "Banned IP list"

echo -e "\n=== Recent Ban Events ==="
sudo grep "Ban" /var/log/fail2ban.log | tail -10

echo -e "\n=== Top 5 Banned IPs ==="
sudo grep "Ban" /var/log/fail2ban.log | grep -oP '\d+\.\d+\.\d+\.\d+' | sort | uniq -c | sort -rn | head -5

9. 고급 설정

영구 차단 설정

[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
findtime = 10m
bantime = -1 # 영구 차단

증분 차단 시간 (Incremental Ban)

반복적으로 차단되는 IP에 대해 차단 시간을 점진적으로 늘립니다.

sudo vim /etc/fail2ban/jail.d/recidive.local
[recidive]
enabled = true
filter = recidive
logpath = /var/log/fail2ban.log
action = iptables-allports[name=recidive]
sendmail-whois-lines[name=recidive, logpath=/var/log/fail2ban.log]
bantime = 1w # 1주일
findtime = 1d # 하루 동안
maxretry = 3 # 3번 차단되면

국가별 IP 차단

GeoIP를 사용하여 특정 국가의 IP를 차단합니다.

# GeoIP 설치
sudo apt install geoip-bin geoip-database

# 필터 생성
sudo vim /etc/fail2ban/filter.d/geoip.conf
[Definition]
# Python 스크립트를 사용한 GeoIP 체크
failregex = <HOST>

[geoip]
# 차단할 국가 코드 (ISO 2자리)
country = CN,RU,KP

화이트리스트 설정

[DEFAULT]
# 절대 차단하지 않을 IP
ignoreip = 127.0.0.1/8 ::1
192.168.1.0/24
10.0.0.0/8
your.trusted.ip.address

# 또는 파일로 관리
ignoreip = %(ignoreip)s
ignorecommand = cat /etc/fail2ban/whitelist.conf
# 화이트리스트 파일 생성
sudo vim /etc/fail2ban/whitelist.conf
192.168.1.100
203.0.113.0/24

systemd 통합 설정

[DEFAULT]
# systemd journal 사용
backend = systemd

[sshd]
enabled = true
filter = sshd
maxretry = 5
bantime = 1h
# logpath 대신 backend 사용
backend = systemd

10. 문제 해결

설정 검증

# 설정 파일 문법 검사
sudo fail2ban-client -t

# 특정 jail 테스트
sudo fail2ban-client -vvv start

# 디버그 모드로 실행
sudo fail2ban-client -x -v start

일반적인 문제

Fail2ban이 시작되지 않음

# 로그 확인
sudo tail -100 /var/log/fail2ban.log

# 설정 검증
sudo fail2ban-client -t

# systemd 상태
sudo systemctl status fail2ban -l

차단이 작동하지 않음

# jail이 활성화되었는지 확인
sudo fail2ban-client status

# 로그 파일 경로 확인
ls -la /var/log/auth.log

# 필터 테스트
fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf

# 로그 권한 확인
sudo chmod 644 /var/log/auth.log

로그 파일을 찾을 수 없음

# SELinux 확인 (CentOS/RHEL)
sudo ausearch -c 'fail2ban-server' --raw | audit2allow -M my-fail2ban
sudo semodule -i my-fail2ban.pp

# 로그 파일 확인
sudo journalctl -u fail2ban | grep "File not found"

이메일 알림이 작동하지 않음

# sendmail 또는 postfix 설치 확인
which sendmail

# sendmail 설치
sudo apt install sendmail # Ubuntu/Debian
sudo yum install sendmail # CentOS/RHEL

# 테스트 메일 발송
echo "Test" | mail -s "Test" admin@example.com

수동 데이터베이스 초기화

# Fail2ban 중지
sudo systemctl stop fail2ban

# 데이터베이스 삭제
sudo rm /var/lib/fail2ban/fail2ban.sqlite3

# Fail2ban 시작
sudo systemctl start fail2ban

11. 성능 최적화

로그 폴링 간격 조정

sudo vim /etc/fail2ban/fail2ban.conf
[Definition]
# 로그 파일 확인 간격 (초)
logtarget = /var/log/fail2ban.log
loglevel = INFO
syslogsocket = auto

# 데이터베이스 설정
dbfile = /var/lib/fail2ban/fail2ban.sqlite3
dbpurgeage = 86400 # 1일 후 오래된 항목 삭제

jail별 최적화

[sshd]
# 로그 인코딩 지정
logencoding = auto

# 날짜 형식 지정
datepattern = {^LN-BEG}

12. 백업 및 복구

설정 백업

# 설정 파일 백업
sudo tar -czf fail2ban-config-backup-$(date +%Y%m%d).tar.gz \
/etc/fail2ban/jail.local \
/etc/fail2ban/jail.d/ \
/etc/fail2ban/filter.d/*.local \
/etc/fail2ban/action.d/*.local

# 데이터베이스 백업
sudo cp /var/lib/fail2ban/fail2ban.sqlite3 \
/backup/fail2ban.sqlite3.$(date +%Y%m%d)

복구

# 설정 복구
sudo tar -xzf fail2ban-config-backup-20241229.tar.gz -C /

# Fail2ban 재시작
sudo systemctl restart fail2ban

13. 보안 베스트 프랙티스

권장 설정

  1. 적절한 bantime 설정: 너무 짧으면 효과 없음, 너무 길면 오탐 시 문제
  2. maxretry 조정: 서비스 특성에 맞게 설정 (SSH: 3-5, 웹: 5-10)
  3. ignoreip 관리: 신뢰할 수 있는 IP만 추가
  4. 로그 모니터링: 정기적으로 차단 로그 검토
  5. recidive jail 활성화: 반복 공격자 장기 차단
  6. 이메일 알림 설정: 중요한 이벤트 즉시 파악

추가 보안 조치

# SSH 포트 변경 (기본 22번에서 변경)
# /etc/ssh/sshd_config
Port 2222

# SSH 키 기반 인증 사용
PasswordAuthentication no
PubkeyAuthentication yes

# root 직접 로그인 차단
PermitRootLogin no

# Fail2ban jail 설정 업데이트
[sshd]
port = 2222

14. 대안 및 보완 도구

함께 사용하면 좋은 도구

  • DenyHosts: SSH 전용 차단 도구
  • CSF (ConfigServer Security & Firewall): 종합 방화벽 솔루�
  • ModSecurity: 웹 애플리케이션 방화벽 (WAF)
  • OSSEC: 호스트 기반 침입 탐지 시스템
  • Snort/Suricata: 네트워크 침입 탐지 시스템

15. 실전 예제

완전한 설정 예제

# /etc/fail2ban/jail.local

[DEFAULT]
bantime = 1h
findtime = 10m
maxretry = 5
destemail = admin@example.com
sender = fail2ban@server.example.com
action = %(action_mwl)s
ignoreip = 127.0.0.1/8 192.168.1.0/24

[sshd]
enabled = true
port = ssh,2222
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 24h

[nginx-http-auth]
enabled = true
port = http,https
filter = nginx-http-auth
logpath = /var/log/nginx/error.log
maxretry = 3

[nginx-limit-req]
enabled = true
port = http,https
filter = nginx-limit-req
logpath = /var/log/nginx/error.log
maxretry = 10
findtime = 60

[recidive]
enabled = true
filter = recidive
logpath = /var/log/fail2ban.log
bantime = 1w
findtime = 1d
maxretry = 3

모니터링 대시보드 스크립트

#!/bin/bash
# /usr/local/bin/fail2ban-dashboard.sh

clear
echo "╔════════════════════════════════════════════════════╗"
echo "║ Fail2ban Monitoring Dashboard ║"
echo "╚════════════════════════════════════════════════════╝"
echo ""

# 전체 상태
echo "📊 Overall Status:"
sudo fail2ban-client status
echo ""

# Jail별 차단 현황
echo "🔒 Banned IPs by Jail:"
for jail in $(sudo fail2ban-client status | grep "Jail list" | sed 's/.*://;s/,//g'); do
banned=$(sudo fail2ban-client status $jail | grep "Currently banned" | awk '{print $NF}')
total=$(sudo fail2ban-client status $jail | grep "Total banned" | awk '{print $NF}')
echo " - $jail: Currently $banned | Total $total"
done
echo ""

# 최근 차단 이벤트
echo "📝 Recent Ban Events (Last 10):"
sudo grep "Ban" /var/log/fail2ban.log | tail -10 | while read line; do
echo " $line"
done
echo ""

# Top 공격 IP
echo "🎯 Top 10 Attacking IPs:"
sudo grep "Ban" /var/log/fail2ban.log | grep -oP '\d+\.\d+\.\d+\.\d+' | sort | uniq -c | sort -rn | head -10
echo ""

# 통계
echo "📈 Statistics:"
echo " Total bans today: $(sudo grep "Ban" /var/log/fail2ban.log | grep "$(date +%Y-%m-%d)" | wc -l)"
echo " Active jails: $(sudo fail2ban-client status | grep "Number of jail" | awk '{print $NF}')"
echo ""

실행 권한 부여:

sudo chmod +x /usr/local/bin/fail2ban-dashboard.sh
sudo /usr/local/bin/fail2ban-dashboard.sh

참고 자료

Share