목록으로 돌아가기
Zero Trust
10분 읽기

[Cloudflare 딥다이브 EP.02] Zero Trust 개념 — WARP·Tunnel·Private Network

VPN과 Zero Trust의 철학 차이, Cloudflare WARP의 BoringTun 내부 구조, Tunnel·WARP Connector·Private Network·Split Tunnel·Gateway/Access Policy 역할, wgcf 3형제까지 실전 구축 전에 반드시 짚어야 할 개념을 정리한다.

ㅂㄹㄱ

2026-04-14 ·

이 글은 개발자의 Cloudflare 인프라 딥다이브 시리즈의 두 번째 편이다.
EP.01에서 다룬 L2/L3 개념을 바탕으로, Zero Trust가 어떤 철학을 갖고 있고 Cloudflare가 이걸 어떻게 구현했는지 정리한다.

들어가며

"Cloudflare Zero Trust를 써보자"고 마음먹은 다음에 가장 혼란스러웠던 건 용어였다. WARP, WARP Connector, Tunnel, Private Network, Split Tunnel, Gateway Policy, Access Policy. 모두 비슷하게 생겼지만 실제 역할은 다르다. 대시보드 메뉴를 아무리 뒤져도 "이걸 언제 켜야 하는지" 감이 잡히지 않았다.

게다가 Cloudflare가 WireGuard를 쓴다는 건 알겠는데, cloudflare-warp 데몬을 깔면 되는 건지, wg-quick으로 직접 돌려야 하는 건지, wgcf라는 서드파티 도구는 왜 필요한 건지 명확하지 않았다. 결국 개념을 제대로 정리하지 않은 채 실전 구축에 들어갔다가 같은 실수를 몇 번이나 반복했다.

결국 이번 편이 답하려는 핵심 질문은 하나다. "VPN이랑 뭐가 다르고, Cloudflare는 이걸 어떻게 구현했어?" 이 질문에 답하려면 Zero Trust의 철학과 Cloudflare가 제공하는 구체적 컴포넌트들을 하나씩 짚고 가야 한다. EP.03의 실전 구축은 그다음이다.


VPN vs Zero Trust: 경계 안과 바깥의 차이

전통적인 VPN은 경계 기반 보안(Perimeter-based Security) 모델이다. 사내망과 외부망 사이에 벽을 세우고, VPN 터널은 그 벽에 뚫은 "정식 출입구"다. 일단 터널 안에 들어오면 내부 자원 대부분에 접근할 수 있다.

Zero Trust는 "네트워크 경계를 신뢰하지 않는다"는 철학이다. 사내망 안에 있다고 해서 자동으로 신뢰하지 않는다. 요청마다 신원(identity)과 디바이스 상태(posture)를 검증한다. 정책도 네트워크 대역이 아니라 사용자/그룹/디바이스 단위로 설정된다.

구분VPNZero Trust
보안 모델경계 기반신원 기반
정책 단위IP 대역, 포트사용자, 그룹, 디바이스
네트워크 접근터널 연결 = 내부 접근연결돼도 리소스별 재검증
신뢰 가정내부망은 신뢰아무것도 신뢰 안 함
장애 포인트중앙 VPN 게이트웨이분산된 엣지 네트워크

Cloudflare Zero Trust는 이 철학을 Cloudflare의 전 세계 엣지 네트워크 위에 얹은 구현체다. 디바이스는 가장 가까운 Cloudflare PoP에 붙고, 거기서부터 목적지까지의 경로는 Cloudflare 백본이 책임진다.


WARP의 정체: WireGuard + BoringTun

Cloudflare WARP는 여러 제품 이름으로 등장한다. 공개 WARP(1.1.1.1 VPN), WARP Client, WARP Connector까지 모두 공통적으로 WireGuard 프로토콜 위에서 동작한다.

BoringTun — 유저스페이스 WireGuard 구현

WireGuard는 원래 리눅스 커널 모듈이다. 하지만 Cloudflare는 모든 OS에서 일관되게 돌리기 위해 BoringTun이라는 유저스페이스 구현을 Rust로 만들어 공개했다. 커널 모듈이 없는 macOS, Windows, iOS, Android 클라이언트에서도 동일한 프로토콜로 동작하게 하기 위해서다.

graph TD
    A[Cloudflare WARP Client] --> B[BoringTun - 유저스페이스 WG 구현]
    B -->|WireGuard 프로토콜| C[Cloudflare 엣지 - 가장 가까운 PoP]
    C --> D[목적지 리소스]
