개발 slecs

YAML 공백 오류로 막히던 IP 필터 설정 파싱 수정

목차

ActuatorIpFilter에서 allowed-ips 목록을 읽어올 때 .trim()을 빠뜨린 한 줄 때문에 IP 필터가 조용히 오작동하고 있었다. 로그상으로는 요청이 들어오고 있는데 필터가 통과를 거부하는 상황. 처음엔 IP 자체가 잘못 설정된 줄 알았다.

재현 절차를 밟아보니 YAML에 공백이 섞여 있었다. 아래처럼 리스트로 적은 값들 사이에 의도치 않은 스페이스가 끼어 있으면 파싱 결과가 "127.0.0.1 " 같은 형태로 나온다.

actuator:
  ip-filter:
    allowed-ips: 127.0.0.1, 10.0.0.1, 192.168.1.100

이걸 ,로 스플릿하면 각 원소에 앞뒤 공백이 붙은 채로 들어온다. equals() 비교에서 당연히 불일치. "127.0.0.1" != "127.0.0.1 ". 코드에서 IP를 비교하는 시점에 .trim()을 한 번만 넣으면 해결되는 문제였는데, 내부 클래스 안에 파싱 로직이 묻혀 있어서 영향 범위 파악에 시간이 좀 걸렸다.

수정 흐름은 단순했다: 재현 → 원인 파악 → 최소 범위 수정 → 배포. 이 루틴이 요즘은 손에 익어가고 있다.

자주 나오는 버그 패턴

이번 건은 전형적인 YAML 파싱 실수였는데, 비슷한 맥락에서 반복되는 패턴들을 묶어보면 이렇다.

패턴 증상
null 체크 순서 오류 NPE (NullPointerException)
경로 예외 처리 누락 필터에서 정상 요청 차단
YAML 공백 혼용 설정값 파싱 실패
import 누락 컴파일 에러

이 중 "YAML 공백 혼용"이 까다로운 이유는 에러가 명확하게 터지지 않는다는 점이다. 컴파일도 되고 앱도 뜨는데 특정 IP에서만 접근이 거부된다. 실제 운영 환경에서 재현하기 전까지는 코드 문제인지 설정 문제인지 판단 자체가 어렵다.

방어적으로 작성한다면 파싱 시점에 바로 trim을 거는 게 맞다. 설정 소비 쪽에서 방어하는 것보다 입구에서 정규화하는 편이 훨씬 안전하다.

List<String> allowedIps = Arrays.stream(raw.split(","))
    .map(String::trim)
    .filter(s -> !s.isEmpty())
    .collect(Collectors.toList());

설정값이 외부에서 오는 경우 - 환경 변수, YAML, DB - 는 어디서 왔든 파싱 직후에 trim + empty 필터를 거는 걸 습관으로 잡아두면 이런 류의 버그를 사전에 차단할 수 있다.

운영 관점에서 본 Rate Limit과 블랙리스트 구조

이번 수정 대상이 IP 필터였던 만큼, 연관된 보안 레이어도 같이 점검했다.

Rate Limit 설계에서 자주 빠지는 함정은 숫자 자체에 집중한다는 거다. "초당 100개 허용" 같은 수치가 기준이 되면 정작 중요한 질문을 놓친다 - 이 수치가 정상 트래픽 패턴과 얼마나 맞는지, 경계 구간에서 버스팅이 가능한지.

Redis의 슬라이딩 윈도우 방식은 고정 윈도우 대비 경계 버스팅에 강하다. 고정 윈도우에서는 윈도우가 초기화되는 순간 직전+직후에 요청을 두 배로 몰아넣는 게 가능하지만, 슬라이딩 윈도우는 항상 직전 N초를 기준으로 카운트하기 때문에 그 틈이 없다. 다만 Redis가 단일 장애점이 되지 않도록 연결 풀 설정과 타임아웃을 반드시 같이 챙겨야 한다. Rate Limit 레이어가 Redis 연결 실패로 전체 요청을 막아버리는 사고는 꽤 고전적인 실수다.

블랙리스트 자동 등록은 수동 대응의 속도 한계를 보완한다. 공격성 요청을 감지하면 DB에 바로 기록하고 다음 요청부터 즉시 차단하는 구조인데, 여기서 챙겨야 할 지점이 세 가지다.

  • 오탐 가능성: 로드 테스트나 배치 작업이 봇으로 오해받는 경우를 예외 처리해야 한다. IP 레인지나 User-Agent 기반 화이트리스트를 먼저 체크하는 레이어를 두는 게 안전하다.
  • 만료 설정: 영구 차단 대신 TTL을 걸어두면 오탐 복구가 가능하다. "일단 막고 나중에 풀자"는 운영 부담이 크다. 처음부터 24시간이나 48시간 TTL로 설계하는 게 낫다.
  • 알림 연동: 자동 차단이 발생할 때마다 슬랙이나 디스코드로 알림을 보내야 한다. 자동화라고 해서 블랙박스가 되면 나중에 왜 막혔는지 추적이 안 된다.

작업 규모 자체는 크지 않았다. 하지만 IP 필터가 조용히 오작동하는 상태를 방치하면 접근 제어 전체의 신뢰도에 영향을 준다. 작은 수정이라도 운영 안정성에 직결되는 경로에 있으면 우선순위를 높여서 처리하는 게 맞다고 생각한다.

댓글 0

첫 댓글 달아줘.