Datadog

Datadog 탐지를 AWS WAF 자동 차단으로 연결하는 방법

Datadog Security Signal에서 AWS WAF IPSet까지 자동화하면서 원본 IP, 오탐, 동시 수정, 검증과 차단 만료를 함께 설계한 기준을 설명한다.

이 글의 목차자동화할 대상은 클릭이 아니라 판단 순서였다7
  1. 자동화할 대상은 클릭이 아니라 판단 순서였다
  2. 탐지 규칙은 확정 판정이 아니라 입력으로 받았다
  3. 원본 IP를 어디서 믿을지 먼저 정했다
  4. IPSet은 주소 한 줄을 추가하는 API가 아니었다
  5. WAF만으로는 차단 만료를 관리할 수 없다
  6. 사람이 다시 볼 기록까지 있어야 끝난다
  7. 참고 자료

운영 로그에서 위협적인 스캔 신호를 찾고 IP를 확인한 뒤 AWS WAF에 반영하는 일이 반복되고 있었다.
2026년 1월 27일부터 2월 23일까지 Datadog과 WAF 로그를 분석하고 차단한 완료 업무가 열 건 남아 있었다.

이 숫자를 공격 열 건으로 그대로 읽을 수는 없었다.
그래도 비슷한 분석과 차단 업무가 이어졌고, 사람이 로그와 주소를 옮기는 구간이 반복된다는 점은 분명했다.

이미 운영 중인 탐지 규칙과 방어 구조를 따라가며 Datadog 신호에서 WAF 차단 목록까지 이어지는 자동화를 만들었다.
목표는 복사 작업을 줄이는 데 그치지 않고, 자동화가 정상 사용자를 막지 않도록 판단과 멈춤 장치를 같은 흐름에 넣는 것이었다.

자동화할 대상은 클릭이 아니라 판단 순서였다

처음에는 “탐지된 IP를 WAF에 넣는다”는 한 줄로 보였다.
그대로 만들면 위험했다.

Datadog Cloud SIEM은 로그가 탐지 규칙과 맞으면 Security Signal을 만든다.
Security Signal은 보안 조사에 필요한 이벤트 묶음이며, 그 자체가 공격자 확정 판정은 아니다.

AWS WAF(Web Application Firewall)는 웹 요청을 규칙에 따라 허용하거나 막는 방화벽이다.
IPSet은 WAF 규칙에서 참조하는 IP 주소 또는 CIDR 목록이다.
CIDR은 하나의 IP나 주소 범위를 표현하는 표기법이다.

탐지 신호의 주소를 곧바로 영구 차단하면 다음 문제가 생긴다.

  • 회사나 제휴사의 정상 NAT 주소를 막을 수 있다.
  • 프록시 뒤의 공유 IP 하나가 여러 사용자를 대표할 수 있다.
  • 조작 가능한 헤더를 원본 IP로 믿을 수 있다.
  • 같은 IP를 여러 자동화가 동시에 수정하며 목록을 덮어쓸 수 있다.
  • 위험이 사라진 주소가 차단 목록에 계속 쌓일 수 있다.

NAT(Network Address Translation)는 여러 내부 사용자가 하나의 외부 IP를 공유하게 만드는 주소 변환 방식이다.
한 IP를 한 사람으로 간주하면 정상 사용자 전체를 함께 막을 수 있다.

자동화의 핵심은 신호에서 차단으로 가는 속도가 아니라, 그 사이의 검증과 되돌리기였다.

예를 들어 로그인 주소에 수백 번 다른 비밀번호를 넣는 시도와, 여러 관리자 경로를 빠르게 훑는 스캔은 자동 대응 후보가 될 수 있다.

그러나 대학교·회사·통신사처럼 여러 사용자가 하나의 IP를 공유하는 환경에서는 한 사람의 이상 행동 때문에 정상 사용자 전체가 막힐 수 있다.

경로의 민감도와 IP 공유 가능성을 함께 보지 않으면 탐지 정확도가 높아도 차단 결과는 나쁠 수 있다.

Datadog 보안 신호를 검증하고 허용 목록을 확인한 뒤 AWS WAF IPSet에 임시 반영하고 감사 기록과 자동 만료를 거치는 흐름
그림처럼 탐지와 차단 사이에는 IP 출처 검증과 허용 목록이 필요하고, 차단 뒤에는 감사 기록과 만료 경로가 필요하다. 자동화가 빠를수록 잘못된 판단을 되돌릴 장치도 가까워야 한다.

