Cloudflare Logpush IP 마스킹: Transformers SQL로 내보내기 전 처리하기

Cloudflare Logpush IP 마스킹|등록 · 수정 |팩트체크 |0|약 5분 읽기
합성 IPv4·IPv6 로그가 SQL 변환을 거쳐 IP가 REDACTED로 가려진 뒤 외부로 전송되는 과정을 표현한 개념 썸네일
합성 IPv4·IPv6 로그가 SQL 변환을 거쳐 IP가 REDACTED로 가려진 뒤 외부로 전송되는 과정을 표현한 개념 썸네일

Quick Answer

Cloudflare 로그 IP를 전송 전에 가리고 실제 도착까지 어떻게 확인하나요?

Cloudflare Logpush에서 IP를 외부 전송 전에 가리려면 Transformers SQL로 필요한 필드만 선택하고 IP 값을 치환합니다. 같은 데이터셋의 호환 NDJSON 작업이 대상이며 기존 필터는 SQL로 옮겨야 합니다. 변환 실패 시 원본을 대신 보내지 않으므로 목적지 로그와 전달 상태까지 확인하세요.

Reading Guide

이 글에서 해결할 문제

이런 분께
외부 SIEM·저장소에 보내는 로그의 IP와 필드를 줄이려는 운영자
읽고 나면
IP 치환 SQL을 시험하고 필터 전환·목적지 출력·실패 상태를 확인합니다.
다루는 범위
합성 데이터 SQL 모의 실행과 오프라인 검사 도구를 로컬 검증했습니다. Cloudflare 미리보기·필터 전환·실제 전달은 미검증입니다.
직접 확인
  • NDJSON·데이터셋을 확인하고 기존 필터를 같은 논리의 SQL로 옮깁니다.
  • 합성 IPv4·IPv6 미리보기 후 실제 도착 파일의 네 필드와 시험 RayID를 대조합니다.
  • last_error 시각·error_message·last_complete와 Health를 함께 확인합니다.
링크가 복사되었습니다

상황별 바로가기: IPv4·IPv6 마스킹 범위 · 기존 필터 전환 · 도착 로그 검사

2026년 10월 12일은 신규 출시일이 아닌 공식 심층 해설 게시일입니다. 기능은 앞선 Birthday Week에 정식 제공됐습니다. 정식 제공 배경·공식 해설

전송 전 변환은 로그 수집 제한과 무엇이 다른가요?

경로는 Cloudflare 로그 → Transformer SQL → Logpush 목적지입니다. 목적지가 받기 전에 행과 필드를 줄이는 방식이므로 외부에 원본을 보낸 뒤 삭제하는 작업과 시점이 다릅니다. Cloudflare 내부 수집 전체를 중단하거나 이미 저장한 로그를 지우는 설정으로 이해하면 안 됩니다.

생성 단계의 수집 범위를 다루는 GitHub Copilot 텔레메트리 설정과도 구분하세요. 이번 글은 Cloudflare에서 외부로 내보내는 경로의 가공을 설명하며, 제품별 수집 설정을 공유하지 않습니다.

플랜·데이터셋·NDJSON 조건 확인

공식 해설은 Free·Pro·Business·Enterprise에서 Transformers를 제공한다고 안내합니다. 계정에서 필요한 데이터셋과 작업을 사용할 수 있는지는 별도로 확인하세요. 플랜 안내

확인 항목적용 전 판단
출력 형식NDJSON 작업인지 확인. CSV 작업은 연결 대상이 아님
데이터셋SQL의 FROM과 작업의 dataset 일치
작업 범위계정 단위인지 zone 단위인지, 대상 ID가 맞는지
기존 필터filter를 SQL WHERE로 옮길 계획과 원래 설정 보관
API 권한대상에 맞는 Logs Write 권한의 토큰
목적지 스키마변경된 필드 이름·자료형을 SIEM이나 수신기가 처리하는지

NDJSON·동일 데이터셋·필터 배타 조건은 Transformers 설정 문서를 기준으로 확인합니다. 출력 형식은 output_options.output_type에 ndjson 또는 csv로 표시됩니다. 확장자만 바꾸는 방식으로 CSV 작업을 전환하지 말고 수신기 형식도 함께 점검하세요. 근거: Logpush 출력 옵션

기능 사용 가능과 무료 사용은 같은 의미가 아닙니다. Logpush는 변환 입력량과 성공적으로 전달한 출력량을 나눠 측정하며 목적지 서비스의 비용도 별도입니다. 이번 예제의 바이트 감소만으로 월 비용 절감액을 계산하지는 않았습니다. 근거: 변환·내보내기 사용량과 요금 범위