Diagram: graph TD A[Cloudflare WARP Client] --> B[BoringTun - 유저스페이스 WG 구현] B -->|WireGuard 프로토콜| C[Cloudflare 엣지 - 가장 가까운 PoP] C --> D[목적지 리소스]

중요한 건 프로토콜 자체는 WireGuard 표준이라는 점이다. 따라서 리눅스 서버에서는 BoringTun을 거치지 않고도 커널의 wg-quick으로 같은 터널에 접속할 수 있다. EP.03에서 실제로 이렇게 구성한다.


WARP Client vs WARP Connector vs WireGuard 네이티브

같은 WireGuard 프로토콜 위에서 동작하지만, 설치 방식에 따라 포워딩 동작이 다르다. "cloudflare-warp 데몬"이라는 한 덩어리로 보면 안 된다. 이 구분을 몰라서 가장 오래 헤맸다.

WARP Client (개인 디바이스 모드)

macOS/Windows GUI 앱, 모바일 앱, 리눅스 warp-cli가 여기에 해당한다. BoringTun 유저스페이스로 동작하며, 로컬 소켓에서 생성된 트래픽만 터널에 넣어준다. 다른 장비에서 포워딩된 패킷은 무시한다.

  • 용도는 개인 디바이스가 Zero Trust에 접속할 때
  • 게이트웨이 용도로는 부적합

WARP Connector (게이트웨이 모드)

전용 Connector 패키지로 설치한다. Cloudflare 내부적으로 netfilter 훅을 활용해 포워딩된 패킷도 정상적으로 터널에 태운다. 서브넷 게이트웨이로 설계된 모드다.

  • 용도는 서브넷 전체를 Zero Trust에 편입
  • 지원 OS는 리눅스 중심 (macOS 지원은 한동안 제한적이었음)
  • 게이트웨이 용도에 적합

WireGuard 네이티브

리눅스의 wg-quick이나 macOS의 brew install wireguard-tools로 설치한 일반 WireGuard다. 커널(리눅스) 또는 그에 준하는 저수준(macOS utun)에서 패킷을 처리한다.

  • 용도는 Connector와 동일 (게이트웨이)
  • 장점은 모든 OS에서 동일하게 동작, NAT 없이 원본 IP 보존
  • 단점wg0.conf를 직접 관리해야 함 (Cloudflare가 공식 conf를 제공하지 않음, wgcf-connector로 추출)

세 가지 비교

항목WARP ClientWARP ConnectorWireGuard 네이티브
대표 구현warp-cli, GUI 앱Connector 패키지wg-quick + conf
실행 레이어유저스페이스 (BoringTun)유저스페이스 + netfilter커널 / utun
로컬 트래픽정상 처리정상 처리정상 처리
포워딩 트래픽무시됨정상 처리정상 처리
지원 OS전 플랫폼리눅스 중심리눅스 / macOS / Windows
게이트웨이 용도부적합적합적합
원본 IP 보존-MASQUERADE 기본NAT 없이 보존 가능
설정 관리CLI 자동CLI 자동conf 파일 수동

홈 네트워크 게이트웨이(Mac Mini)는 macOS에서 돌아야 하므로 Connector 대신 WireGuard 네이티브를 선택했다. VPC 게이트웨이(서버 A)는 Connector로도 가능했지만 원본 IP를 보존하기 위해 역시 WireGuard 네이티브로 통일했다. 개인 디바이스(맥북, 외부 접속 디바이스)는 WARP Client GUI 앱이 가장 편하다.


Cloudflare Zero Trust 구성 요소

대시보드에 로그인하면 보이는 메뉴들이 실제로 어떤 역할을 하는지 정리한다.

Tunnel (Cloudflare Tunnel)

내부 서비스를 외부에 공개할 때 쓴다. 공인 IP나 포트 포워딩 없이 Cloudflare 엣지로 outbound 커넥션만 열어서, 외부 사용자 요청을 엣지가 받아 터널을 통해 내부로 전달한다.

  • 방향은 내부 → Cloudflare (outbound only)
  • 용도는 셀프호스팅 서비스를 공개 도메인에 바인딩
  • 예시로 집에서 돌리는 Jellyfin을 media.example.com으로 공개

cloudflared 데몬이 내부에서 돌면서 엣지와 터널을 유지한다.

WARP Connector

