어떤 서버든 조만간 플러딩(flooding) 공격을 받게 되며, 이는 서비스 부하 증가와 리소스 사용량 증대로 이어집니다. 인터넷상의 수많은 봇들은 취약점을 찾고 데이터를 수집하기 위해 웹사이트를 스캔합니다.
이러한 봇들은 악의적인 행동을 보이며, 서버 리소스를 낭비하지 않기 위해 차단해야 합니다.
이 글에서는 플러딩 공격에 대처하는 한 가지 방법을 다룹니다. DDoS 공격에 대처하기 위해서는 다른 서비스와 방법이 사용됩니다.
다음은 그러한 요청의 예시입니다:
100.xx.188.xx - - [10/Sep/2025:00:57:59 +0000] "GET /aa.php HTTP/1.1" 404 27 "-" "-"
100.xx.188.xx - - [10/Sep/2025:00:57:59 +0000] "GET /file.php HTTP/1.1" 301 162 "-" "-"
100.xx.188.xx - - [10/Sep/2025:00:57:59 +0000] "GET /file.php HTTP/1.1" 404 27 "-" "-"
100.xx.188.xx - - [10/Sep/2025:00:57:59 +0000] "GET /wp-file.php HTTP/1.1" 301 162 "-" "-"
100.xx.188.xx - - [10/Sep/2025:00:57:59 +0000] "GET /wp-file.php HTTP/1.1" 404 27 "-" "-"
100.xx.188.xx - - [10/Sep/2025:00:57:59 +0000] "GET /k.php HTTP/1.1" 301 162 "-" "-"
100.xx.188.xx - - [10/Sep/2025:00:57:59 +0000] "GET /k.php HTTP/1.1" 404 27 "-" "-"
100.xx.188.xx - - [10/Sep/2025:00:57:59 +0000] "GET /al.php HTTP/1.1" 301 162 "-" "-"
100.xx.188.xx - - [10/Sep/2025:00:57:59 +0000] "GET /al.php HTTP/1.1" 404 27 "-" "-"
100.xx.188.xx - - [10/Sep/2025:00:57:59 +0000] "GET /wp- HTTP/1.1" 301 162 "-" "-"
100.xx.188.xx - - [10/Sep/2025:00:58:00 +0000] "GET /wp- HTTP/1.1" 404 48273 "-" "-"
100.xx.188.xx - - [10/Sep/2025:00:58:00 +0000] "GET /admin.php HTTP/1.1" 301 162 "-" "-"
100.xx.188.xx - - [10/Sep/2025:00:58:00 +0000] "GET /admin.php HTTP/1.1" 404 27 "-" "-"
100.xx.188.xx - - [10/Sep/2025:00:58:00 +0000] "GET /file2.php HTTP/1.1" 301 162 "-" "-"
100.xx.188.xx - - [10/Sep/2025:00:58:00 +0000] "GET /file2.php HTTP/1.1" 404 27 "-" "-"
로그에서 볼 수 있듯이, 봇은 초당 약 9개의 요청을 서버로 보내고 있으며, 이는 상당히 많은 양입니다. 특히 여러 IP 주소를 가진 이러한 봇이 여러 개 있을 경우 가상 서버에 상당한 부하를 줄 수 있습니다.
우리의 목표는 정적 파일을 제외하고 너무 많은 정기적인 요청을 하는 IP 주소를 차단하는 것입니다. 동적 요청만이 부하를 발생시키므로 동적 요청만 계산할 것입니다.
1. Fail2ban 설치
apt install fail2ban
2. 설정
nano /etc/fail2ban/jail.local
[DEFAULT]
# 주요 설정
ignoreip = 127.0.0.1/8 ::1
bantime = 3600
findtime = 600
maxretry = 200
# 이메일 설정
destemail = corp@domain.tld
sender = fail2ban@domain.tld
sendername = Fail2Ban
mta = sendmail
# 기본 동작 (이메일 알림 포함)
action = %(action_mwl)s
[nginx-flood]
enabled = true
port = http,https
filter = nginx-flood
logpath = /var/log/nginx/*access*.log
maxretry = 200
findtime = 60
bantime = 3600
# action은 DEFAULT에서 상속되므로 중복할 필요 없음
2.1 필터 자체
nano /etc/fail2ban/filter.d/nginx-flood.conf
[Definition]
# 정적 파일을 계산에서 제외
failregex = ^<HOST> -.*"(GET|POST|HEAD) (?!.*\.(jpg|jpeg|png|gif|ico|css|js|woff|woff2|ttf|eot|svg|pdf|txt|xml)(\?.*)?$).* HTTP/\d\.\d".*
ignoreregex =
datepattern = ^[^\[]*\[({DATE})\s+({TIME})\s+[^\]]*\]
2.2 수정 사항
이메일 주소를 본인의 것으로 변경하는 것을 잊지 마세요:
destemail = corp@domain.tld
sender = fail2ban@domain.tld
2.3 트리거 임계값
필요한 경우, 오탐을 피하기 위해 자신에게 맞게 매개변수를 조정하세요:
maxretry = 200
findtime = 60
bantime = 3600
3. 서비스 시작
systemctl restart fail2ban
systemctl enable fail2ban
4. 보기 및 관리
4.1 차단된 IP 보기
iptables의 경우
iptables -L -n
fail2ban의 경우
fail2ban-client status nginx-flood
4.2 테스트
테스트 IP를 일시적으로 차단 목록에 추가
fail2ban-client set nginx-flood banip 1.2.3.4
차단 여부 및 이메일 수신 여부 확인
fail2ban-client set nginx-flood unbanip 1.2.3.4
No Comments Yet