effidevFlutter · Cloudflare 엣지 · 클라우드 비용 최적화
한국어

Cloudflare Zero Trust Tunnel과 Access로 로컬 개발 및 스테이징 환경 안전하게 자동화하기

Cloudflare Zero Trust Tunnel과 Access를 활용한 로컬 개발 자동화

로컬 개발 환경이나 스테이징(Staging) 서버에 외부 결제 서비스(Stripe, PortOne) 웹훅이나 GitHub Actions 커밋 웹훅을 수신해야 할 때, 개발자들은 흔히 ngrok 같은 도구를 사용한다. 그러나 ngrok 무작위 URL 변경 문제, 세션 제한, 유료 구독 비용, 그리고 인바운드 방화벽 포트를 열어야 하는 보안 위험은 팀 단위 프론트엔드/백엔드 협업에서 커다란 장돌로 작용한다.

**Cloudflare Zero Trust Tunnel(cloudflared)**과 Cloudflare Access를 조합하면 인바운드 방화벽 포트(Inbound Port 80/443)를 단 1개도 열지 않고, 팀 고유 커스텀 도메인(dev.mycompany.com)으로 완벽하게 보안 설정된 터널을 무료로 구축할 수 있다.

이 글에서는 ngrok을 대체하는 cloudflared 데몬 구성법, Docker Compose 기반 자동화, Cloudflare Access OIDC(Google Workspace/GitHub SSO) 연동, 웹훅 전용 Service Token 우회 정책, 그리고 라스베가스 수준의 보안 감사 로깅 구축법을 실전 가이드로 제시한다.

핵심 요약

  • 인바운드 포트 0개(Zero Inbound Ports): cloudflared는 내부 개발 머신에서 Cloudflare 에지 노드로 아웃바운드(Outbound) 핑만 연결하므로 방화벽 포트를 개방할 필요가 전혀 없다.
  • 커스텀 도메인 & SSL 자동화: ngrok처럼 주소가 매번 바뀌지 않고 dev-alice.company.com 형태의 고정 도메인 및 Cloudflare 관리형 무료 TLS/SSL 인증서가 적용된다.
  • Cloudflare Access SSO 결합: 스테이징 환경 진입 시 Google Workspace 또는 GitHub SSO 패스스루 인증을 요구하여 해커의 무단 접근을 100% 차단한다.
  • Service Token을 통한 CI/CD 웹훅 우회: GitHub/Stripe 웹훅 수신 시 SSO 로그인 창을 띄우지 않고 HTTP Header 기반 CF-Access-Client-Id 인증으로 자동 통과 처리할 수 있다.

ngrok vs Cloudflare Zero Trust Tunnel 아키텍처 비교

비교 항목 ngrok (Free/Pro) Cloudflare Zero Trust Tunnel
기본 도메인 무작위 하브도메인 (재시작 시 변경) 고정 커스텀 도메인 (dev.domain.com)
방화벽 설정 ngrok 서버 수신 인바운드 포트 완전 차단 (Outbound Only)
인증 & SSO HTTP Basic Auth (Pro만 지원) Google/GitHub/Okta OIDC SSO 무료 포함
연동 디바이스 수 제한적 무제한 (Free 플랜 최대 50인 팀)
비용 월 $8 ~ $20/인 기본 Zero Trust Free 플랜 ($0)
DDoS 방어 제한적 Cloudflare 글로벌 L3/L4/L7 DDoS 방어

cloudflared 설치 및 터널 생성 실전 절차

Step 1. CLI 설치 및 Cloudflare 인증

# macOS Homebrew 설치
brew install cloudflared

# Cloudflare 계정 인증 (브라우저 로그인)
cloudflared tunnel login

Step 2. 터널 생성 및 DNS CNAME 레코드 바인딩

# 'dev-local-tunnel' 이름의 터널 생성
cloudflared tunnel create dev-local-tunnel

# 생성된 Tunnel ID 확인 (예: c8a3f81e-xxxx-xxxx-xxxx-xxxxxxxxxxxx)
# 커스텀 도메인에 DNS 레코드 라우팅 등록
cloudflared tunnel route dns dev-local-tunnel dev-api.mycompany.com

Step 3. config.yml 구성

~/.cloudflared/config.yml 파일을 작성하여 로컬 포트(예: 3000)로 트래픽을 전달한다.

tunnel: c8a3f81e-xxxx-xxxx-xxxx-xxxxxxxxxxxx
credentials-file: /Users/developer/.cloudflared/c8a3f81e-xxxx-xxxx-xxxx-xxxxxxxxxxxx.json

ingress:
  # 1. 로컬 3000번 개발 서버로 매핑
  - hostname: dev-api.mycompany.com
    service: http://localhost:3000
  # 2. 로컬 8080번 스테이징 서버 매핑
  - hostname: staging.mycompany.com
    service: http://localhost:8080
  # 3. Catch-all (404)
  - service: http_status:404

Step 4. 터널 백그라운드 실행

cloudflared tunnel run dev-local-tunnel

Docker Compose 환경에서 cloudflared 자동화

개발팀 전체가 동일한 터널 환경을 공유하도록 docker-compose.yml에 컨테이너로 내장시킬 수 있다.

version: "3.8"

services:
  app:
    build: .
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=development

  cloudflared:
    image: cloudflare/cloudflared:latest
    restart: unless-stopped
    command: tunnel --no-autoupdate run
    environment:
      - TUNNEL_TOKEN=${CLOUDFLARE_TUNNEL_TOKEN}

.env 파일에 CLOUDFLARE_TUNNEL_TOKEN만 작성해두면 개발자가 docker compose up 실행 시 즉시 로컬 인스턴스가 보안 터널로 외부에 노출된다.

Cloudflare Access OIDC 인증 및 웹훅 우회 설정

스테이징 웹사이트에 접근할 때 사내 구글 계정으로 로그인하게 만들면서, GitHub나 Stripe 웹훅 요청만 정상 수신하려면 Cloudflare Access Application Policy를 설정한다.

1. Access Application 생성

  1. Cloudflare Zero Trust 대시보드 -> Access -> Applications -> Add an Application
  2. Self-hosted 선택 후 Domain에 staging.mycompany.com 지정.
  3. Identity Provider로 Google Workspace 또는 GitHub 선택.

2. Service Token을 활용한 웹훅 Bypass 정책 설정

웹훅은 로그인 화면을 거칠 수 없으므로, HTTP 헤더에 Service Token이 포함된 경우 SSO를 우회(Bypass)하도록 정책 규칙(Rules)을 추가한다.

GitHub Actions나 외부 결제 서비스 설정 시 아래 헤더를 추가한다.

CF-Access-Client-Id: xxxxxxx.access
CF-Access-Client-Secret: yyyyyyyy-secret-token

보안 감사 로깅 (Audit Logs)

Cloudflare Zero Trust는 스테이징 환경에 접근한 모든 사용자의 이메일, IP 주소, 요청 URL, 타임스탬프를 실시간 로그로 기록한다. Zero Trust 대시보드의 Logs -> Access 메뉴에서 해킹 시도나 무단 접속을 즉각 감지할 수 있다.

결론

ngrok의 보안 취약점과 불안정한 URL 대신 Cloudflare Zero Trust Tunnel + Access를 도입하면, 팀원 전원에게 고정 커스텀 도메인과 SSO 보안이 적용된 로컬/스테이징 자동화 환경을 $0 비용으로 제공할 수 있다.