Cloudflare Tunnel + Zero Trust — Expose ứng dụng nội bộ ra Internet an toàn, miễn phí

Posted on: 4/18/2026 3:11:25 AM

Bạn đang phát triển một ứng dụng web trên máy cá nhân và muốn chia sẻ cho đồng nghiệp test mà không cần deploy lên server? Hay bạn có một dịch vụ nội bộ chạy trên mạng công ty, cần cho đối tác bên ngoài truy cập an toàn mà không muốn mở port trên firewall? Cloudflare Tunnel kết hợp Zero Trust Access giải quyết chính xác bài toán này — hoàn toàn miễn phí, không cần IP tĩnh, không cần mở port, và tích hợp sẵn bảo mật cấp enterprise.

330+ Data center toàn cầu của Cloudflare
$0 Chi phí Tunnel — không giới hạn bandwidth
50 users Zero Trust free tier
QUIC Giao thức mặc định từ 2025

1. Bài toán: Expose dịch vụ nội bộ ra Internet

Cách truyền thống để đưa một ứng dụng nội bộ (localhost, private network) lên Internet thường yêu cầu: mua IP tĩnh, cấu hình port forwarding trên router, mở firewall rule, và setup TLS certificate. Mỗi port mở là một attack surface tiềm tàng — đặc biệt nguy hiểm khi expose các dịch vụ nhạy cảm như admin panel, database UI, hay internal API.

graph LR
    subgraph Traditional["Cách truyền thống ⚠️"]
        direction LR
        A["Internet"] -->|"Port 443 mở"| B["Router/Firewall"]
        B -->|"Port Forward"| C["Server nội bộ"]
    end
    subgraph Tunnel["Cloudflare Tunnel ✅"]
        direction LR
        D["Internet"] -->|"HTTPS"| E["Cloudflare Edge"]
        F["cloudflared"] -->|"Outbound QUIC"| E
        F --- G["Server nội bộ"]
    end
    style Traditional fill:#fff5f5,stroke:#e94560
    style Tunnel fill:#f0fff0,stroke:#4CAF50
    style A fill:#e94560,stroke:#fff,color:#fff
    style D fill:#4CAF50,stroke:#fff,color:#fff
    style E fill:#2c3e50,stroke:#fff,color:#fff
    style B fill:#ff9800,stroke:#fff,color:#fff
    style C fill:#f8f9fa,stroke:#e0e0e0,color:#2c3e50
    style F fill:#f8f9fa,stroke:#4CAF50,color:#2c3e50
    style G fill:#f8f9fa,stroke:#e0e0e0,color:#2c3e50

So sánh mô hình truyền thống (mở port) vs Cloudflare Tunnel (outbound-only)

Với mô hình truyền thống, mỗi dịch vụ bạn expose ra ngoài đều phải đối mặt với DDoS, brute force, port scanning, và vô số rủi ro bảo mật. Cloudflare Tunnel đảo ngược hoàn toàn mô hình này: thay vì mở cửa cho traffic đi vào, bạn chỉ tạo kết nối đi ra từ server đến Cloudflare Edge — không có port nào mở trên firewall cả.

2. Cloudflare Tunnel — Kiến trúc và cách hoạt động

Cloudflare Tunnel hoạt động dựa trên daemon cloudflared — một chương trình nhẹ chạy trên cùng mạng với dịch vụ nội bộ. Daemon này thiết lập các kết nối outbound-only đến mạng lưới toàn cầu của Cloudflare, tạo thành một "đường hầm" (tunnel) an toàn.

sequenceDiagram
    participant User as 👤 User (Internet)
    participant CF as ☁️ Cloudflare Edge
    participant CD as 🔧 cloudflared
    participant App as 🖥️ Ứng dụng nội bộ

    Note over CD,CF: Bước 1 — cloudflared khởi tạo tunnel
    CD->>CF: Kết nối outbound qua QUIC (HTTP/3)
    CF-->>CD: Xác thực tunnel token
    CD->>CF: Mở nhiều connection đến các edge server khác nhau

    Note over User,CF: Bước 2 — User truy cập
    User->>CF: HTTPS request đến app.example.com
    CF->>CF: DNS resolve → CNAME đến tunnel UUID
    CF->>CF: Áp dụng WAF + DDoS Protection
    CF->>CD: Forward request qua tunnel QUIC
    CD->>App: Proxy đến localhost:3000
    App-->>CD: Response
    CD-->>CF: Trả về qua tunnel
    CF-->>User: HTTPS response (TLS tự động)