탐지 규칙은 확정 판정이 아니라 입력으로 받았다

실제 완료 기록에는 Datadog Detection Rule로 위협적인 스캔 신호를 탐지하고, 해당 IP를 WAF 차단 목록에 추가하는 workflow가 남아 있다.
Workflow는 여러 도구의 작업을 조건과 순서에 따라 실행하는 자동화 흐름이다.

공개 글에서는 내부 경로와 탐지 임계값을 그대로 싣지 않는다.
공격자가 회피 조건을 알 수 있고 정상 트래픽 구조도 드러날 수 있기 때문이다.

현재 같은 자동화를 만든다면 처음부터 Block으로 시작하지 않는다.
신호의 심각도, 반복 횟수, 요청한 경로와 알려진 정상 트래픽 여부를 함께 보고 초기에는 승인 단계를 두거나 WAF의 Count 동작으로 관찰한다.

Count는 요청을 막지 않고 규칙에 맞았다는 지표만 남긴다.
탐지 조건이 정상 사용자를 얼마나 포함하는지 먼저 확인할 수 있다.

Datadog workflow는 게시된 상태에서 보안 알림 규칙과 연결해야 자동으로 실행된다.
외부 시스템을 변경하는 action은 별도 자격 증명을 사용하므로, 누가 workflow와 연결 설정을 바꿀 수 있는지도 RBAC(Role-Based Access Control)로 제한해야 한다.
RBAC는 사용자의 역할에 따라 가능한 작업을 제한하는 권한 관리 방식이다.

자동화 수준은 다음처럼 나눌 수 있다.

상황우선 대응이유
새 탐지 규칙이거나 정상 트래픽과 겹칠 가능성이 큼Count로 관찰실제 요청을 막지 않고 오탐 범위를 측정할 수 있다
신호는 강하지만 공유 IP 가능성이 있음사람 승인 후 짧게 차단정상 사용자 영향과 근거를 한 번 더 확인한다
여러 독립 신호가 반복되고 허용 목록에도 없음짧은 TTL의 자동 차단피해 시간을 줄이되 자동 해제 경로를 남긴다
알려진 사내·제휴사 NAT 또는 모니터링 주소차단하지 않고 별도 조사한 주소가 여러 정상 주체를 대표할 수 있다

이 표는 당시 내부 탐지 임계값을 공개한 것이 아니라 현재 같은 시스템을 설계할 때 쓸 수 있는 운영 기준이다.

원본 IP를 어디서 믿을지 먼저 정했다

WAF는 요청을 직접 보며 출발지 IP를 확인할 수 있다.
CDN이나 로드 밸런서 같은 프록시가 앞에 있다면 X-Forwarded-For 같은 헤더에서 원래 주소를 읽도록 구성할 수도 있다.

문제는 모든 헤더를 신뢰할 수 없다는 점이다.
클라이언트가 직접 넣은 값을 프록시가 덮어쓰지 않는 구조라면 공격자가 다른 주소로 가장할 수 있다.

그래서 원본 IP 추출은 다음 조건과 묶어야 한다.

  1. 요청이 신뢰하는 프록시 경로를 실제로 통과했는지 확인한다.
  2. 그 프록시가 어느 위치의 헤더 값을 기록하는지 확인한다.
  3. IPv4는 /32, IPv6는 /128처럼 단일 주소 CIDR로 정규화한다.
  4. 사내 NAT, 모니터링 서비스와 제휴사 주소는 별도 허용 목록과 대조한다.
  5. 주소 형식이 잘못됐거나 근거 필드가 비어 있으면 차단하지 않는다.

허용 목록을 WAF의 가장 앞에서 무조건 Allow로 처리하는 방법도 조심해야 한다.
WAF는 낮은 우선순위 숫자부터 규칙을 평가하고 AllowBlock을 만나면 뒤의 규칙을 더 보지 않는다.
정상 주소라는 이유로 다른 공격 검사까지 전부 건너뛰게 만들 수 있으므로 Web ACL 전체의 규칙 순서를 함께 봐야 한다.

Web ACL은 WAF가 요청에 적용할 규칙과 우선순위를 모은 목록이다.

