1인 창업 일지 #13 Fail2ban을 중단, 과도한 보안이 오히려 독이 될 때
TL;DR
- Fail2ban 설정이 너무 민감해서 정상 사용자(나)까지 차단당함
- 여러 도메인에 적용되어 있어 한 번 밴당하면 모든 서비스 접근 불가
- 요즘 웹 스택에서는 전통적인 공격들이 대부분 무의미
- 결국 Fail2ban을 완전히 중단하기로 결정
사건의 발단, 내가 내 서버에서 밴당하다
어느 날 평소처럼 웹사이트 개발을 하다가 갑자기 모든 사이트에 접근이 안 되기 시작했다. 처음에는 DNS 문제인 줄 알았는데, 알고 보니 내 IP가 Fail2ban에 의해 차단된 것이었다.
로그를 확인해보니 이런 요청들 때문이었다.
101.36.106.89 - - [21/Aug/2025:01:55:48 +0900] "GET /favicon.ico HTTP/1.1" 404 134 "-" "Go-http-client/1.1"
101.36.106.89 - - [21/Aug/2025:01:55:48 +0900] "GET /sitemap.xml HTTP/1.1" 404 134 "-" "Go-http-client/1.1"
101.36.106.89 - - [21/Aug/2025:01:55:48 +0900] "GET /robots.txt HTTP/1.1" 404 134 "-" "Go-http-client/1.1"
PlaintextGoogle Analytics나 Search Console에서 보낸 것으로 추정되는 정상적인 요청들이었는데, 404 에러가 발생했다는 이유로 악성 사용자로 분류된 것이다.
문제가 된 Fail2ban 설정
내 설정을 살펴보니 문제가 한 눈에 보였다.
# 404 스캔 차단 - 1분 내 30번 404 발생시 1시간 차단
[nginx-404-scan]
enabled = true
maxretry = 30
findtime = 60
bantime = 3600
# 환경설정 파일 스캔 - 5분 내 2번 시도로 7일 차단
[nginx-env-scan]
enabled = true
maxretry = 2
findtime = 300
bantime = 604800 # 7일!
# Rate Limiting - 5분 내 5번 요청으로 1시간 차단
[nginx-limit-all]
enabled = true
maxretry = 5
findtime = 300
bantime = 3600
Nginx왜 정상 사용자가 걸리는가?
1. favicon.ico의 함정
웹사이트에서 favicon.png를 사용하고 있는데도 브라우저와 봇들은 여전히 /favicon.ico를 요청한다. 이는 웹 표준의 역사적 유산 때문이다.
- 브라우저는 HTML을 파싱하기 전에 기본 경로를 먼저 시도
- 검색엔진 봇들은 호환성을 위해 .ico 파일을 우선 탐색
- Google Analytics, Search Console 등도 마찬가지
결과적으로 정상적인 웹사이트 운영만으로도 404 에러가 계속 발생한다.
2. 개발 환경에서의 함정
개발하면서 자연스럽게 발생하는 행동들
- 페이지 새로고침을 여러 번
- 잘못된 URL로 테스트
- API 엔드포인트 확인
- 정적 파일 로딩 시 일시적 404
이런 것들이 쌓이면 쉽게 임계치를 넘는다.
3. 여러 도메인의 위험성
더 큰 문제는 Fail2ban이 IP 기반으로 동작한다는 점이다.
# 하나의 IP가 차단되면 모든 도메인에서 접근 불가
domain1.com ❌
domain2.com ❌
domain3.com ❌
Plaintext한 사이트에서 실수로 밴당하면 운영하는 모든 웹서비스에 접근할 수 없게 된다.
요즘 웹 스택에서는 대부분 무의미한 공격들
Fail2ban으로 차단하려던 공격들을 다시 살펴보니, 요즘 환경에서는 대부분 위협이 되지 않는다.
전통적인 공격 vs 현대적 방어
# 이런 공격들은 이제 대부분 무의미
GET /.env # 웹 접근 불가능하게 설정됨
GET /wp-admin/ # WordPress 안 쓰면 관계없음
GET /phpmyadmin/ # PHP 안 쓰면 소용없음
GET /config.php # 정적 사이트에는 무의미
Plaintext현대적 웹 스택의 기본 보안
프레임워크 레벨:
- Next.js, React: XSS, CSRF 자동 방어
- FastAPI, Django: SQL 인젝션, 입력 검증 기본 제공
- Express.js: Helmet 등으로 보안 헤더 자동 설정
인프라 레벨:
- Cloudflare, AWS WAF: 대부분 공격 자동 차단
- Docker: 컨테이너 격리로 시스템 침투 어려움
- HTTPS: 기본 적용으로 중간자 공격 방어
아키텍처 레벨:
- JAMstack: 서버사이드 공격 벡터 자체가 없음
- API 기반: 전통적인 파일 기반 공격 무효
- 마이크로서비스: 공격 범위 제한
결론: Fail2ban 완전 중단
결국 이런 이유들로 Fail2ban을 완전히 중단하기로 결정했다.
# 1. 모든 차단 해제
sudo fail2ban-client unban --all
# 2. 서비스 중지 및 비활성화
sudo systemctl stop fail2ban
sudo systemctl disable fail2ban
Plaintext대안적 보안 전략
Fail2ban 대신 이런 것들에 집중하기로 했다.
1. 애플리케이션 보안 강화
- 입력 검증 철저히
- 인증/인가 로직 견고하게
- 보안 헤더 적절히 설정
2. 인프라 보안 활용
- Cloudflare Pro 사용
- 필요하면 AWS WAF 적용
- 정기적인 보안 업데이트
교훈
보안은 적당히가 좋다. 과도한 보안 설정이 오히려
- 정상 사용자를 차단하고
- 개발 생산성을 떨어뜨리며
- 실제 위협에 대한 집중을 방해할 수 있다
요즘 웹 환경에서는 프레임워크와 클라우드 서비스의 기본 보안만으로도 충분히 안전하다.
무분별한 Fail2ban 설정보다는 코드 품질과 아키텍처 설계에 더 신경 쓰는 것이 실용적인 보안 전략이라고 생각한다.
“완벽한 보안은 존재하지 않는다. 하지만 완벽하게 사용할 수 없는 시스템은 확실히 존재한다.”