Tunnel이 "서비스 공개"용이라면, WARP Connector는 내부 네트워크 자체를 Zero Trust 네트워크에 편입시키는 용도다. 특정 서브넷(예: 10.20.0.0/18)을 Cloudflare에 등록하고 그 서브넷의 게이트웨이에 Connector를 설치하면, WARP로 로그인한 디바이스가 해당 서브넷에 직접 접근할 수 있다.

  • 방향은 양방향 (라우팅 가능한 사설망 연결)
  • 용도는 여러 사이트와 클라우드를 하나의 사설망처럼 연결
  • 예시로 홈 네트워크(10.10.0.0/16)와 Vultr VPC(10.20.0.0/18) 연결

Private Network

WARP Connector(또는 Tunnel)가 어떤 CIDR(Classless Inter-Domain Routing)을 커버하는지 Cloudflare에 알려주는 라우팅 테이블 등록이다. 여기에 10.20.0.0/18을 등록해야 WARP 클라이언트가 해당 대역을 어떤 Connector로 보내야 할지 알 수 있다.

graph LR
    Client[WARP Client] --> CF[Cloudflare Edge]
    CF -->|10.20.0.0/18| VPC[VPC Connector]
    CF -->|10.10.0.0/16| Home[홈 Connector]
    VPC --> VPCServer[VPC 서버]
    Home --> HomeDevice[홈 디바이스]
Diagram: graph LR Client[WARP Client] --> CF[Cloudflare Edge] CF -->|10.20.0.0/18| VPC[VPC Connector] CF -->|10.10.0.0/16| Home[홈 Connector] VPC --> VPCServer[VPC 서버] Home --> HomeDevice[홈 디바이스]

Split Tunnel

WARP 클라이언트에서 어떤 대역을 터널로 보내고 어떤 대역은 직접 나갈지 결정하는 설정이다. 두 가지 모드가 있다.

  • Exclude 모드에서는 기본적으로 모든 트래픽이 터널을 탄다. 지정한 대역만 제외된다.
  • Include 모드에서는 기본적으로 직접 나간다. 지정한 대역만 터널을 탄다.

사설망 접근 목적이면 Include 모드를 쓰고 필요한 CIDR만 등록하는 게 깔끔하다. 전체 트래픽을 Cloudflare로 우회시키는 건 불필요한 지연과 비용을 만든다.


Gateway Policy vs Access Policy

둘 다 "누가 어디 접근할 수 있는가"를 결정하는 정책이지만, 작동하는 레이어가 다르다.

Gateway Policy

네트워크 레이어(L3/L4/DNS)에서 동작한다. WARP 클라이언트를 통해 나가는 모든 트래픽을 검사하고, 조건에 맞으면 Allow/Block/Isolate 한다.

  • 적용 범위는 WARP를 통해 흐르는 트래픽 전체
  • 제어 단위는 IP, 포트, 도메인, 카테고리
  • 예시로 "dev 팀은 prd 서브넷 접근 금지", "경영지원팀은 소셜미디어 차단"

Access Policy

애플리케이션 레이어(L7)에서 동작한다. 특정 URL이나 셀프호스팅 앱 앞에 SSO(Single Sign-On)를 붙여서, 인증된 사용자만 접근하게 한다.

  • 적용 범위는 특정 도메인이나 URL
  • 제어 단위는 사용자, 그룹, 디바이스 posture
  • 예시로 "admin.example.com은 조직 이메일로 로그인한 디바이스만 허용"
구분Gateway PolicyAccess Policy
레이어L3/L4/DNSL7 (HTTP)
대상트래픽 전체특정 앱/URL
인증 방식디바이스 postureSSO 로그인
동작 지점네트워크 흐름 중간앱 앞단 리버스 프록시

실전에서는 둘을 같이 쓴다. Gateway Policy로 네트워크 수준의 접근을 제한하고, 민감한 관리 앱에는 Access Policy로 SSO를 덧붙이는 식이다.

Gateway Policy의 맹점

Gateway Policy는 WARP를 통과한 트래픽에만 적용된다. WARP를 거치지 않는 직접 경로(예: WireGuard Primary 터널)로 흐른 트래픽은 Gateway Policy가 아예 보지 못한다. EP.05에서 다룰 3레이어 방화벽(Vultr Firewall Group + iptables + Gateway Policy) 설계의 핵심 이유가 여기에 있다.


wgcf 3형제: 비슷한데 역할이 다른 도구들