Luồng hoạt động của Cloudflare Tunnel — từ khởi tạo đến xử lý request

2.1. Outbound-only: Không cần mở port

Điểm then chốt của kiến trúc Tunnel: cloudflared chỉ tạo kết nối đi ra (outbound). Firewall của bạn mặc định cho phép traffic outbound, nên không cần cấu hình gì thêm. Tất cả inbound traffic từ Internet đều đi qua Cloudflare Edge trước, được lọc bởi WAF, chống DDoS, rồi mới chuyển tiếp qua tunnel đến server nội bộ.

2.2. QUIC — Giao thức mặc định

Từ 2025, cloudflared sử dụng QUIC (HTTP/3) làm giao thức mặc định thay cho HTTP/2 over TCP trước đây. QUIC mang lại nhiều lợi thế:

Đặc điểmHTTP/2 over TCP (cũ)QUIC (mới)
Head-of-Line BlockingẢnh hưởng tất cả stream trên cùng connectionMỗi stream độc lập, không ảnh hưởng lẫn nhau
Connection setupTCP handshake + TLS handshake (2-3 RTT)0-RTT hoặc 1-RTT (tích hợp TLS 1.3)
Reconnect sau mất mạngPhải thiết lập lại hoàn toànConnection migration — giữ nguyên session
MultiplexingBị ảnh hưởng bởi TCP HoL blockingTrue multiplexing ở transport layer
Trên mạng không ổn địnhChậm, hay timeoutResilient, tự phục hồi nhanh

Vì sao QUIC quan trọng với Tunnel?

Cloudflare Tunnel mở nhiều connection đồng thời đến các edge server khác nhau. Với HTTP/2, một packet loss trên TCP sẽ block toàn bộ stream trên connection đó (HoL blocking). QUIC giải quyết triệt để vấn đề này, giúp tunnel ổn định hơn đáng kể trên các mạng có độ trễ cao hoặc packet loss — rất phù hợp cho home lab hoặc mạng 4G/5G.

3. Thiết lập Cloudflare Tunnel từ đầu

Có hai cách quản lý tunnel: Dashboard-managed (khuyến nghị, cấu hình trên cloud) và Locally-managed (cấu hình bằng file YAML, phù hợp GitOps). Dưới đây là cả hai cách.

3.1. Cài đặt cloudflared

macOS
brew install cloudflared
Linux (Debian/Ubuntu)
curl -L https://pkg.cloudflare.com/install.sh | sudo bash
sudo apt install cloudflared
Windows (winget)
winget install Cloudflare.cloudflared
Docker
docker run -d --name cf-tunnel \
  --restart unless-stopped \
  cloudflare/cloudflared:latest \
  tunnel --no-autoupdate run --token YOUR_TUNNEL_TOKEN

3.2. Dashboard-managed Tunnel (Khuyến nghị)

Đây là cách đơn giản nhất, cấu hình hoàn toàn trên Cloudflare Dashboard:

Bước 1: Đăng nhập one.dash.cloudflare.comNetworksTunnelsCreate a tunnel

Bước 2: Chọn Cloudflared làm connector, đặt tên tunnel (ví dụ: my-homelab)

Bước 3: Copy token và chạy trên server:

cloudflared service install eyJhbGciOi...YOUR_TOKEN
# Hoặc chạy trực tiếp (không cài service):
cloudflared tunnel --no-autoupdate run --token eyJhbGciOi...YOUR_TOKEN

Bước 4: Quay lại Dashboard, thêm Public Hostname:

FieldGiá trị mẫuGiải thích
SubdomainappSubdomain bạn muốn
Domainexample.comDomain đã thêm vào Cloudflare
Service TypeHTTPGiao thức dịch vụ nội bộ
URLlocalhost:3000Địa chỉ dịch vụ nội bộ