1단계: 보낼 필드와 IP 마스킹 범위 정하기

아래 SQL은 IP의 일부 구간을 남기지 않고 원값 전체를 일정한 문자열로 대체합니다. IP별 분석을 포기하는 대신 주소 형식별 누락을 줄이기 위한 이 예제의 선택입니다. 남길 필드는 ray_id·status·client_ip_redacted·provider 네 개로 한정합니다.

공식 해설의 부분 가림 예시는 점으로 구분된 IPv4의 뒤쪽 숫자를 정규식으로 바꿉니다. 이 패턴을 IPv6에도 그대로 적용하면 치환 대상이 없어 원문이 남을 수 있습니다. 이는 예제 패턴의 적용 범위를 보고 내린 판단이며, 서비스 장애라는 뜻은 아닙니다. 부분 마스킹을 선택한다면 IPv6와 매핑 주소를 포함한 별도 규칙을 검증해야 합니다.

또 ClientIP만 가렸다고 다른 민감정보까지 없어지는 것은 아닙니다. HTTP 로그에는 쿼리 문자열을 포함하는 ClientRequestURI, 헤더·쿠키·다른 IP 필드 등이 존재할 수 있습니다. 이 예제는 필요한 열을 열거해 나머지를 제외합니다. RayID처럼 남긴 식별자도 다른 데이터와 연결할 수 있는지 검토하세요. 근거: HTTP Requests 필드 정의

2단계: 합성 IPv4·IPv6 입력 로그 준비

다음은 실제 운영 로그가 아닌 편집부 작성 합성 데이터입니다. 문서용 IPv4 대역과 IPv6 접두사를 사용했고 URI의 이메일·세션 값도 가짜입니다. IPv4 문서용 주소 · IPv6 문서용 주소

{"RayID":"0000000000000001","ClientIP":"203.0.113.24","EdgeResponseStatus":403,"ClientRequestURI":"/login?email=sample%40example.invalid","ClientRequestUserAgent":"SyntheticProbe/1.0"}
{"RayID":"0000000000000002","ClientIP":"2001:db8::42","EdgeResponseStatus":502,"ClientRequestURI":"/check?client_ip=2001:db8::42","ClientRequestUserAgent":"SyntheticProbe/1.0"}
{"RayID":"0000000000000003","ClientIP":"198.51.100.17","EdgeResponseStatus":200,"ClientRequestURI":"/healthz","ClientRequestUserAgent":"SyntheticProbe/1.0"}
{"RayID":"0000000000000004","ClientIP":"::ffff:192.0.2.10","EdgeResponseStatus":404,"ClientRequestURI":"/missing?session=synthetic-only","ClientRequestUserAgent":"SyntheticProbe/1.0"}

입력 NDJSON 다운로드. 각 줄이 JSON 객체 하나이며 JSON 배열 파일은 아닙니다. ClientIP는 문자열, EdgeResponseStatus는 정수로 두어 데이터셋의 자료형에 맞췄습니다. 이 최소 샘플은 전체 HTTP 로그 스키마를 재현한 파일이 아닙니다.

3단계: Transformers SQL 작성

SELECT
  RayID AS ray_id,
  EdgeResponseStatus AS status,
  '[REDACTED]' AS client_ip_redacted,
  'cloudflare' AS provider
FROM http_requests
WHERE EdgeResponseStatus >= 400

redact-ip.sql 다운로드. WHERE는 이 글의 시험 정책이며 실제 운영 필터를 대신 추정한 조건이 아닙니다. 기존 작업의 조건이 다르면 그 의미를 유지하도록 수정해야 합니다.

SELECT에 원본 ClientIP와 URI를 넣지 않고 마스킹 결과에 새 이름을 부여했습니다. 따라서 SIEM에서 client_ip_redacted를 IP 주소형으로 강제 파싱하지 않도록 매핑도 바꿔야 합니다. 별칭·상수·조건식의 기본 구조는 SQL SELECT 문서에서 확인할 수 있습니다. Transformers는 이 방언의 일부 기능만 지원하므로 다른 DB의 복잡한 쿼리를 그대로 가져오지 마세요.

SELECT * 뒤에 가린 IP를 추가하면 원본 IP도 남는 쿼리가 될 수 있습니다. 출력에 허용할 열을 직접 적고, 나중에 데이터셋에 열이 추가되더라도 자동으로 함께 나가지 않는지 검토하는 편이 목적에 맞습니다.

로컬 모의 결과: 입력 4건에서 출력 3건