WARP Connector용 WireGuard 설정을 뽑아내려면 서드파티 도구를 써야 한다. 이름이 비슷한 도구가 셋 있다.

도구용도접근 가능 범위
wgcf공개 WARP(1.1.1.1) 설정 추출인터넷 (VPN 출구 역할)
wgcf-connectorWARP Connector 설정 추출Zero Trust 프라이빗 네트워크
wgcf-teamsZero Trust 개인 디바이스 설정 추출Zero Trust 프라이빗 네트워크

wgcf

퍼블릭 WARP용이다. 이걸로 뽑은 conf로 연결하면 1.1.1.1 VPN에 붙는다. 사설망 접근 용도가 아니라 단순히 WARP 네트워크를 거쳐 인터넷으로 나가는 VPN이다.

wgcf-connector

이 시리즈에서 쓰는 도구다. 대시보드에서 WARP Connector를 만들면 받는 토큰(eyJhIjoi...)을 넣어주면 wg0.conf를 뽑아준다. 이 conf로 wg-quick up을 돌리면 커널 레벨에서 WARP Connector와 동일한 터널이 생긴다.

wgcf-teams

개인 디바이스가 Zero Trust에 붙을 때 쓴다. WARP 클라이언트 앱 대신 리눅스 서버처럼 GUI가 없는 환경에서 Zero Trust 네트워크에 참여시키고 싶을 때 유용하다.

셋 다 같은 저자(animmouse)가 만든 도구들이고, 원리는 "Cloudflare 내부 API로 디바이스 등록 → WireGuard 키페어 생성 → conf 조립"으로 동일하다. 대상이 다를 뿐이다.

디바이스 프로필 주의사항

wgcf-connector로 설정을 추출하려면 Cloudflare 대시보드에서 해당 Connector가 쓰는 디바이스 프로필의 Device tunnel protocol을 WireGuard로 변경해야 한다. 기본값은 MASQUE(HTTP/3 기반)인데 이 상태에서는 WireGuard conf를 뽑을 수 없다. 이 설정 하나 빠뜨려서 한참 헤맸다.


삽질 기록

Mac Mini에서 WARP Client로 게이트웨이 만들려다 실패

처음에는 Mac Mini에 WARP Client GUI 앱을 깔고 IP 포워딩만 켜면 홈 디바이스 패킷이 Zero Trust로 나갈 줄 알았다. 그런데 맥북에서 VPC 서버로 쏜 패킷이 모두 사라졌다. tcpdump로 보니 Mac Mini의 utun 인터페이스에 들어가긴 하는데 엣지까지 나가지 않았다. WARP Client는 로컬 소켓에서 만든 트래픽만 터널에 넣고 다른 장비에서 포워딩된 패킷은 무시한다는 걸 뒤늦게 알았다.

리눅스 서버 A에서는 달랐다. 같은 Cloudflare 계열 도구지만 WARP Connector 패키지로 설치했더니 포워딩된 패킷이 정상적으로 터널을 탔다. Connector는 게이트웨이용으로 설계됐기 때문이다. 다만 Connector는 기본적으로 MASQUERADE를 걸어 원본 IP가 사라진다는 문제가 있었다.

결국 양쪽 모두 wg-quick으로 WireGuard 네이티브를 돌리는 방향으로 통일했다. macOS에서도 동일하게 동작하고, NAT 없이 원본 IP를 보존할 수 있기 때문이다. 이때 wgcf-connector로 Connector 토큰에서 WireGuard conf를 뽑아낸다.

MASQUE가 기본값이라 conf 추출 실패

wgcf-connector에 토큰을 넣었는데 자꾸 "invalid protocol" 에러가 났다. Cloudflare가 최근 도입한 MASQUE(HTTP/3 기반) 프로토콜이 디바이스 프로필의 기본값이었기 때문이다. WireGuard conf를 뽑으려면 프로필에서 명시적으로 protocol을 바꿔줘야 한다.


정리

이번 편의 핵심 개념을 한 장으로 요약한다.