Cloudflare tự động tạo DNS CNAME record trỏ đến tunnel UUID. TLS certificate cũng được cấp tự động — dịch vụ nội bộ chạy HTTP thuần, nhưng user truy cập qua HTTPS.

3.3. Locally-managed Tunnel (GitOps)

Nếu bạn muốn quản lý cấu hình bằng file (version control, IaC), dùng cách này:

Terminal
# Đăng nhập và tạo tunnel
cloudflared tunnel login
cloudflared tunnel create my-homelab

# Thêm DNS route
cloudflared tunnel route dns my-homelab app.example.com
cloudflared tunnel route dns my-homelab api.example.com
~/.cloudflared/config.yml
tunnel: my-homelab
credentials-file: /home/user/.cloudflared/<TUNNEL-UUID>.json

ingress:
  - hostname: app.example.com
    service: http://localhost:3000
  - hostname: api.example.com
    service: http://localhost:8080
    originRequest:
      connectTimeout: 30s
      noTLSVerify: true
  - hostname: ssh.example.com
    service: ssh://localhost:22
  # Catch-all rule — bắt buộc phải có
  - service: http_status:404

Catch-all rule là bắt buộc

File config.yml phải kết thúc bằng một rule không có hostname (catch-all). Nếu thiếu, cloudflared sẽ từ chối khởi động. Rule này xử lý các request không match hostname nào — thường trả về 404.

Terminal
# Chạy tunnel
cloudflared tunnel run my-homelab

# Hoặc cài làm system service (tự khởi động cùng OS)
sudo cloudflared service install
sudo systemctl enable cloudflared
sudo systemctl start cloudflared

4. Zero Trust Access — Bảo vệ dịch vụ bằng xác thực

Tunnel expose dịch vụ ra Internet, nhưng bạn không muốn ai cũng truy cập được. Cloudflare Zero Trust Access cho phép đặt lớp xác thực (authentication) phía trước dịch vụ — giống như đặt một "cổng bảo vệ" mà user phải đăng nhập trước khi vào.