동일한 SQL을 Python 표준 라이브러리의 SQLite 메모리 DB에서 실행했습니다. 상태 200인 한 건이 제외됐고, 남은 세 건의 원본 IP·URI·User-Agent 표식이 출력에 없는 것을 확인했습니다.

{"ray_id":"0000000000000001","status":403,"client_ip_redacted":"[REDACTED]","provider":"cloudflare"}
{"ray_id":"0000000000000002","status":502,"client_ip_redacted":"[REDACTED]","provider":"cloudflare"}
{"ray_id":"0000000000000004","status":404,"client_ip_redacted":"[REDACTED]","provider":"cloudflare"}

위 결과는 로컬 SQL 모의 출력입니다. Cloudflare 미리보기 응답이나 실제 전달 로그가 아닙니다. SQLite와 Cloudflare의 DataFusion 실행 환경은 다르므로 데이터셋 검증·형 변환·런타임 제한까지 통과했다는 증거로 사용할 수 없습니다.

simulate.py를 입력 NDJSON·SQL과 같은 폴더에 저장한 뒤 아래 명령으로 재현할 수 있습니다. 확인한 모의 출력 NDJSON도 함께 제공합니다. 실제 배달 로그의 행 순서는 이 출력과 같다고 가정하지 말고 ray_id로 대조하세요.

python3 simulate.py

4단계: Transformer Studio와 API 미리보기

대시보드 Logpush에서 Transformer Studio를 열고 http_requests 데이터셋을 선택합니다. SQL을 입력해 Run으로 제공 샘플을 확인한 뒤 저장합니다. Studio의 미리보기와 목적지 연결은 별도 단계입니다. 근거: Studio 작성·미리보기·연결 순서

이 글의 합성 입력을 지정하려면 API 미리보기 요청을 사용할 수 있습니다. 본문은 NDJSON 여러 줄이 아니라 sql과 input 객체 하나입니다. 아래 파일은 요청 본문이며 성공 응답이 아닙니다.

대상 CF_ACCOUNT_ID와 Logs Write 권한의 CLOUDFLARE_API_TOKEN을 셸 환경에 준비한 뒤 각 파일을 개별로 시험합니다. 토큰은 파일에 넣지 않습니다.

curl --fail-with-body --show-error \
  --request POST \
  --header "Authorization: Bearer ${CLOUDFLARE_API_TOKEN}" \
  --header 'Content-Type: application/json' \
  --data-binary @preview-ipv6.json \
  "https://api.cloudflare.com/client/v4/accounts/${CF_ACCOUNT_ID}/logpush/transformers/preview"

HTTP 상태와 success·errors·result를 함께 확인합니다. 통과 대상은 네 필드와 치환 값을, 제외 대상은 출력을 확인하세요. API 문서는 제외한 경우 result가 null이라고 설명합니다. 미리보기 응답 형식

5단계: 기존 필터를 SQL로 옮기고 연결

기존 필터가 있다면 먼저 보관하고 같은 논리의 WHERE를 만듭니다. 예를 들어 EdgeResponseStatus의 geq 400 조건은 이 글의 >= 400에 대응합니다. 여러 조건의 AND·OR·괄호까지 유지해야 합니다. 근거: Logpush 필터 연산자·조건 의미

대시보드에서는 기존 필터를 SQL 조건으로 변환해 제시하므로 이를 WHERE에 복사해 의미를 확인합니다. API는 이 작업을 자동으로 해주지 않습니다. 같은 작업 갱신 요청에서 filter를 비우고 transformer_id를 지정해야 하며, 필터가 남아 있으면 400 오류가 납니다. 근거: 필터 전환 조건

{
  "filter": "",
  "transformer_id": 42
}

갱신 본문 예제의 42는 예시 ID입니다. 저장한 실제 Transformer ID로 바꾸고 attach-transformer.json으로 저장하세요. 원래 조건이 SQL에 포함됐는지 미리보기로 확인한 뒤 별도 시험 작업에 적용합니다.

curl --fail-with-body --show-error \
  --request PUT \
  --header "Authorization: Bearer ${CLOUDFLARE_API_TOKEN}" \
  --header 'Content-Type: application/json' \
  --data-binary @attach-transformer.json \
  "https://api.cloudflare.com/client/v4/zones/${CF_ZONE_ID}/logpush/jobs/${CF_JOB_ID}"

위 주소는 이 글의 zone 단위 HTTP 작업 예시입니다. 계정 단위 작업은 accounts 경로와 계정 ID를 사용합니다. 목적지·출력 옵션을 불필요하게 덮어쓰지 않도록 필요한 변경만 보내고, 응답과 재조회로 설정을 확인하세요. 근거: 작업 갱신 경로