개념한 줄 요약
Zero Trust경계가 아니라 신원으로 신뢰를 판단
WARPCloudflare가 구현한 WireGuard 기반 터널
BoringTunCloudflare가 만든 유저스페이스 WireGuard (Rust)
Tunnel내부 서비스를 외부에 공개 (outbound)
WARP Connector내부 네트워크를 Zero Trust에 편입 (양방향)
Private NetworkConnector가 커버하는 CIDR 등록
Split Tunnel어떤 트래픽을 터널로 보낼지 결정
Gateway Policy네트워크 레이어 접근 제어
Access Policy앱 레이어 SSO 기반 접근 제어
wgcf-connectorWARP Connector용 WireGuard conf 추출 도구
graph TD
    A[인프라 요구사항] --> B{무엇을 하고 싶은가?}
    B -- 내부 서비스 외부 공개 --> C[Cloudflare Tunnel]
    B -- 내부 네트워크 전체 연결 --> D[WARP Connector]
    B -- 개인 디바이스 접근 --> E[WARP Client]

    C --> F[Private Network에 CIDR 등록]
    D --> F
    E --> G[Split Tunnel로 대상 대역 지정]
    F --> G
    G --> H[Gateway Policy: 네트워크 접근 제어]
    G --> I[Access Policy: 앱 접근 제어]
Diagram: graph TD A[인프라 요구사항] --> B{무엇을 하고 싶은가?} B -- 내부 서비스 외부 공개 --> C[Cloudflare Tunnel] B -- 내부 네트워크 전체 연결 --> D[WARP Connector] B -- 개인 디바이스 접근 --> E[WARP Client] C --> F[Private Network에 CIDR 등록] D --> F E --> G[Split Tunnel로 대상 대역 지정] F --> G G --> H[Gateway Policy: 네트워크 접근 제어] G --> I[Access Policy: 앱 접근 제어]

개념 정리가 끝났다. 다음 편에서는 이 도구들을 실제로 조립해서 홈 네트워크와 Vultr VPC를 하나의 사설망으로 묶는 전 과정을 다룬다. wgcf-connector로 conf를 뽑는 것부터, Mac Mini와 서버 A를 게이트웨이로 세팅하고, dnsmasq로 라우팅을 자동 배포하는 데까지 이어진다.


참고자료

자주 묻는 질문

VPN과 Zero Trust는 뭐가 다른가?
VPN은 경계 기반 보안 모델로, 터널 안에 들어오면 내부 자원 대부분에 접근할 수 있다. Zero Trust는 신원 기반 보안 모델로, 요청마다 사용자와 디바이스 상태를 재검증한다. Cloudflare Zero Trust는 이 철학을 글로벌 엣지 네트워크 위에 구현한 서비스다.
WARP Client와 WARP Connector는 뭐가 다른가?
WARP Client는 개인 디바이스 모드로, 로컬 소켓에서 만든 트래픽만 터널에 넣는다. WARP Connector는 게이트웨이 모드로 netfilter 훅을 활용해 다른 장비에서 포워딩된 패킷도 터널로 보낸다. 서브넷 전체를 Zero Trust에 편입시키려면 Connector 또는 WireGuard 네이티브를 써야 한다.
BoringTun과 WireGuard 커널 모듈 중 뭘 쓰는가?
Cloudflare WARP 클라이언트는 BoringTun(Rust 기반 유저스페이스 WireGuard 구현)을 기본으로 쓴다. 프로토콜 자체는 표준 WireGuard이므로, 리눅스 서버에서는 wg-quick으로 커널 모듈을 직접 돌려도 동일한 터널에 접속할 수 있다.
wgcf, wgcf-connector, wgcf-teams 중 뭘 써야 하나?
퍼블릭 WARP(1.1.1.1) 연결이면 wgcf, Zero Trust WARP Connector 게이트웨이 구축이면 wgcf-connector, 개인 디바이스를 Zero Trust 사설망에 붙이려면 wgcf-teams를 쓴다. 셋 다 같은 저자(animmouse)가 만든 서드파티 도구다.
Gateway Policy와 Access Policy 중 어떤 걸 써야 하나?
레이어가 다르다. Gateway Policy는 L3/L4/DNS 네트워크 레이어 접근 제어(IP·포트·도메인 기반), Access Policy는 L7 애플리케이션 레이어 SSO 접근 제어(사용자·그룹 기반)다. 실전에서는 네트워크 레벨 제한은 Gateway Policy로, 민감한 관리 앱 SSO는 Access Policy로 병행한다.
Split Tunnel에서 Include 모드와 Exclude 모드 중 뭐가 나은가?
사설망 접근이 목적이면 Include 모드로 필요한 CIDR만 등록하는 게 깔끔하다. Exclude 모드로 전체 트래픽을 Cloudflare로 우회시키면 불필요한 지연과 비용을 만든다.