cloudflare: Pseudo IPv4 (Class E 240/4) 정리 — Netbis 관찰 기반

- infra/security/cloudflare.md: Pseudo IPv4 섹션 신규 (동작 원리·모드·함의·오해 주의)
- services/netbis.md: client_ip 의미에서 부정확한 '254.x 범위' → '240.0.0.0/4' 정정, CF docs 링크
- history: 2026-04-24 CF Pseudo IPv4 정체 규명 (CGNAT 오진 교훈 포함)
This commit is contained in:
kaffa
2026-04-24 08:11:44 +09:00
parent 2a8cf22e43
commit 102da9c2fe
3 changed files with 150 additions and 1 deletions

View File

@@ -0,0 +1,109 @@
---
title: CF Pseudo IPv4 (Class E 240/4) 정체 규명
updated: 2026-04-24
tags: [cloudflare, netbis, log-analysis, incident]
---
## 배경
Netbis NPM → zlambda → VictoriaLogs 로그 파이프라인이 2026-04-23 구축 + 실 client IP 추출 VRL transform 정비 완료 직후, VL top client_ip 집계에서 **240.0.0.0/4 (클래스 E, "Reserved for Future Use") 대역이 전체 트래픽의 45%**를 차지하는 현상 관찰.
## 초기 오진
- 처음에는 "한국 모바일 통신사의 CGNAT 240/4 활용" 으로 추정하고 답변
- 근거로 UA 95%+ 모바일 + KR 앱 브랜드(KakaoTalk/Daum/NAVER)
- **이 추정은 틀렸음.** 공식 문서·RFC·APNIC/IETF 검색 결과 KR 통신사가 240/4를 CGNAT에 사용한다는 기록 없음
## 실제 원인 — CF Pseudo IPv4
Cloudflare 공식 [Pseudo IPv4 문서](https://developers.cloudflare.com/network/pseudo-ipv4/) 및 [Support 문서](https://support.cloudflare.com/hc/en-us/articles/229666767) 확인:
> "Cloudflare uses Class E IP space (240.0.0.0 - 255.255.255.255) for these addresses. The Pseudo IPv4 service uses a hashing algorithm applied to top 64 bits of the connecting IPv6 address"
> "overwrite the existing Cf-Connecting-IP and X-Forwarded-For headers with a Pseudo IPv4 address"
즉:
```
IPv6 클라이언트 → CF 엣지
→ IPv6 상위 64비트 MD5 해시 → 240/4 매핑
→ CF-Connecting-IP 및 X-Forwarded-For 헤더 값 overwrite
→ NPM의 real_ip_header CF-Connecting-IP 설정 → $remote_addr에 240/4 기록
→ Vector VRL → VL의 client_ip 필드에 240/4 저장
```
Netbis 조건과 완벽 일치:
- 백엔드 Apache 2.4.38 + PHP 5.6.40 (IPv6 지원 미흡한 레거시)
- 모바일 트래픽 비율 높음 (모바일 = IPv6 비율 높음)
- CF 대시보드에서 Pseudo IPv4 Overwrite headers 모드 활성 상태
## 검증 증거
로그 필드 샘플 5건 공통 패턴:
```
client_ip = 240/4 범위 값
xff_chain = 동일 값 (CF가 두 헤더 모두 overwrite)
cf_edge_ip = 172.70.x 등 CF 대역
client_ip_source = remote_addr
```
UA 분포 (1h, 240/4 IP 한정):
```
Android (Chrome): 15,469 (67%)
iPhone (Safari): 4,694 (20%)
Daum/Kakao 앱: 1,512
KakaoTalk: 962
NAVER: 573
Windows: 591 (2.6%)
Mac: 3 (0.01%)
```
데스크톱 2.6%뿐 — 모바일 IPv6 비율 높음과 부합.
## 함의
### 차단 영향 범위
- 240/4 IP 하나 = **단일 IPv6 /64 prefix 전체**의 해시 결과
- 한 가정 IPv6 `/64`는 수십~수백 디바이스·수년 SLAAC 주소 포함
- 따라서 **240/4 IP ban = 한 가정/기업의 모든 IPv6 디바이스 장기간 차단 위험**
- CGNAT(수천 유저)보다는 좁지만 단일 IP로 간주하면 오탐 증폭
### 봇 탐지 관점
- 역설적으로 현재 Overwrite 모드가 IPv6 봇넷 탐지에 유리
- IPv6 프라이버시 확장으로 수천 주소 돌리는 봇도 같은 /64면 같은 240/4 하나로 collapse
- 진짜 IPv6를 받았다면 매번 다른 주소라 탐지 훨씬 어려웠을 것
- 단 /64 차단 = 해당 prefix의 정상 유저 동반 차단 → ban duration을 짧게(10~30분) 유지 권장
### 시나리오/ML feature
- 240/4 IP를 "가상 식별자"로 그대로 사용 가능 (결정적 해시이므로)
- CGNAT 플래그로 분류 금지 — 잘못된 분류로 처리 로직 왜곡됨
- 필요 시 Pseudo IPv4 모드를 "Add header"로 전환해 실 IPv6 확보 가능 (백엔드 IPv6 처리 여부 선행 확인 필수)
## 대안 경로 (추후 결정사항)
| 조치 | 효과 | 리스크 |
|------|------|-------|
| 현상 유지 (Overwrite) | 레거시 백엔드 호환 유지 | 240/4 해석·ban 설계에 주의 필요 |
| Add header 모드 전환 | CF-Connecting-IP에 실 IPv6, 별도 헤더에 240/4 | PHP 5.6 IPv6 주소 문자열 처리 검증 필요 |
| 백엔드 IPv6 업그레이드 | 근본 해결 | 애플리케이션 호환 작업 대규모 |
## 정본 반영
- `infra/security/cloudflare.md``Pseudo IPv4 (Class E 240/4)` 섹션 신규
- `services/netbis.md` — client_ip 의미 설명 정정 (254.x → 240/4, 메커니즘 링크)
## 참고 자료
- [CF Pseudo IPv4 공식 문서](https://developers.cloudflare.com/network/pseudo-ipv4/)
- [CF Support 문서](https://support.cloudflare.com/hc/en-us/articles/229666767)
- [APNIC Blog: Looking for 240/4 addresses](https://blog.apnic.net/2024/09/10/looking-for-240-4-addresses/)
- [benjojo: Class E Addresses in the Real World](https://blog.benjojo.co.uk/post/class-e-addresses-in-the-real-world)
- [IETF draft-schoen-intarea-unicast-240](https://datatracker.ietf.org/doc/draft-schoen-intarea-unicast-240/)
## 오진 교훈
- UA 분포만으로 "CGNAT"로 단정 금지 — Pseudo IPv4가 모바일 IPv6 해시 결과이므로 같은 시그널이 나옴
- 예약 대역 IP 관찰 시 먼저 CF 엣지 기능(Pseudo IPv4, IP anonymization 등) 가능성부터 확인
- 공식 벤더 문서 확인이 UA·트래픽 패턴 추론보다 선행되어야 함

View File

@@ -27,6 +27,46 @@ Syn 이 엣지 관점에서 소유. 일반 DNS 관리 협업은 Heimdall.
⚠️ **Rate Limit, WAF 규칙, Firewall 설정은 API로 조회/변경 불가 — 대시보드에서만 관리 가능**. 토큰 스코프 확장이 필요하면 CF 대시보드 > My Profile > API Tokens에서 편집.
## Pseudo IPv4 (Class E 240/4)
레거시 IPv4-only 백엔드를 위한 CF 기능. **Netbis zone에서 활성 상태로 관찰됨** (Apache 2.4.38 + PHP 5.6.40). Kappa 계정 zone에는 현재 기본 Off로 추정.
### 동작 원리
```
클라이언트 (IPv6) → CF 엣지
→ IPv6 주소 상위 64비트를 MD5 해시
→ 결과를 240.0.0.0/4 (240~255.x.x.x) 범위의 IPv4로 매핑
→ CF-Connecting-IP 및 X-Forwarded-For 헤더를 해시된 IPv4로 overwrite
→ 진짜 IPv6는 Cf-Connecting-IPv6 별도 헤더로 전달
```
### 모드 3종 (CF 대시보드 Network → Pseudo IPv4)
| 모드 | CF-Connecting-IP | 별도 헤더 |
|------|-----------------|----------|
| Off | 실 IPv6/IPv4 | - |
| Add header | 실 IP 그대로 | `Cf-Pseudo-IPv4`에 해시 |
| **Overwrite headers** | 해시(240/4) | `Cf-Connecting-IPv6`에 실 IPv6 |
### 관찰 시그널 (Netbis)
- VL `client_ip` 필드 중 240.0.0.0/4 대역 IP 등장 = IPv6 접속자
- UA 분포: 95%+ 모바일 (Android Chrome / iPhone Safari / KakaoTalk / Daum / NAVER) — KR 모바일 IPv6 보급률 높음
- 동일 IPv6 `/64` prefix → 항상 같은 240/4 IP로 매핑 (재현 가능한 식별자)
- **한 240/4 IP = 한 가정/ /64 단위 유저 집합** — ban 시 /64 전체가 차단됨
### 오해 주의
- 240/4는 KR 통신사 CGNAT 아님 (공식 문서 없음, 공개 라우팅도 안 됨)
- 실제로는 CF Pseudo IPv4 해시값 — "가짜 IP"
- CGNAT 오인하면 차단 효과 완전히 다르게 판단됨
### 관련 링크
- [CF Pseudo IPv4 docs](https://developers.cloudflare.com/network/pseudo-ipv4/)
- [CF Support: Pseudo IPv4 overview](https://support.cloudflare.com/hc/en-us/articles/229666767)
## Zone
| Zone | Zone ID | Status | Plan | NS | DNS rec | 비고 |

View File

@@ -245,7 +245,7 @@ NPM-1..6 호스트 Vector(0.55)
| 라벨 | `host=npm-1..6`, `service=npm`, `log_type=access|error`, `zone=<서빙 zone CSV>`(npm-1/5/6 은 `shared`), `relay=zlambda`, `program=npm`, `proxy_host_id`(파일명에서 추출), `client_ip`(실 IP), `cf_edge_ip`, `xff_chain`, `client_ip_is_cf_edge`, `client_ip_source`, `remote_addr`(raw Client) |
| 파싱 포맷 | NPM proxy/standard v2 (Real+XFF 포함, 2026-04-23 이후) 우선, v1(Real+XFF 없음) legacy fallback. 모두 실패 시 `log_format=raw` |
| nginx 설정 | 6대 전부 `real_ip_header CF-Connecting-IP`, `real_ip_recursive on`, `set_real_ip_from` 에 CF + CloudFront IP 대역 포함. log_format에 `[Client $remote_addr] [Real $realip_remote_addr] [XFF $http_x_forwarded_for]` 3필드 기록 (2026-04-23 일괄 패치) |
| client_ip 의미 | nginx real_ip 재작성 후의 실 고객 IP (CF-Connecting-IP 경유). IPv6 방문자의 경우 CF Pseudo IPv4 254.x 범위로 나타남 — 시나리오/AI 분석에 식별자로 사용 가능. Rewrite 실패(Client == Real) 시 `client_ip_is_cf_edge=true` + `client_ip=null` + `client_ip_source=cf_edge_rewrite_failed` |
| client_ip 의미 | nginx real_ip 재작성 후의 실 고객 IP (CF-Connecting-IP 경유). **IPv6 방문자 CF Pseudo IPv4 기능으로 `240.0.0.0/4` (240~255.x.x.x) 범위의 해시 값으로 나타남** — [[../infra/security/cloudflare#Pseudo IPv4 (Class E 240/4)]] 참조. Rewrite 실패(Client == Real) 시 `client_ip_is_cf_edge=true` + `client_ip=null` + `client_ip_source=cf_edge_rewrite_failed` |
| zlambda relay | [[zlambda]] NixOS container `vector-relay` (Docker `timberio/vector:0.45.0-debian`, net `vector-net`, port 9999/tcp) |
| zlambda 모듈 | `~/nixos-infra/vector.nix` — 전용 render/env systemd + Docker oci-container |
| bearer token | zlambda agenix `secrets/vector-bearer-token.age` (kaffa + zlambda host key 복호화). NPM config 에는 평문, Vault 백업은 `secret/cloud/vector-relay-netbis` |