IPSet은 주소 한 줄을 추가하는 API가 아니었다

AWS WAFv2의 UpdateIPSet은 주소 하나만 덧붙이는 patch API가 아니다.
전달한 주소 목록으로 IPSet의 변경 가능한 전체 상태를 교체한다.

따라서 기존 값을 읽지 않고 새 주소 하나만 보내면 이미 차단 중인 주소가 사라질 수 있다.
현재 기준으로 안전한 흐름은 다음과 같다.

WAF IPSet을 동시 수정에 안전하게 갱신하는 흐름TypeScript단순화 예시변경 발생
async function addBlockedAddress(address: string) {
  const current = await waf.getIPSet({ id, name, scope });
  const addresses = [...new Set([...current.addresses, address])];

  await waf.updateIPSet({
    id,
    name,
    scope,
    addresses,
    lockToken: current.lockToken,
  });
}

이 코드는 당시 내부 구현을 복사한 것이 아니라 AWS API 계약을 설명하기 위한 단순화 예시다.

GetIPSet은 현재 주소 목록과 LockToken을 돌려준다.
LockToken은 내가 읽은 뒤 다른 변경이 있었는지를 확인하는 낙관적 잠금 값이다.
그사이 다른 작업이 목록을 바꾸면 WAFOptimisticLockException이 발생하며, 최신 목록을 다시 읽고 병합해 재시도해야 한다.

현재 이 자동화를 운영한다면 변경 직후 전 세계 모든 위치가 같은 상태라고 가정해서는 안 된다.
AWS 문서는 WAF 변경이 전파되는 동안 수초에서 수분 동안 위치별 상태가 잠시 다를 수 있다고 설명한다.
API 성공과 실제 차단 로그를 나눠 확인해야 한다.

WAF만으로는 차단 만료를 관리할 수 없다

WAF IPSet의 주소 항목에는 만료 시각 필드가 없다.
/32 주소와 “언제 제거할지”를 한 항목에 함께 저장할 수 없다는 뜻이다.

따라서 임시 차단을 만들려면 주소, 근거가 된 signal ID, 추가 시각, 만료 예정 시각과 변경 주체를 다른 저장소에 기록해야 한다.
EventBridge와 Lambda, 또는 예약 가능한 Datadog workflow가 만료된 주소를 다시 읽어 제거할 수 있다.

이 만료 구조는 당시 완료 기록에 구체적으로 남아 있지 않다.
WAF API에 TTL(Time To Live) 필드가 없다는 사실에서 도출한 현재 권장 설계다.

TTL은 데이터가 유효한 기간이다.
영구 차단이 꼭 필요한 주소와 일정 시간 뒤 다시 평가할 주소를 구분하면 목록이 끝없이 커지는 문제를 줄일 수 있다.

차단을 해제할 때도 GetIPSet으로 최신 목록과 LockToken을 다시 읽고, 대상 주소만 제거한 전체 목록을 보내야 한다.

추가와 제거가 같은 IPSet을 갱신하므로 한쪽만 동시 수정 충돌을 처리하면 만료 작업이 다른 차단을 되살리거나 지울 수 있다.

사람이 다시 볼 기록까지 있어야 끝난다

자동화가 완료됐다는 업무 기록은 남아 있지만 차단 건수, 오탐률과 절약한 운영 시간은 보존되지 않았다.
그 숫자를 추정해 성과로 만들지는 않았다.

확인할 수 있는 결과는 반복되던 분석·차단 업무 이후 Datadog 탐지 신호를 AWS WAF 반영으로 연결하는 workflow가 2026년 2월 24일 완료됐다는 것이다.

이 작업으로 사람이 주소를 복사하는 절차를 workflow 안으로 옮겼다.
그보다 중요한 변화는 탐지 근거, IP 정규화, 변경 충돌과 되돌릴 시간을 하나의 운영 계약으로 보게 된 점이었다.

자동 차단은 보안 판단을 없애는 기능이 아니다.
판단을 같은 순서로 반복하고, 잘못된 판단의 영향과 지속 시간을 제한하는 기능이어야 했다.

참고 자료

소신을 상징하는 고래 일러스트
작성자소신 · Soshin

직접 부딪힌 문제와 해결 과정을 다음에 다시 꺼내 볼 수 있도록 기록합니다.