Prometheus 수집 차단 방지를 위한 봇 필터 경로 설정 개선
목차
관찰 가능성(observability) 스택을 제대로 쓰려면 수집 파이프라인이 끊기지 않아야 한다. 그게 흔들리면 Grafana 대시보드는 빈 그래프만 보여주고, 장애를 뒤늦게 알게 된다. 이번 작업은 딱 그 지점이었다. Prometheus가 /actuator/prometheus를 주기적으로 긁어가야 하는데 봇 차단 필터가 그 요청을 먼저 가로막고 있었다.
왜 막혔나 - BotBlockFilter와 actuator 경로 충돌
구조는 단순하다. Spring Boot Actuator가 /actuator/prometheus 엔드포인트로 메트릭을 노출하고, Prometheus가 설정된 간격마다 HTTP GET으로 가져간다. 문제는 앞단에 BotBlockFilter가 있었다는 것.
Actuator 엔드포인트는 외부에 열면 안 된다. 누구나 /actuator/env나 /actuator/heapdump를 긁어갈 수 있으면 그게 보안 구멍이니까. 그래서 IP 허용 목록 기반 필터를 달아뒀는데, Prometheus 수집 서버가 그 목록에 없거나 봇 패턴으로 걸러지면 메트릭 수집이 조용히 끊긴다. 로그에는 403이 쌓이고, Grafana는 "No data"를 보여주지만 서비스 자체는 멀쩡하니 바로 눈에 안 띈다.
필터 설정에서 /actuator 하위 경로를 봇 차단 체크에서 제외하고, IP 필터 허용 목록으로만 접근을 통제하는 방향으로 정리했다.
management:
endpoints:
web:
exposure:
include: health,prometheus
metrics:
export:
prometheus:
enabled: true
BotBlockFilter 쪽에서는 경로 제외 목록에 /actuator/**를 추가했다. 단, 이 제외는 "봇 차단 로직을 건너뛴다"는 의미이지, IP 필터까지 우회시킨다는 뜻이 아니다. 두 필터는 별도 체인에서 각자 역할을 한다. 이 구분을 명확히 안 하면 나중에 "왜 actuator가 외부에서 열려?"라는 혼란이 생긴다.
작업 중에 YAML 파싱 문제로 한 번 막혔다. 허용 IP 목록을 콤마로 구분해서 설정 파일에 넣었는데, 앞뒤 공백이 섞여서 비교가 틀어졌다. trim() 처리 한 줄 추가로 해결됐지만, 이런 류의 버그가 운영 환경에서 조용히 살아있으면 나중에 디버깅이 은근히 오래 걸린다. YAML에서 문자열 값 비교할 때 공백 처리는 습관적으로 챙기는 게 낫다.
Grafana datasource와 대시보드도 이번에 같이 점검했다. Prometheus 타겟 설정을 수정하면서 Zipkin/Tempo 연동 엔드포인트도 조정했다.
봇 필터 경로 제외 설계 시 고려할 것
경로 제외 목록을 무작정 넓히면 보안 구멍이 생긴다. 반대로 너무 좁히면 수집 파이프라인이 막힌다. 경험상 이 트레이드오프를 정리하는 방식은 아래 표처럼 구분하는 것이다.
| 경로 유형 | 봇 필터 제외 | IP 필터 적용 | 비고 |
|---|---|---|---|
/actuator/prometheus |
O | O | Prometheus 수집 서버 IP만 허용 |
/actuator/health |
O | 선택적 | 로드밸런서 헬스체크 허용 필요 |
/actuator/** (나머지) |
X | O | 내부망 또는 VPN만 |
/api/** |
X | X | 일반 트래픽, 봇 필터 정상 작동 |
봇 필터에서 경로를 제외할 때는 "이 경로가 외부 공격 벡터가 될 수 있나"를 먼저 따진다. /actuator/prometheus는 읽기 전용 메트릭 엔드포인트라 그 자체로 위험도가 낮지만, IP 제한을 병행하지 않으면 누군가 메트릭 데이터를 계속 긁어갈 수 있다.
블랙리스트 자동 등록 구조
봇 필터 개선하면서 자동 차단 구조도 같이 정리했다. 공격성 요청을 감지했을 때 수동으로 대응하면 속도가 느리다. DB에 자동 등록하고 다음 요청부터 즉시 차단하는 구조가 훨씬 실용적이다.
자동 등록 로직 대략적인 흐름:
요청 수신
→ BotBlockFilter 통과 여부 판단
→ 공격 패턴 감지 (임계값 초과 등)
→ DB 블랙리스트 자동 INSERT (TTL 포함)
→ 해당 IP/UA 다음 요청부터 즉시 403
→ 슬랙/디스코드 알림 발송
여기서 놓치기 쉬운 게 오탐 처리다. 로드 테스트 도구나 배치 작업이 봇으로 오해받으면 운영 중에 내부 서비스가 스스로를 차단하는 상황이 생긴다. 예외 IP 목록을 별도로 유지하고, 자동 차단 전에 해당 IP가 예외 목록에 있는지 먼저 확인하는 단계를 끼워야 한다.
TTL도 중요하다. 영구 차단은 오탐 복구가 번거롭다. 24시간이나 72시간 TTL을 두면 오탐된 경우 자동으로 풀리고, 실제 공격 IP는 재시도 시 다시 잡힌다.
알림 연동은 자동화 시스템을 믿기 위한 장치다. 얼마나 차단이 발생하는지, 어떤 패턴인지 슬랙으로 계속 보면 필터 기준이 적절한지 감이 온다. 조용히 차단하고 모르고 있으면 오탐도 모르고 지나간다.
작업 규모 자체는 크지 않았다. 경로 제외 설정 몇 줄, YAML 공백 처리 한 줄. 근데 이게 없으면 메트릭이 조용히 끊기고, 끊긴 줄도 모르고 지나간다. 관찰 가능성 스택은 신뢰할 수 있을 때만 의미가 있으니까, 수집 파이프라인 자체가 안정적으로 돌아가게 하는 게 먼저다.
댓글 0
첫 댓글 달아줘.