Fail2ban 개요 Fail2ban은 로그 파일을 모니터링하여 악의적인 활동(무차별 대입 공격, 포트 스캔 등)을 탐지하고 자동으로 차단하는 침입 방지 소프트웨어입니다.
주요 기능
로그 파일 실시간 모니터링
정규표현식 기반 패턴 매칭
자동 IP 차단 (iptables, firewalld, ufw 등)
시간 기반 자동 차단 해제
이메일 알림 기능
다양한 서비스 지원 (SSH, Apache, Nginx, MySQL 등)
작동 원리
로그 모니터링 : Fail2ban은 지정된 로그 파일을 실시간으로 감시합니다.
패턴 매칭 : 설정된 정규표현식 패턴(filter)과 로그를 비교합니다.
실패 횟수 카운트 : 특정 IP에서 실패가 발생할 때마다 카운트를 증가시킵니다.
차단 실행 : 설정된 임계값(maxretry)을 초과하면 해당 IP를 차단합니다.
자동 해제 : 설정된 시간(bantime) 후 자동으로 차단을 해제합니다.
1. 설치 Ubuntu/Debian sudo apt update sudo apt install fail2ban -y sudo systemctl start fail2ban sudo systemctl enable fail2ban sudo systemctl status fail2ban
CentOS/RHEL sudo yum install epel-release -y 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.local ├── jail.conf ├── jail.local ├── jail.d/ ├── filter.d/ ├── action.d/ └── fail2ban.d/
jail.local 생성 Fail2ban의 기본 설정 파일은 /etc/fail2ban/jail.conf 에 있습니다. 그러나 기본 파일을 직접 수정하는 것은 업데이트 시 덮어쓰여질 수 있으므로, 로컬 설정 파일 인 /etc/fail2ban/jail.local을 만들어 사용자 설정을 오버라이드하는 것이 좋습니다.
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local sudo vim /etc/fail2ban/jail.local
기본 설정 예시 [DEFAULT] ignoreip = 127.0 .0.1 /8 ::1 192.168 .1.0 /24 bantime = 10 mfindtime = 10 mmaxretry = 5 destemail = admin@example.comsender = fail2ban@example.comaction = %(action_mwl)sbanaction = 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 = sshdlogpath = /var/log/auth.log maxretry = 5 findtime = 10 mbantime = 1 h
Apache 보호 설정 [apache-auth] enabled = true port = http,httpsfilter = apache-authlogpath = /var/log/apache2/error.logmaxretry = 3 bantime = 1 h[apache-badbots] enabled = true port = http,httpsfilter = apache-badbotslogpath = /var/log/apache2/access.logmaxretry = 2 bantime = 24 h[apache-noscript] enabled = true port = http,httpsfilter = apache-noscriptlogpath = /var/log/apache2/error.logmaxretry = 3 bantime = 1 h
Nginx 보호 설정 [nginx-http-auth] enabled = true port = http,httpsfilter = nginx-http-authlogpath = /var/log/nginx/error.logmaxretry = 3 bantime = 1 h[nginx-limit-req] enabled = true port = http,httpsfilter = nginx-limit-reqlogpath = /var/log/nginx/error.logmaxretry = 10 findtime = 60 bantime = 1 h[nginx-botsearch] enabled = true port = http,httpsfilter = nginx-botsearchlogpath = /var/log/nginx/access.logmaxretry = 2 bantime = 24 h
MySQL 보호 설정 [mysqld-auth] enabled = true port = 3306 filter = mysqld-authlogpath = /var/log/mysql/error.logmaxretry = 5 bantime = 1 h
개별 Jail 파일 생성 sudo vim /etc/fail2ban/jail.d/sshd.local
[sshd] enabled = true port = 2222 maxretry = 3 bantime = 24 hfindtime = 10 m
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_mwl)sdestemail = admin@example.comsender = fail2ban@hostnamemta = 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 sudo fail2ban-client status sshd sudo fail2ban-client status sudo fail2ban-client start sshd sudo fail2ban-client stop sshd sudo fail2ban-client reload sshd sudo fail2ban-client get sshd bantime sudo fail2ban-client get sshd maxretry
IP 차단 관리 sudo fail2ban-client status sshd sudo fail2ban-client set sshd banip 192.168.1.100 sudo fail2ban-client set sshd unbanip 192.168.1.100 sudo fail2ban-client unban --all sudo fail2ban-client set sshd unbanip --all
로그 확인 sudo tail -f /var/log/fail2ban.log sudo grep "Ban" /var/log/fail2ban.log sudo grep "192.168.1.100" /var/log/fail2ban.log sudo grep "Ban" /var/log/fail2ban.log | tail -20 sudo journalctl -u fail2ban -f sudo journalctl -u fail2ban --since "1 hour ago"
7. iptables/방화벽 확인 iptables로 차단 규칙 확인 sudo iptables -L fail2ban-sshd -v -n sudo iptables -L -n -v sudo iptables -L -n | grep -i reject
firewalld 사용 시 sudo firewall-cmd --list-rich-rules sudo firewall-cmd --zone=drop --list-sources
8. 모니터링 및 통계 차단 통계 확인 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 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 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 = sshfilter = sshdlogpath = /var/log/auth.logmaxretry = 3 findtime = 10 mbantime = -1
증분 차단 시간 (Incremental Ban) 반복적으로 차단되는 IP에 대해 차단 시간을 점진적으로 늘립니다.
sudo vim /etc/fail2ban/jail.d/recidive.local
[recidive] enabled = true filter = recidivelogpath = /var/log/fail2ban.logaction = iptables-allports[name=recidive] sendmail-whois-lines[name=recidive, logpath=/var/log/fail2ban.log] bantime = 1 w findtime = 1 d maxretry = 3
국가별 IP 차단 GeoIP를 사용하여 특정 국가의 IP를 차단합니다.
sudo apt install geoip-bin geoip-database sudo vim /etc/fail2ban/filter.d/geoip.conf
[Definition] failregex = <HOST>[geoip] country = CN,RU,KP
화이트리스트 설정 [DEFAULT] ignoreip = 127.0 .0.1 /8 ::1 192.168.1.0/24 10.0.0.0/8 your.trusted.ip.address ignoreip = %(ignoreip)signorecommand = cat /etc/fail2ban/whitelist.conf
sudo vim /etc/fail2ban/whitelist.conf
192.168.1.100 203.0.113.0/24
systemd 통합 설정 [DEFAULT] backend = systemd[sshd] enabled = true filter = sshdmaxretry = 5 bantime = 1 hbackend = systemd
10. 문제 해결 설정 검증 sudo fail2ban-client -t sudo fail2ban-client -vvv start sudo fail2ban-client -x -v start
일반적인 문제 Fail2ban이 시작되지 않음 sudo tail -100 /var/log/fail2ban.log sudo fail2ban-client -t sudo systemctl status fail2ban -l
차단이 작동하지 않음 sudo fail2ban-client status ls -la /var/log/auth.logfail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf sudo chmod 644 /var/log/auth.log
로그 파일을 찾을 수 없음 sudo ausearch -c 'fail2ban-server' --raw | audit2allow -M my-fail2ban sudo semodule -i my-fail2ban.pp sudo journalctl -u fail2ban | grep "File not found"
이메일 알림이 작동하지 않음 which sendmailsudo apt install sendmail sudo yum install sendmail echo "Test" | mail -s "Test" admin@example.com
수동 데이터베이스 초기화 sudo systemctl stop fail2ban sudo rm /var/lib/fail2ban/fail2ban.sqlite3 sudo systemctl start fail2ban
11. 성능 최적화 로그 폴링 간격 조정 sudo vim /etc/fail2ban/fail2ban.conf
[Definition] logtarget = /var/log/fail2ban.logloglevel = INFOsyslogsocket = autodbfile = /var/lib/fail2ban/fail2ban.sqlite3dbpurgeage = 86400
jail별 최적화 [sshd] logencoding = autodatepattern = {^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 / sudo systemctl restart fail2ban
13. 보안 베스트 프랙티스 권장 설정
적절한 bantime 설정 : 너무 짧으면 효과 없음, 너무 길면 오탐 시 문제
maxretry 조정 : 서비스 특성에 맞게 설정 (SSH: 3-5, 웹: 5-10)
ignoreip 관리 : 신뢰할 수 있는 IP만 추가
로그 모니터링 : 정기적으로 차단 로그 검토
recidive jail 활성화 : 반복 공격자 장기 차단
이메일 알림 설정 : 중요한 이벤트 즉시 파악
추가 보안 조치 Port 2222 PasswordAuthentication no PubkeyAuthentication yes PermitRootLogin no [sshd] port = 2222
14. 대안 및 보완 도구 함께 사용하면 좋은 도구
DenyHosts : SSH 전용 차단 도구
CSF (ConfigServer Security & Firewall) : 종합 방화벽 솔루�
ModSecurity : 웹 애플리케이션 방화벽 (WAF)
OSSEC : 호스트 기반 침입 탐지 시스템
Snort/Suricata : 네트워크 침입 탐지 시스템
15. 실전 예제 완전한 설정 예제 [DEFAULT] bantime = 1 hfindtime = 10 mmaxretry = 5 destemail = admin@example.comsender = fail2ban@server.example.comaction = %(action_mwl)signoreip = 127.0 .0.1 /8 192.168 .1.0 /24 [sshd] enabled = true port = ssh,2222 filter = sshdlogpath = /var/log/auth.logmaxretry = 3 bantime = 24 h[nginx-http-auth] enabled = true port = http,httpsfilter = nginx-http-authlogpath = /var/log/nginx/error.logmaxretry = 3 [nginx-limit-req] enabled = true port = http,httpsfilter = nginx-limit-reqlogpath = /var/log/nginx/error.logmaxretry = 10 findtime = 60 [recidive] enabled = true filter = recidivelogpath = /var/log/fail2ban.logbantime = 1 wfindtime = 1 dmaxretry = 3
모니터링 대시보드 스크립트 #!/bin/bash clear echo "╔════════════════════════════════════════════════════╗" echo "║ Fail2ban Monitoring Dashboard ║" echo "╚════════════════════════════════════════════════════╝" echo "" echo "📊 Overall Status:" sudo fail2ban-client status echo "" 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 "" 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
참고 자료