개발 slecs

서버 보안 필터 강화와 블랙리스트 자동 차단 도입

목차

운영 서버에 붙어있는 보안 필터는 꽤 오래 손을 안 댔다. 완화 상태로 놔둔 Rate Limit 임계값이 그대로 남아 있었고, 블랙리스트는 이슈가 생길 때마다 수동으로 넣는 구조였다. 실시간으로 들어오는 스캐닝 요청에 수동 대응은 속도가 안 나온다. 이번에 임계값 재조정, 패턴 감지 확장, 블랙리스트 자동 등록 이 세 가지를 한 번에 정리했다.

처리 흐름과 변경 내용

필터 미들웨어가 요청을 처리하는 순서는 다음과 같다.

요청 수신
  → 화이트리스트 IP 확인
  → 봇 UA / 의심 경로 감지
  → Rate Limit 체크 (Redis 슬라이딩 윈도우)
  → 차단 / 블랙리스트 등록 / 통과

순서가 중요하다. 화이트리스트 체크를 맨 앞에 두는 건 모니터링 에이전트나 내부 서비스가 Rate Limit에 걸리는 걸 막기 위해서다. 봇 UA 감지를 Rate Limit보다 먼저 처리하는 건, 패턴이 명확한 공격은 굳이 Redis 조회까지 갈 필요 없이 바로 끊는 게 낫기 때문이다. 순서 하나가 Redis 부하를 꽤 줄여준다.

이번 작업에서 변경된 항목을 정리하면:

항목 기존 변경 후
Rate Limit 임계값 완화 상태 강화 (1분 기준 하향)
공격 패턴 감지 기본 UA 목록 의심 경로 + 페이로드 확장
블랙리스트 등록 수동 DB 자동 등록

Rate Limit에 슬라이딩 윈도우를 쓰는 이유는 고정 윈도우의 경계 문제 때문이다. 1분 고정 윈도우면 59초에 100회 + 다음 윈도우 시작 1초에 100회, 합산 2초 안에 200회가 허용된다. 슬라이딩 윈도우는 그 틈을 막는다. Redis ZADD + ZREMRANGEBYSCORE + ZCARD 조합으로 구현하는 게 흔한 패턴이고, Lua 스크립트로 원자성 보장하는 게 일반적이다.

예외 경로 처리와 AJAX 제외

예외 경로 설정이 여기서 제일 신경 쓰이는 부분이었다. 헬스체크 엔드포인트, 메트릭 수집 경로가 필터에 걸리면 모니터링이 죽거나 로드밸런서가 헬스 체크 실패로 인스턴스를 내린다. 보안 강화하다가 운영 장애를 만드는 상황은 피해야 한다. 해당 경로들은 필터 진입 전에 명시적으로 스킵하도록 빼뒀다.

AJAX 요청은 Rate Limit 카운트에서 제외하는 옵션도 추가했다. 페이지 하나 로드할 때 AJAX 요청이 수십 개 나가는 구조라면, 일반 사용자가 페이지 몇 개 탐색하는 것만으로 임계값에 닿는다. X-Requested-With: XMLHttpRequest 헤더나 Content-Type 기반으로 판별해서 제외하는 방식인데, 이 처리는 UA 스푸핑으로 우회 가능하다는 점은 감수해야 한다. 어차피 AJAX 제외는 정상 트래픽 보호 목적이지, 공격 차단 로직이 아니기 때문에 트레이드오프로 봤을 때 괜찮다고 판단했다.

블랙리스트 자동 등록 구조

공격성 요청이 들어왔을 때 수동으로 IP를 넣는 건 대응 속도가 느리다. 패턴 감지에서 걸린 IP를 DB에 자동으로 올리고, 다음 요청부터 즉시 차단하는 구조로 바꿨다. 이렇게 하면 스캐닝 시도가 들어왔을 때 첫 요청에 감지하고 그 이후는 Redis나 DB에서 바로 차단으로 떨어진다.

자동 등록에서 반드시 챙겨야 할 것들:

  • 오탐 관리: 로드 테스트, 배치 작업, CDN 아웃바운드 IP가 봇으로 오해받는 케이스가 생긴다. 테스트 전에 해당 IP를 화이트리스트에 넣는 습관이 필요하고, 자동 등록 조건을 충분히 좁혀야 한다.
  • TTL 설정: 영구 차단 대신 TTL을 두는 게 낫다. 오탐이 발생했을 때 복구 수단이 없으면 조용히 서비스 장애로 번진다. IP가 유동이면 실제 공격자 IP도 바뀌기 때문에 영구 차단의 실효성도 생각보다 낮다.
  • 알림 연동: 자동 차단 발생 시 슬랙이나 디스코드로 알림을 붙여놨다. 자동화가 돌고 있다는 게 눈에 보여야 신뢰가 생기고, 오탐도 빨리 잡힌다.

작업 규모 자체는 크지 않았다. 임계값 몇 개 수정하고, 패턴 목록 보충하고, 자동 등록 로직 붙인 게 전부다. 근데 이런 작은 조정들이 실제로 운영 중에 차이를 만든다. 조용히 들어오는 스캐닝 트래픽이 줄어드는 걸 로그에서 확인하면 이런 작업이 괜히 한 게 아니라는 게 느껴진다.

댓글 0

첫 댓글 달아줘.