6단계: 실제 목적지에 도착한 로그 대조

미리보기는 변환 결과를, 실제 전달 시험은 작업 연결·목적지 권한·수신기 스키마까지 확인합니다. 합성 NDJSON을 저장했다고 실제 Logpush 원본으로 주입되는 것은 아닙니다. 실제 시험은 자신이 관리하는 시험 zone에서 무해한 요청을 만들고, 그 이벤트를 목적지에서 찾는 방식으로 진행하세요. 공개 글에는 운영 원본 대신 합성 예시를 사용합니다.

  1. 변경 시각·job ID·Transformer ID·SQL 버전을 기록합니다.
  2. 변경 후 생성한 시험 이벤트의 RayID와 시간 범위를 비공개로 보관합니다.
  3. 목적지 객체나 수신 레코드에서 같은 이벤트를 찾아 출력 키와 자료형을 확인합니다.
  4. 원본 ClientIP와 중복 IP 필드, URI·헤더 등의 불필요한 값이 남지 않았는지 확인합니다.
  5. 상태 200인 제외 대상이 전달되지 않는지도 작업 상태와 함께 판단합니다.
  6. IPv6 시험 환경이 없다면 IPv6 실제 전달은 미확인으로 기록합니다.

과거 원본 객체와 변경 후 객체를 섞어 검사하지 마세요. 도착 데이터가 없을 때에도 WHERE에 의해 제외됐는지, 아직 전달 중인지, 변환이나 목적지 수신이 실패했는지를 나눠 봐야 합니다. 한 건을 찾았다는 사실과 모든 배치가 정상 전달됐다는 판단도 구분합니다.

내려받은 NDJSON을 명령으로 검사하기

verify-delivery.py 다운로드는 Python 3.9 이상에서 추가 패키지 없이 실행합니다. 이 글의 SQL을 그대로 사용한 출력이 대상입니다. 목적지에서 변경 후 구간의 파일을 내려받아 검사하세요. .ndjson.gz도 지원합니다.

# delivered.ndjson은 목적지에서 내려받은 실제 파일로 교체
python3 verify-delivery.py delivered.ndjson \
  --expect-ray-id 'YOUR_TEST_RAY_ID'

YOUR_TEST_RAY_ID를 변경 후 만든 통과 대상 시험 이벤트의 실제 값으로 바꿉니다. 여러 이벤트는 --expect-ray-id를 반복하세요. 도구는 네 필드의 정확한 구성, 정수 status 400 이상, IP 치환 상수, provider와 요청한 RayID의 존재를 검사합니다. 결과에는 건수·행 번호·오류 코드를 표시하고 원본 레코드 값과 예상 밖 필드명은 출력하지 않습니다.

종료 코드의미와 다음 조치
0파일이 예제 출력 정책을 충족하고 지정한 시험 이벤트를 포함. 작업 상태와 대조
1빈 파일·잘못된 JSON·필드·값 불일치 또는 시험 이벤트 누락. 검사 구간·SQL·출력 확인
2파일 읽기·UTF-8·압축 오류 또는 명령 인수 문제. 파일과 호출 확인

합성 모의 출력으로 도구부터 시험하려면 python3 verify-delivery.py output.local-simulation.ndjson --expect-ray-id 0000000000000001을 실행합니다. 이 도구는 합성 데이터를 사용하는 로컬 테스트 11개를 통과했습니다. client_ip_redacted에 원본 IP가 남은 경우, 예상 밖 필드, 누락 이벤트, 빈 파일·잘못된 압축 등을 실패로 처리하는지 확인했습니다.

검사 통과는 내려받은 파일의 정책 일치 결과입니다. 파일의 출처·생성 시점·전체 배달 성공이나 모든 민감정보의 제거를 입증하지는 않습니다. 남겨 둔 ray_id의 연결 가능성도 별도로 검토하세요. SQL의 출력 정책을 바꿨다면 도구의 FIELDS와 값 검사도 맞춰 바꿔야 합니다.

last_error만 보지 말고 오류 설명·완료 범위를 함께 확인

API 명세에서 last_error는 마지막 실패 시각입니다. 오류 설명은 error_message에 있습니다. Transformer 안내의 last_error 언급을 보고 이 필드가 항상 오류 메시지라고 가정하지 마세요. last_complete는 성공적으로 전달한 로그의 마지막 시간 범위를 나타내며 현재 시각이나 단순 API 호출 시각과는 다릅니다. 근거: 작업 상태 필드 정의