graph TB
    subgraph ZeroTrust["Cloudflare Zero Trust"]
        direction TB
        A["User truy cập app.example.com"] --> B{"Access Policy"}
        B -->|"Chưa đăng nhập"| C["Login Page
(Email OTP / Google / GitHub)"] C --> D["Xác thực Identity"] D -->|"Pass"| E["Cho phép truy cập"] D -->|"Fail"| F["Chặn — 403"] B -->|"Đã có session"| E E --> G["Forward qua Tunnel"] G --> H["Dịch vụ nội bộ"] end style ZeroTrust fill:#f8f9fa,stroke:#e0e0e0 style A fill:#e94560,stroke:#fff,color:#fff style B fill:#ff9800,stroke:#fff,color:#fff style C fill:#2c3e50,stroke:#fff,color:#fff style E fill:#4CAF50,stroke:#fff,color:#fff style F fill:#e94560,stroke:#fff,color:#fff style H fill:#2c3e50,stroke:#fff,color:#fff

Luồng xác thực Zero Trust Access — user phải qua "cổng bảo vệ" trước khi đến dịch vụ

4.1. Cấu hình Access Application

Trên Dashboard one.dash.cloudflare.com:

Bước 1: Vào AccessApplicationsAdd an application → chọn Self-hosted

Bước 2: Nhập Application domain: app.example.com

Bước 3: Tạo Access Policy:

TrườngGiá trịGiải thích
Policy nameAllow team membersTên policy
ActionAllowCho phép truy cập nếu match
Include — Emails*@company.comCho phép toàn bộ email domain công ty
Include — Emailpartner@external.comHoặc cho phép email cụ thể

Bước 4: Chọn Identity Provider — mặc định là One-time PIN (gửi mã OTP qua email, không cần cấu hình gì thêm). Hoặc tích hợp Google, GitHub, Okta, Azure AD qua SettingsAuthentication.

Free tier đủ cho team nhỏ

Cloudflare Zero Trust free tier hỗ trợ đến 50 users — quá đủ cho startup, team phát triển, hoặc home lab cá nhân. Bao gồm Access policies, email OTP, và cả browser-rendered SSH/VNC. Nếu cần hơn 50 users, plan Pay-as-you-go bắt đầu từ ~$7/user/tháng.

4.2. Các Identity Provider được hỗ trợ

ProviderCấu hìnhPhù hợp với
One-time PIN (Email OTP)Không cần — sẵn cóSetup nhanh, cá nhân, demo
Google WorkspaceOAuth Client ID + SecretCông ty dùng Google
GitHubOAuth AppTeam developer, open source
Azure AD (Entra ID)App Registration + Tenant IDDoanh nghiệp dùng Microsoft 365
OktaOIDC/SAMLEnterprise SSO
SAML 2.0 GenericEntity ID + SSO URLBất kỳ IdP nào hỗ trợ SAML

5. Các use case thực tế

5.1. Home Lab — Self-host an toàn

Bạn chạy Homeassistant, Nextcloud, Grafana, hoặc media server (Jellyfin, Plex) trên NAS hoặc Raspberry Pi tại nhà. Thay vì mở port trên router (và lo lắng về bảo mật), dùng Tunnel để expose qua domain riêng với Access bảo vệ.

config.yml — Home Lab
tunnel: homelab
credentials-file: /home/pi/.cloudflared/uuid.json

ingress:
  - hostname: home.mydomain.com
    service: http://192.168.1.100:8123   # Home Assistant
  - hostname: cloud.mydomain.com
    service: http://192.168.1.100:8080   # Nextcloud
  - hostname: grafana.mydomain.com
    service: http://192.168.1.100:3000   # Grafana
  - service: http_status:404

5.2. Development — Chia sẻ localhost cho team

Đang develop feature mới, muốn PM hoặc designer test trên điện thoại mà không cần deploy?

Terminal — Quick tunnel (tạm thời)
# Tạo tunnel tạm — random URL, mất khi tắt terminal
cloudflared tunnel --url http://localhost:5173

# Output: https://random-words.trycloudflare.com
Terminal — Named tunnel (lâu dài)
# Hoặc dùng named tunnel cho URL cố định
# dev.mydomain.com luôn trỏ đến máy bạn
cloudflared tunnel route dns dev-laptop dev.mydomain.com
cloudflared tunnel run dev-laptop

5.3. SSH/RDP không cần VPN

Cloudflare hỗ trợ render SSH và RDP ngay trên trình duyệt — user không cần cài client. Kết hợp Access để chỉ cho phép người được uỷ quyền truy cập.

graph LR
    A["Admin"] -->|"Mở browser"| B["ssh.example.com"]
    B --> C["Cloudflare Access
Xác thực email OTP"] C --> D["Browser-rendered SSH"] D -->|"Qua Tunnel"| E["Server SSH
port 22"] style A fill:#e94560,stroke:#fff,color:#fff style B fill:#2c3e50,stroke:#fff,color:#fff style C fill:#ff9800,stroke:#fff,color:#fff style D fill:#4CAF50,stroke:#fff,color:#fff style E fill:#f8f9fa,stroke:#e0e0e0,color:#2c3e50

SSH qua trình duyệt — không cần VPN, không cần SSH client

5.4. Multi-service trên cùng server

Một tunnel duy nhất có thể expose nhiều dịch vụ trên các hostname khác nhau — không cần nhiều tunnel hay nhiều server:

graph TB
    subgraph Cloudflare["Cloudflare Edge"]
        direction LR
        D1["app.example.com"]
        D2["api.example.com"]
        D3["admin.example.com"]
    end
    subgraph Server["Server nội bộ"]
        direction LR
        T["cloudflared"]
        S1["Vue App :5173"]
        S2[".NET API :5000"]
        S3["Admin Panel :8080"]
    end
    D1 --> T
    D2 --> T
    D3 --> T
    T --> S1
    T --> S2
    T --> S3
    style Cloudflare fill:#f8f9fa,stroke:#2c3e50
    style Server fill:#f0fff0,stroke:#4CAF50
    style T fill:#e94560,stroke:#fff,color:#fff
    style S1 fill:#fff,stroke:#4CAF50,color:#2c3e50
    style S2 fill:#fff,stroke:#4CAF50,color:#2c3e50
    style S3 fill:#fff,stroke:#4CAF50,color:#2c3e50

Một tunnel — nhiều dịch vụ trên các hostname khác nhau

6. High Availability và Production Deployment

6.1. Replica connector

Dùng cùng một tunnel token trên nhiều máy — Cloudflare tự động load balance giữa các connector. Nếu một máy chết, traffic chuyển sang máy còn lại mà không downtime.

docker-compose.yml — HA Tunnel
services:
  tunnel-1:
    image: cloudflare/cloudflared:latest
    restart: unless-stopped
    command: tunnel --no-autoupdate run --token ${TUNNEL_TOKEN}

  tunnel-2:
    image: cloudflare/cloudflared:latest
    restart: unless-stopped
    command: tunnel --no-autoupdate run --token ${TUNNEL_TOKEN}

  web-app:
    image: my-web-app:latest
    ports:
      - "3000:3000"

6.2. Infrastructure as Code với Terraform

Từ 2026, Terraform provider v5 của Cloudflare đã ổn định, hỗ trợ đầy đủ quản lý tunnel qua IaC:

main.tf
resource "cloudflare_zero_trust_tunnel_cloudflared" "homelab" {
  account_id = var.cloudflare_account_id
  name       = "homelab-tunnel"
  secret     = random_id.tunnel_secret.b64_std
}

resource "cloudflare_zero_trust_tunnel_cloudflared_config" "homelab" {
  account_id = var.cloudflare_account_id
  tunnel_id  = cloudflare_zero_trust_tunnel_cloudflared.homelab.id

  config {
    ingress_rule {
      hostname = "app.${var.domain}"
      service  = "http://localhost:3000"
    }
    ingress_rule {
      service = "http_status:404"
    }
  }
}

resource "cloudflare_record" "app" {
  zone_id = var.cloudflare_zone_id
  name    = "app"
  content = "${cloudflare_zero_trust_tunnel_cloudflared.homelab.id}.cfargotunnel.com"
  type    = "CNAME"
  proxied = true
}

7. So sánh Cloudflare Tunnel với các giải pháp khác

Tiêu chíCloudflare TunnelngrokTailscalefrp (self-hosted)
Chi phíFree, không giới hạnFree (1 agent, 1 domain). Pro $15/thángFree (100 devices)Free (cần server)
Custom domain✅ Miễn phíChỉ plan trả phíQua MagicDNS nội bộ✅ Tự cấu hình
TLS tự động✅ (nội bộ)❌ Cần Let's Encrypt
DDoS Protection✅ Tích hợp sẵnHạn chế
WAF✅ Free tier
Auth/SSO✅ Zero Trust AccessOAuth (trả phí)✅ Tailscale ACL
HA/Load Balance✅ Multi-connectorChỉ plan Enterprise✅ Peer-to-peer❌ Manual
Mô hìnhEdge proxy (public)Edge proxy (public)Peer-to-peer (private)Reverse proxy
Phù hợpExpose public + bảo mậtDemo nhanh, webhookMạng nội bộ teamFull control

Khi nào KHÔNG nên dùng Cloudflare Tunnel?

Peer-to-peer networking: Nếu bạn chỉ cần các máy trong team kết nối với nhau (không public), Tailscale hoặc WireGuard phù hợp hơn. Data residency: Nếu pháp lý yêu cầu data không đi qua bên thứ ba, dùng frp hoặc VPN riêng. Serving static files lớn: Dùng Cloudflare R2 hoặc Pages thay vì tunnel đến file server.

8. Bảo mật nâng cao

8.1. Kết hợp nhiều lớp bảo vệ

graph TB
    A["Request từ Internet"] --> B["Layer 1: Cloudflare DDoS Protection"]
    B --> C["Layer 2: WAF Rules"]
    C --> D["Layer 3: Bot Management"]
    D --> E["Layer 4: Zero Trust Access
(Email OTP / SSO)"] E --> F["Layer 5: Access Policy
(Email domain, country, device)"] F --> G["Layer 6: Tunnel mã hóa QUIC"] G --> H["Dịch vụ nội bộ"] style A fill:#e94560,stroke:#fff,color:#fff style B fill:#2c3e50,stroke:#fff,color:#fff style C fill:#2c3e50,stroke:#fff,color:#fff style D fill:#2c3e50,stroke:#fff,color:#fff style E fill:#ff9800,stroke:#fff,color:#fff style F fill:#ff9800,stroke:#fff,color:#fff style G fill:#4CAF50,stroke:#fff,color:#fff style H fill:#f8f9fa,stroke:#e0e0e0,color:#2c3e50

6 lớp bảo mật từ edge đến origin — tất cả miễn phí trên free tier

8.2. Lockdown firewall hoàn toàn

cloudflared chỉ tạo kết nối outbound, bạn có thể lockdown firewall server hoàn toàn — chặn tất cả inbound traffic. Điều này biến server từ "có thể scan được từ Internet" thành "vô hình" (invisible) với mọi port scanner.

iptables — Lockdown hoàn toàn inbound
# Chỉ cho phép outbound traffic (cloudflared cần)
# Block toàn bộ inbound (trừ established connections)
sudo iptables -P INPUT DROP
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
sudo iptables -A INPUT -i lo -j ACCEPT

# Server giờ "vô hình" — nmap sẽ không thấy port nào mở
# Nhưng cloudflared vẫn hoạt động bình thường vì chỉ tạo outbound connections

8.3. Service Token cho API-to-API

Nếu một service bên ngoài cần gọi API qua tunnel (không phải người dùng đăng nhập), dùng Service Token thay cho Access Policy:

# Tạo service token trong Dashboard:
# Access → Service Auth → Create Service Token
# Lưu lại CF-Access-Client-Id và CF-Access-Client-Secret

# Gọi API với service token:
curl -H "CF-Access-Client-Id: YOUR_CLIENT_ID" \
     -H "CF-Access-Client-Secret: YOUR_CLIENT_SECRET" \
     https://api.example.com/internal/endpoint

9. Monitoring và Troubleshooting

9.1. Kiểm tra trạng thái tunnel

# Xem danh sách tunnel
cloudflared tunnel list

# Xem chi tiết connections
cloudflared tunnel info my-homelab

# Metrics endpoint (Prometheus-compatible)
cloudflared tunnel --metrics localhost:2000 run my-homelab
# Truy cập http://localhost:2000/metrics để xem metrics

9.2. Diagnostic logs

# Bật debug log
cloudflared tunnel --loglevel debug run my-homelab

# Từ 2026, QUIC connection metrics chi tiết hơn:
# - Số stream active
# - RTT trung bình đến edge
# - Packet loss rate
# - Connection migration events

Dashboard monitoring

Trên one.dash.cloudflare.comNetworksTunnels, bạn có thể xem real-time: tunnel status (healthy/degraded/down), connector version, edge location đang kết nối, và traffic volume. Không cần thiết lập gì thêm — có sẵn với free tier.

10. Checklist triển khai Production

#Hạng mụcChi tiết
1Cài cloudflared như system servicesudo cloudflared service install — tự restart khi crash hoặc reboot
2Dùng Dashboard-managed tunnelCấu hình cloud-side, dễ quản lý từ xa, không cần SSH vào server để thay đổi
3Bật Zero Trust AccessTối thiểu email OTP cho tất cả dịch vụ có UI
4Service Token cho APIDùng CF-Access-Client-Id + CF-Access-Client-Secret cho API-to-API
5Lockdown firewallBlock toàn bộ inbound traffic — cloudflared chỉ cần outbound
6HA với multi-connectorChạy cùng token trên 2+ máy để tránh SPOF
7MonitoringEnable metrics endpoint + kiểm tra Dashboard tunnel health
8Terraform (nếu multi-env)IaC cho tunnel + Access policies, dễ replicate giữa staging/prod

Tổng kết

Cloudflare Tunnel + Zero Trust Access là một trong những giải pháp free-tier mạnh nhất hiện tại cho việc expose dịch vụ nội bộ ra Internet. Không cần IP tĩnh, không cần mở port, TLS tự động, DDoS protection tích hợp, và lớp xác thực Zero Trust — tất cả với $0. Từ home lab cá nhân đến startup production, đây là công cụ mà mọi developer và sysadmin nên có trong toolkit.

Tham khảo: