WebRTC IP Leak / VPN·Proxy 비교 테스터

HTTP echo IP 와 WebRTC(srflx) IP 를 수집·비교해 현재 브라우저 환경의 VPN/Proxy 특성을 분석합니다.

🧭 브라우저 환경

📖 동작 원리

HTTP echo vs WebRTC srflx — 왜 두 값을 비교하는가

브라우저가 외부에 보이는 공인 IP 는 프로토콜/경로에 따라 달라질 수 있습니다. HTTP(TCP) 과 WebRTC STUN(UDP) 의 결과가 같으면 단일 경로, 다르면 Split tunneling / SOCKS / HTTP-only 프록시 / VPN 이상 동작의 강한 시그널입니다.

  • HTTP echo IPfetch() 로 공개 echo 서비스(ipify, ipapi, myip) 호출 → 응답 헤더/바디에서 서버가 관측한 TCP 경로의 공인 IP 를 회수합니다.
  • WebRTC srflx IPRTCPeerConnection 으로 STUN 서버에 UDP 질의를 보내면 STUN 서버가 관측한 외부 주소(=NAT 반사 IP) 를 ICE candidate 의 typ srflx 로 돌려줍니다. 이는 UDP 경로의 공인 IP 입니다.
  • host candidate — 로컬(사설) IP. 최신 Chrome/Firefox 에서는 .local 형태로 mDNS 난독화됩니다.
  • relay candidate — TURN 서버 경유. 일반 브라우저 환경에선 거의 안 나타납니다.

해석 가이드

  • HTTP IP == WebRTC IP — 단일 경로. 정상 직결 / 풀터널 VPN / 시스템 레벨 터널(WireGuard, OpenVPN TUN). 두 값이 같다고 해서 VPN 이 아닌 것은 아님 — 둘 다 VPN IP 로 동일하게 나올 수 있음.
  • HTTP IP ≠ WebRTC IP경로 분리. 가능성 있는 원인:
    • 브라우저 SOCKS/HTTP 프록시 — TCP 만 프록시, UDP 는 직결 (SOCKS5 UDP 는 Chrome/Firefox 기본 미지원)
    • Split tunneling VPN — 앱/도메인별 분기, WebRTC 트래픽이 VPN 밖으로 유출
    • 다중 WAN / PBR(policy-based routing) — TCP/UDP 가 서로 다른 게이트웨이
    ※ 이 시그널만으로는 SOCKS vs Split tunnel 을 구분할 수 없습니다. 두 경우 모두 관측 결과는 동일(HTTP≠WebRTC)이며, 추가 시그널(UA, 지리정보, 포트 패턴)과 결합해야 판별 가능.
  • HTTP 만 수집 · WebRTC 차단RTC leak protection 동작 (확장 프로그램 / Brave 설정 / 기업 정책). 탐지 측 입장에선 VPN/프라이버시 툴 사용 의심 시그널.
  • 다중 STUN 이 서로 다른 srflx IP 반환비정상 라우팅 (다중 WAN, TURN 경유, 비대칭 NAT, 또는 STUN 서버 일부가 차단되어 prflx 로 폴백).
  • IPv4 없고 IPv6 만 나옴 — IPv6-only 네트워크 또는 VPN 이 IPv4 만 터널링하는 설정.
  • HTTPS echo IP ≠ HTTP echo IP스킴별 경로 분리. 웹 프록시가 HTTPS 는 bypass(또는 CONNECT 미지원) 하고 HTTP 평문만 프록시할 때 발생. 자체 서버가 평문 HTTP 일 경우 "501(서버 관측 IP)=프록시 / 외부 HTTPS echo=원천 IP" 로 갈라지는 증상이 이 케이스.
🔐 왜 HTTP 와 HTTPS 가 프록시에서 다르게 동작하는가

핵심은 프록시가 두 트래픽을 건드릴 수 있는 권한/능력이 다르다는 점입니다. HTTP 는 프록시가 내용을 전부 보고 대리 요청을 수행하지만, HTTPS 는 암호화 벽에 막혀 단순 바이트 중계만 가능합니다.

1. HTTP — 프록시가 내용을 다 본다

브라우저가 평문 HTTP 를 프록시에 보내면 프록시는 URL·헤더·바디를 모두 읽고, 목적지 서버로 새 TCP 연결을 열어 대리 요청을 보냅니다. 목적지 서버가 보는 src IP 는 프록시 IP 입니다.