curl·jq가 있는 셸에서 필요한 상태만 추려 볼 수 있습니다. 출력 결과를 공유하기 전에는 error_message에 민감한 주소나 설정값이 포함됐는지도 확인하세요.

set -o pipefail
curl --fail-with-body --show-error \
  --header "Authorization: Bearer ${CLOUDFLARE_API_TOKEN}" \
  "https://api.cloudflare.com/client/v4/zones/${CF_ZONE_ID}/logpush/jobs/${CF_JOB_ID}" \
  | jq '{success, errors, result: (.result | {id, dataset, enabled, last_complete, last_error, error_message})}'
관측 상태다음 점검
연결 시 400필터 잔존, 데이터셋 불일치, 잘못된 ID·SQL 필드·자료형
403계정의 기능 접근과 토큰 권한·범위
런타임 변환 실패오류 설명·SQL 버전·출력 크기, 같은 입력의 미리보기
변환은 통과하나 도착하지 않음목적지 인증·수신 오류·배달 재시도·enabled
도착량이 예상보다 적음WHERE·샘플링·재시도·배치 실패를 구분

Logpush Health에서 성공 업로드·재시도·실패·드롭을 함께 확인하세요. last_error가 null인 것만으로 이번 변경의 실제 전달을 입증할 수는 없습니다. 근거: 배달 상태와 Health 대시보드

변환이 실패하면 원본이 대신 전송되나요?

아닙니다. 변환 배치가 실패하면 원본으로 우회하지 않고 해당 배치를 재시도합니다. 실패가 계속되면 기록이 결국 드롭되어 복구할 수 없을 수 있습니다. 근거: 런타임 실패 처리 원본 노출을 막는 동작이 로그의 무기한 보존까지 보장하지는 않습니다.

장애 때에는 작업 ID·시각·오류를 보관하고, 문제가 난 SQL을 수정해 미리보기와 전달 상태를 다시 확인합니다. 원본 전송이 허용되지 않는 작업에서는 Transformer를 단순히 해제하는 방식으로 복구하지 마세요. 기존 설정을 보관해 두더라도 어떤 필드와 조건으로 다시 보낼지 먼저 정해야 합니다.

Logpush Transformers 검토 기록표 CSV에 변경 전 조건·SQL·미리보기·실제 도착·오류·복구 결과를 남길 수 있습니다. 빈 양식이므로 실제 도착 파일·검사 결과·작업 상태를 함께 보관해 사용하세요.

자주 묻는 질문

CSV Logpush 작업에도 적용할 수 있나요?

현재는 호환 NDJSON 작업이 대상입니다. CSV 작업은 Studio의 연결 대상에 표시되지 않습니다. 형식을 바꾸려면 목적지 파서와 스키마까지 함께 검증해야 합니다.

기존 필터와 Transformer를 함께 쓰면 왜 400 오류가 나나요?

작업 하나에 두 방식을 동시에 설정할 수 없기 때문입니다. 기존 조건을 SQL WHERE에 옮겨 확인한 뒤 같은 갱신 요청에서 filter를 비우고 transformer_id를 지정하세요. 필터만 지우면 기존 선별 조건을 잃을 수 있습니다.

변환 실패 시 원본 로그가 그대로 전송되나요?

자동 원본 대체 전송은 하지 않습니다. 재시도와 지속 실패에 따른 드롭 가능성이 있으므로 오류 설명·마지막 완료 범위·작업 활성 상태와 목적지 도착을 함께 확인해야 합니다.

Evidence & Limitations

근거·검증 범위·업데이트 기록

확인한 근거

Cloudflare Logpush Transformers 공식 심층 해설를 기준으로 핵심 사실을 확인하고, 사실과 편집부 해석을 구분했습니다.

경험 정보와 한계

직접 사용 후기나 자체 성능 시험이 아닌 공개 원문·공식 문서 기반 분석입니다. 실제 화면과 기능은 계정·기기·배포 시점에 따라 다를 수 있습니다.

게시·수정 기록

최초 게시 2026-10-16T08:34:43+09:00 · 최종 수정 2026. 10. 16.

도착 NDJSON 검사 도구와 종료 코드별 대응을 추가하고 반복 요약을 줄였습니다.

전문 검토 영역

IT 매거진 편집부가 AI·소프트웨어·개발·모바일·보안·테크 비즈니스 관점에서 구성하고 팩트체크 데스크가 출처와 표현을 검토했습니다.

Related Articles

현재 기사와 연결되는 배경·기술·시장 분석을 골라 바로 이동할 수 있습니다.