建立Cloudflare Tunnel
Ubuntu 26.04 使用 Cloudflare Tunnel 建立對外 Server 設定教學
適用環境: Ubuntu 26.04、4G/LTE Router、CGNAT、Web Server / API Server 文件版本: 2026-09 Cloudflare 設定方式: Remotely-managed Tunnel
1. 目的
本文件說明如何讓位於 4G/LTE Router 後方的 Ubuntu Server,透過 Cloudflare Tunnel 對 Internet 提供網站或 API 服務。
此架構不需要:
- 固定 Public IP
- 電信商提供 Public IPv4
- Router Port Forwarding
- Router DMZ
- 開放 TCP 80 / 443 inbound
因此即使 4G/LTE 電信網路採用 CGNAT,也可以建立公開網站。
Cloudflare Tunnel 的運作方式是由 Ubuntu 上的 cloudflared 主動向 Cloudflare 建立 outbound connection,因此 Internet 使用者不會直接連到 LTE Router 或 Ubuntu 的 Public IP。Cloudflare 官方要求 Server 可主動連到 Cloudflare,主要 Tunnel 流量使用 TCP/UDP 7844。
2. 系統架構
假設環境如下:
Internet 使用者
│
│ https://server.example.com
▼
┌──────────────────────┐
│ Cloudflare │
│ DNS / HTTPS / WAF │
└──────────┬───────────┘
│
│ Cloudflare Tunnel
│ outbound connection
│
▼
┌──────────────────────┐
│ 4G / LTE Router │
│ │
│ CGNAT 可以 │
│ 不需 Port Forwarding │
└──────────┬───────────┘
│ LAN
│
▼
┌────────────────────────────┐
│ Ubuntu Server 26.04 │
│ │
│ cloudflared │
│ │ │
│ └── localhost:8080 │
│ │ │
│ Web / API │
└────────────────────────────┘
本文件以以下設定為範例:
網域:
example.com
公開網址:
https://server.example.com
Ubuntu Server:
192.168.8.10
Web Server:
http://127.0.0.1:8080
實際安裝時請將 example.com 與 Port 8080 改成實際環境。
3. 前置條件
需要準備:
- Cloudflare 帳號
- 一個網域,例如
example.com - 該網域已加入 Cloudflare
- Ubuntu Server 可以正常連 Internet
- Ubuntu 上已有欲發布的 Web / API 服務
Cloudflare 官方要求,若要透過 Public Hostname 正式發布應用程式,網域必須由 Cloudflare 管理。
例如:
example.com
已經加入 Cloudflare DNS 管理後,可以建立:
server.example.com
api.example.com
grafana.example.com
app.example.com
4. 確認 Ubuntu 網路
首先確認 Ubuntu Server 可以正常連 Internet。
ip addr
確認 Default Route:
ip route
測試 Internet:
ping -c 4 1.1.1.1
再測試 DNS:
ping -c 4 cloudflare.com
亦可確認目前對外 IP:
curl -4 https://ifconfig.me
即使此 IP 是 4G 電信商 CGNAT 後方的共享 IP,也不影響 Cloudflare Tunnel。
5. 確認 Web Server 正常運作
Cloudflare Tunnel 設定之前,應先確認應用程式本身可正常使用。
例如服務使用:
127.0.0.1:8080
執行:
curl http://127.0.0.1:8080
若回傳 HTML 或 API Response,即表示服務正常。
亦可確認目前有哪些 TCP Port 正在 Listen:
sudo ss -lntp
例如:
LISTEN 0 511 127.0.0.1:8080
代表服務正在:
http://127.0.0.1:8080
等待連線。
6. 安裝 cloudflared
6.1 安裝 Cloudflare Repository Signing Key
執行:
sudo mkdir -p --mode=0755 /usr/share/keyrings
下載 Cloudflare repository signing key:
curl -fsSL https://pkg.cloudflare.com/cloudflare-main.gpg \
| sudo tee /usr/share/keyrings/cloudflare-main.gpg >/dev/null
6.2 加入 Cloudflare APT Repository
echo "deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/cloudflared any main" \
| sudo tee /etc/apt/sources.list.d/cloudflared.list
6.3 安裝 cloudflared
sudo apt update
sudo apt install cloudflared
確認版本:
cloudflared --version
Cloudflare 官方目前仍提供 Debian / Ubuntu APT repository 作為 cloudflared 的正式安裝方式。
7. 在 Cloudflare 建立 Tunnel
登入 Cloudflare Dashboard。
進入:
Networking
↓
Tunnels
↓
Create Tunnel
Cloudflare 官方目前的 Dashboard 建立流程即位於:
Networking → Tunnels
7.1 建立 Tunnel 名稱
例如輸入:
ubuntu-lte-server
名稱主要供管理辨識使用。
建議採:
production-web
office-server
lab-server
ubuntu-lte-server
hospital-demo-server
等容易辨識的名稱。
按:
Create Tunnel
8. 將 Ubuntu Server 加入 Tunnel
建立 Tunnel 後,Cloudflare 會出現:
Setup Environment
選擇:
Operating System:Debian
Architecture:64-bit
Cloudflare 會產生一條包含 Tunnel Token 的指令。
形式大致如下:
sudo cloudflared service install <TUNNEL_TOKEN>
例如:
sudo cloudflared service install eyJhIjoiXXXXXXXXXXXX...
請直接使用 Cloudflare Dashboard 產生的實際指令,不要自行製造 Token。
Cloudflare 官方目前正式使用:
sudo cloudflared service install <TUNNEL_TOKEN>
將 remotely-managed tunnel 安裝成 Linux system service。
9. Tunnel Token 安全注意事項
TUNNEL_TOKEN 應視為機密資訊。
不得:
上傳 GitHub
放進公開 Wiki
貼在公開文件
放入 Dockerfile
放入網站 JavaScript
寄到公開 Mailing List
Cloudflare 明確指出,持有 Tunnel Token 的人即可啟動該 Tunnel connector,因此應將 Token 視為憑證管理。若 Token 洩漏,應立即 Rotate Token。
10. 確認 cloudflared Service
安裝完成後:
sudo systemctl status cloudflared
正常情況應顯示:
Active: active (running)
可確認是否設定為開機自動啟動:
sudo systemctl is-enabled cloudflared
預期:
enabled
若需重新啟動:
sudo systemctl restart cloudflared
查看即時 Log:
sudo journalctl -u cloudflared -f
11. 確認 Cloudflare Tunnel 狀態
回到:
Cloudflare Dashboard
Networking
→ Tunnels
正常情況 Tunnel 應顯示:
Healthy
Cloudflare 官方亦以 Healthy 作為 connector 已成功連接的狀態。
架構此時已經形成:
Cloudflare
▲
│
│ persistent outbound tunnel
│
cloudflared
│
Ubuntu
但是目前還沒有指定哪個網址要連到哪一個 Server Port。
12. 建立 Public Hostname
點選:
Networking
→ Tunnels
→ ubuntu-lte-server
進入:
Routes
→ Add route
選擇:
Published application
Cloudflare 目前將 Public Hostname 與 Local Service 的對應稱為 Published Application route。
13. 設定網域名稱
假設希望建立:
https://server.example.com
設定:
Hostname
Subdomain:
server
Domain:
example.com
最後形成:
server.example.com
14. 設定 Service URL
假設 Ubuntu 上的 Web Server 是:
http://127.0.0.1:8080
設定:
Service URL:
http://localhost:8080
或:
http://127.0.0.1:8080
然後選擇:
Add route
Cloudflare 官方支援直接將 hostname 對應至同一台主機,例如:
app.example.com
↓
http://localhost:8080
若服務在另一台 LAN Server,也可以設定 LAN IP,例如:
http://192.168.8.20:8080
15. HTTPS 如何處理
如果 Ubuntu 上的 Web Server 為:
http://localhost:8080
並不表示 Internet 使用者只能使用 HTTP。
外部仍然使用:
https://server.example.com
流程為:
Browser
HTTPS
│
▼
Cloudflare
│
│ Cloudflare Tunnel
▼
cloudflared
HTTP localhost
│
▼
Web Server :8080
因此若 cloudflared 與 Web Server 在同一台 Ubuntu 上,通常可以直接:
Service URL:
http://localhost:8080
不需要為 localhost 額外申請 TLS Certificate。
16. DNS 設定
使用 Dashboard 建立 Published Application route 時,Cloudflare 會建立對應的 Tunnel DNS 設定。
其概念為:
server.example.com
CNAME
<TUNNEL-ID>.cfargotunnel.com
Cloudflare 官方說明,透過 Dashboard 建立 Public Hostname 時會自動建立指向 Tunnel 的 DNS record。
因此一般不需要另外手動新增 A Record:
server.example.com → LTE Public IP
也不應該將 4G Router 的 IP 當作此服務的 A Record。
17. 外部測試
設定完成後:
curl https://server.example.com
或直接使用 Browser:
https://server.example.com
建議另外使用:
手機 5G
其他公司網路
家用光纖
等不在該 LTE Router LAN 裡的網路進行測試。
若可以正常開啟,即代表:
Internet
→ Cloudflare
→ Tunnel
→ LTE
→ Ubuntu
→ Web Server
整條路徑正常。
18. Router 不需要設定 Port Forwarding
使用 Cloudflare Tunnel 後,4G Router 不需要:
TCP 80 Forwarding
TCP 443 Forwarding
DMZ
UPnP
Public IP
固定 IP
原因是連線方向為:
Ubuntu
│
│ Outbound
▼
Cloudflare
而不是:
Internet
│
│ Inbound
▼
LTE Router
這也是 Cloudflare Tunnel 特別適合 4G、5G、CGNAT 環境的主要原因。
19. Ubuntu Firewall 建議
如果只透過 Cloudflare Tunnel 提供 Web Service,Ubuntu 不需要對 Internet 開放:
80
443
8080
可使用 UFW:
sudo ufw default deny incoming
sudo ufw default allow outgoing
如果仍需要從區網 SSH 管理,例如 LAN 為:
192.168.8.0/24
可只允許 LAN:
sudo ufw allow from 192.168.8.0/24 to any port 22 proto tcp
啟用:
sudo ufw enable
確認:
sudo ufw status verbose
形成:
Inbound:
Internet → 22 ✗
Internet → 80 ✗
Internet → 443 ✗
Internet → 8080 ✗
LAN → SSH 22 ✓
Outbound:
Ubuntu → Cloudflare ✓
這會比直接將 Server Port Forward 到 Internet 安全許多。
20. 特殊 Firewall 環境
一般 Ubuntu:
sudo ufw default allow outgoing
即可正常建立 Cloudflare Tunnel。
如果公司 Firewall 特別限制 outbound traffic,必須允許:
TCP 7844
UDP 7844
由 Ubuntu 向 Cloudflare outbound。
Cloudflare 官方目前說明,Tunnel 主要使用:
UDP 7844 → QUIC
TCP 7844 → HTTP/2
因此限制型 Firewall 應允許 TCP 與 UDP 7844 outbound。
不需要允許:
Internet → Server TCP 7844
因為 7844 是 outbound connection。
21. 建議讓 Web Server 只 Listen localhost
如果 Web Application 與 cloudflared 在同一台 Ubuntu,建議應用程式 Listen:
127.0.0.1
而不是:
0.0.0.0
例如:
127.0.0.1:8080
這樣 LAN 裡其他電腦也不能直接存取 8080。
架構會成為:
Internet
│
▼
Cloudflare
│
▼
cloudflared
│
▼
127.0.0.1:8080
│
▼
Application
此方式可進一步減少服務直接暴露的範圍。
22. 一個 Tunnel 可以發布多個服務
不需要每一個網站都建立一個 Tunnel。
例如同一個 Tunnel:
ubuntu-lte-server
可以設定:
www.example.com
↓
http://localhost:80
api.example.com
↓
http://localhost:8080
grafana.example.com
↓
http://localhost:3000
ai.example.com
↓
http://localhost:8000
Cloudflare Tunnel 支援在一個 Tunnel 中建立多個 Published Applications。
因此比較建議:
一台 Server / 一個網路環境
↓
一個 Tunnel
↓
多個 Hostname / Service
而不是每個 Application 建立一個 Tunnel。
23. Docker 環境範例
假設 Ubuntu Docker 中執行:
docker run -d \
--name myapp \
-p 127.0.0.1:8080:8080 \
myapp
則 Cloudflare Tunnel:
server.example.com
↓
http://localhost:8080
即可。
推薦:
-p 127.0.0.1:8080:8080
而非:
-p 8080:8080
因為前者只會將應用程式發布到 localhost。
24. Nginx 架構範例
較完整的正式 Server 可以採:
Internet
│
▼
Cloudflare
│
│ Tunnel
▼
cloudflared
│
▼
Nginx
127.0.0.1:80
│
├── /api
│ ↓
│ FastAPI :8000
│
├── /app
│ ↓
│ Node :3000
│
└── /
↓
Web Site
Cloudflare 設定:
server.example.com
↓
http://localhost:80
由 Nginx 再負責 Reverse Proxy。
對具有多個 Web Service 的 Ubuntu Server,此架構較容易維護。
25. 常用維護指令
確認 cloudflared:
cloudflared --version
查看狀態:
sudo systemctl status cloudflared
啟動:
sudo systemctl start cloudflared
停止:
sudo systemctl stop cloudflared
重新啟動:
sudo systemctl restart cloudflared
開機自動啟動:
sudo systemctl enable cloudflared
即時 Log:
sudo journalctl -u cloudflared -f
最近 100 筆 Log:
sudo journalctl -u cloudflared -n 100
26. 更新 cloudflared
因為透過 APT Repository 安裝,可以定期執行:
sudo apt update
sudo apt upgrade
或只更新:
sudo apt install --only-upgrade cloudflared
更新完成後:
sudo systemctl restart cloudflared
27. 常見問題排除
問題一:Cloudflare 顯示 Tunnel Down / Disconnected
先檢查:
sudo systemctl status cloudflared
再看:
sudo journalctl -u cloudflared -n 100
確認 Ubuntu Internet:
ping cloudflare.com
若有嚴格 Firewall,確認 outbound TCP/UDP 7844 未被封鎖。
問題二:網站顯示 502 Bad Gateway
通常代表:
Browser
↓
Cloudflare OK
↓
Tunnel OK
↓
cloudflared OK
↓
Application ERROR
先執行:
curl http://127.0.0.1:8080
如果本機都連不到,問題並不在 Cloudflare,而是 Application。
再確認:
sudo ss -lntp
例如實際服務為:
127.0.0.1:8000
但 Cloudflare 設定:
localhost:8080
就會產生錯誤。
問題三:HTTP / HTTPS 設錯
如果 Application 實際為:
http://localhost:8080
Cloudflare Service URL 就應設定:
http://localhost:8080
不要設定:
https://localhost:8080
外部網址仍然可以使用:
https://server.example.com
問題四:HTTPS Origin Certificate Error
如果 Backend 本身使用 HTTPS:
https://localhost:443
則需確保 Backend Certificate 與 Cloudflare Tunnel 的 TLS 設定正確。
若沒有特殊需求,而且:
cloudflared
與:
Web Server
在同一台主機,通常直接採:
http://localhost
會較簡單。
不要為了解決錯誤就長期關閉 Certificate Verification。
問題五:Tunnel 正常,但 DNS 找不到
測試:
nslookup server.example.com
或:
dig server.example.com
確認 Cloudflare Dashboard:
Networking
→ Tunnels
→ Tunnel
→ Routes
是否真的已建立:
server.example.com
↓
http://localhost:8080
28. Tunnel Token 洩漏處理
如果 Token 曾經:
貼到 GitHub
貼到公開 Chat
寄出
外洩
被其他人取得
不要只刪除文字,應直接更換 Token。
Cloudflare Dashboard:
Networking
→ Tunnels
→ 選擇 Tunnel
→ Rotate token
然後 Ubuntu:
sudo cloudflared service uninstall
再以新 Token:
sudo cloudflared service install <NEW_TOKEN>
Cloudflare 官方說明,Token rotate 後舊 Token 將無法建立新的 connector connection。
29. 建議正式環境設定
正式環境建議採:
4G LTE Router
│
│ 不設定 Port Forwarding
│
Ubuntu Server
│
├── UFW deny incoming
│
├── SSH 僅允許 LAN / VPN
│
├── cloudflared
│
└── Application
│
└── 127.0.0.1 only
公開端:
server.example.com
│
▼
Cloudflare
│
│ HTTPS
│ WAF
│ DDoS protection
│ Tunnel
▼
Ubuntu Server
30. 建議的完整設定範例
假設:
Domain:
example.com
Public URL:
https://server.example.com
Ubuntu:
192.168.8.10
Application:
127.0.0.1:8080
最終設定為:
Cloudflare Tunnel
Name:
ubuntu-lte-server
Published Application:
Hostname:
server.example.com
Service:
http://localhost:8080
Ubuntu:
sudo systemctl status cloudflared
應為:
active (running)
Application:
curl http://127.0.0.1:8080
應正常回覆。
外部:
curl https://server.example.com
應正常回覆。
Router:
Port Forwarding:無
DMZ:無
Public IP:不需要
Static IP:不需要
31. 完成後檢查清單
正式上線前依序確認:
- Domain 已由 Cloudflare 管理
- Ubuntu 可以連 Internet
- Local Application 可以正常使用
cloudflared已安裝- Cloudflare Tunnel 已建立
cloudflaredsystemd service 為 Running- Cloudflare Tunnel 顯示 Healthy
- Published Application 已建立
- Hostname 設定正確
- Service URL 與 Application Port 一致
- 外部 HTTPS 可以正常開啟
- LTE Router 未開 Port Forwarding
- Ubuntu UFW 不對外開放 Application Port
- Tunnel Token 未存放於 GitHub 或公開文件
- SSH 不直接暴露於 Internet
完成以上項目後,Ubuntu Server 即可透過 4G/LTE 網路穩定提供對外 Web / API 服務。
32. 最終架構
Internet
│
│
https://server.example.com
│
▼
┌─────────────────────┐
│ Cloudflare │
│ │
│ DNS / TLS / WAF │
│ DDoS Protection │
└──────────┬──────────┘
│
│ Cloudflare Tunnel
│ TCP/UDP 7844 outbound
│
┌──────────▼──────────┐
│ 4G / LTE Network │
│ CGNAT │
└──────────┬──────────┘
│
┌──────────▼──────────┐
│ LTE Router │
│ │
│ No Port Forwarding │
│ No DMZ │
└──────────┬──────────┘
│
192.168.8.10
│
┌──────────▼──────────┐
│ Ubuntu 26.04 │
│ │
│ cloudflared │
│ │ │
│ ▼ │
│ localhost:8080 │
│ │ │
│ ▼ │
│ Web / API │
└─────────────────────┘
此架構特別適用於 4G/5G Router、行動式設備、展示場域、偏鄉據點、臨時 POC Server,以及無法取得固定 Public IP 的環境。