[브라우저] ──"GET http://api.ipify.org/ HTTP/1.1"──▶ [프록시] ──새 TCP 연결──▶ [목적지 서버] ↑ src IP = 프록시 IP
  • 프록시는 헤더/바디 평문 가시X-Forwarded-For 덧붙이거나 내용 변조 가능
  • 프록시 = "대리인(agent)" 역할
  • 결과: 목적지가 관측한 src IP = 프록시 IP

2. HTTPS — 프록시는 암호화 벽에 막힌다

브라우저는 먼저 프록시에 CONNECT host:443 을 보내 "바이트만 중계해 달라" 고 요청합니다. TLS 핸드셰이크는 브라우저 ↔ 목적지 서버 끝점 간 에서만 일어나므로 프록시는 암호화된 바이트를 읽을 수도, 복호화할 수도, 변조할 수도 없습니다.

[브라우저] ──"CONNECT api.ipify.org:443"──▶ [프록시] ──TCP 터널──▶ [목적지 서버] └──────────── TLS 핸드셰이크 (end-to-end) ────────────┘ ↑ 암호화된 바이트만 통과 — 프록시는 내용 못 봄

이때 프록시가 취할 수 있는 행동은 3가지:

(a) 제대로 CONNECT 터널링
프록시가 목적지까지 TCP 를 열고 바이트만 왕복. 목적지가 보는 src IP = 프록시 IP. HTTP 와 동일한 결과.
(b) 거부 / 직결 폴백현실에서 가장 흔한 패턴
많은 무료·브라우저 확장형·antidetect 프록시는 CONNECT 를 제대로 구현하지 않음. 브라우저는 오류를 받고 프록시를 우회해 직결 시도하거나 요청 실패. 직결되면 목적지가 보는 src IP = 원천 IP. 사용자가 감지하지 못한 채 실제 IP 가 유출.
(c) TLS MITM (SSL Bump)
프록시가 자체 루트 CA 를 브라우저에 심고 중간에서 TLS 를 가로채 복호화. 기업 SSL 검사 게이트웨이나 Burp/Fiddler 같은 디버깅 도구에서 사용. 브라우저가 그 루트 CA 를 신뢰하지 않으면 인증서 오류로 연결 실패.

3. 정리 표

구분HTTP (평문)HTTPS (TLS)
프록시가 보는 것전체 내용 (URL·헤더·바디)암호화된 바이트뿐
프록시 역할대리 요청자 (agent)단순 바이트 중계 (tunnel) 또는 직결 폴백
요청 방식GET http://host/pathCONNECT host:443 후 TLS
목적지가 본 src IP프록시 IPCONNECT 지원 시 프록시 IP,
아니면 원천 IP
MITM 가능?N/A (이미 평문)루트 CA 설치돼야만
현실에서 자주 보이는 결과대부분 프록시 경유자주 bypass 되어 원천 IP 유출

4. 탐지 관점의 의미

스킴별 갈라짐 자체가 프록시 시그널입니다. 정상 네트워크(직결 / 풀터널 VPN)라면 HTTP·HTTPS 둘 다 같은 IP 가 나옵니다. HTTPS 만 원천 IP 로 새는 건 "개인용 프록시/확장" 의 전형적 지문이며, 거꾸로 말하면 사용자가 아무리 프록시로 IP 를 숨기려 해도 HTTPS echo 한 번으로 진짜 IP 가 드러난다는 뜻입니다.

이 페이지가 HTTP 평문 엔드포인트(http://api.ipify.org, http://ipv4.icanhazip.com) 와 HTTPS 엔드포인트를 나란히 호출하고, Scheme 칼럼과 HTTPS IP ≠ HTTP IP verdict 로 분리 패턴을 시각화하는 이유입니다. (페이지를 https:// 로 열면 mixed content 정책으로 http:// 호출이 브라우저에서 차단되므로, 프록시 진단 목적이라면 HTTP 로 이 페이지를 여는 것을 권장합니다.)

⚙️ 테스트 설정
형식: stun:host:port — 예: stun:stun.l.google.com:19302. URL 쿼리스트링 ?stun=stun:host:port 로 추가 서버를 URL 에 포함할 수도 있습니다.
대기 중

🔎 분석 결과

📊 세부 결과

HTTP echo IP (TCP)

엔드포인트별 응답
EndpointSchemeIPms

WebRTC srflx IP (UDP)

STUN 서버별 공인 후보 (srflx / prflx / relay — IP 기준 중복 제거, host 숨김)
STUNTypeProtoIPPortms

Relay / Prflx

TURN 경유 또는 peer reflexive 후보
TypeIPPort

Raw result JSON