這是本文件的舊版!
設定 Cloudflare Tunnel 提供對外網站服務
架構說明
原本架構
flowchart LR
A[User Browser] --> B["Cloudflare Proxy
(CDN)"] B --> C[Firewall] C --> D["Nginx Proxy Manager
(Reverse Proxy)"] D --> E[WebServer 1] D --> F[WebServer 2] D --> G[WebServer 3] D --> H[...] D --> I[WebServer n]
(CDN)"] B --> C[Firewall] C --> D["Nginx Proxy Manager
(Reverse Proxy)"] D --> E[WebServer 1] D --> F[WebServer 2] D --> G[WebServer 3] D --> H[...] D --> I[WebServer n]
- 這架構需要 Firewall 上面有固定 IP , 並設定 Port Forwarding 到 Reverse Proxy 主機上
- 在 Reverse Proxy 上面設定每個 WebServer 的 Proxy Forward 網址與 SSL 憑證
Cloudflare Tunnel 架構
flowchart LR
A[User Browser] --> B["Cloudflare Network
Tunnels Service
(CDN + Reverse Proxy)"] subgraph D [Cloudflared Connectors] D1["Cloudflared
(Connector A)"] D2["Cloudflared
(Connector B)"] D3["Cloudflared
(Connector C)"] %% 強制垂直排列 D1 ~~~ D2 D2 ~~~ D3 end D -->|通過| C[Firewall] C -->|主動連接| B D --> E[WebServer 1] D --> F[WebServer 2] D --> G[WebServer 3] D --> H[...] D --> I[WebServer n]
Tunnels Service
(CDN + Reverse Proxy)"] subgraph D [Cloudflared Connectors] D1["Cloudflared
(Connector A)"] D2["Cloudflared
(Connector B)"] D3["Cloudflared
(Connector C)"] %% 強制垂直排列 D1 ~~~ D2 D2 ~~~ D3 end D -->|通過| C[Firewall] C -->|主動連接| B D --> E[WebServer 1] D --> F[WebServer 2] D --> G[WebServer 3] D --> H[...] D --> I[WebServer n]
- 這架構不需要 Firewall 上面有固定 IP , 也不用設定 Port Forwarding
設定方式
1. 建立 Cloudflare Tunnel
2. 選擇 Cloudflared 安裝環境
- 將連結的 token 取出
- 改用 docker compose 方式進行 Cloudflared 部署
wget https://raw.githubusercontent.com/tryweb/docker-compose/refs/heads/main/cloudflared/docker-compose.yml wget https://raw.githubusercontent.com/tryweb/docker-compose/refs/heads/main/cloudflared/.env.example
docker-compose.yml
services: cloudflared: image: cloudflare/cloudflared restart: always command: 'tunnel --no-autoupdate run --token ${TOKEN}' watchtower: container_name: watchtower image: containrrr/watchtower volumes: - /var/run/docker.sock:/var/run/docker.sock environment: - TZ=Asia/Taipei - WATCHTOWER_SCHEDULE=0 0 4 * * * # 每天凌晨4點檢查更新 - WATCHTOWER_CLEANUP=true # 清理舊的映像檔 #- WATCHTOWER_NOTIFICATIONS=slack # 使用 Slack 通知 #- SLACK_HOOK_URL=https://hooks.slack.com/services/YOUR/SLACK/WEBHOOK labels: - "com.centurylinklabs.watchtower.enable=true" restart: unless-stopped
.env
TOKEN=eyJhIjoixxxxxxxxxxxxxx
https://raw.githubusercontent.com/tryweb/docker-compose/refs/heads/main/cloudflared/.env.example
- 將 .env.example 改名為 .env 並將 token 修改成剛剛 docker cli 取出的值
- 啟動 docker compose
docker compose pull docker compose up -d docker compose logs -f
3. 建立多台 Cloudflared 環境
- 因為 Cloudflared 如果異常, 整體網路就無法正常運作, 所以可以建立多台來支援, 也可以分攤流量
- 但是在同一個 Cloudflare Tunnel 的多台 Cloudflared , 必須在相同網段才能合理運作, Exp. Cloudflared A : 192.168.11.4/24 , Cloudflared B : 192.168.11.7/24 , Cloudflared C : 192.168.11.9/24
- 安裝程序如同上一步驟, Token 都相同
4. 確認 Cloudflare Tunnel 狀態
5. 設定網站對應
- 這步驟類似 Nginx Proxy Manager(Reverse Proxy)設定網站對應
- 新增一個網站會在 Cloudflare 該網域的 DNS 建立一筆 CNAME 紀錄, 如果 DNS 已經有一筆 A 或衝突的紀錄, 就會新增失敗, 需要回到 DNS 管理將衝突的紀錄先刪除
- 要先到 Cloudflared 內驗證要 Forward 的網址 Exp. http://192.168.11.233 是否可以正常存取
- 如果新增成功, 可以查看網站的紀錄 Exp. access.log 可以看到流量會由三台 Cloudflared 隨機進入
: 192.168.11.4 - - [03/Apr/2025:19:25:24 +0800] "GET / HTTP/1.1" 200 36257 "-" "check_http/v (monitoring-plugins 2.4.0)" 192.168.11.4 - - [03/Apr/2025:19:30:23 +0800] "GET / HTTP/1.1" 200 36257 "-" "check_http/v (monitoring-plugins 2.4.0)" 192.168.11.9 - - [03/Apr/2025:19:35:18 +0800] "GET /modules/tadnews/pda.php?op=news&nsn=13&ncsn=5 HTTP/1.1" 200 2705 "-" "Mozilla/5.0 (compatible; AhrefsBot/7.0; +http://ahrefs.com/robot/)" 192.168.11.7 - - [03/Apr/2025:19:35:24 +0800] "GET / HTTP/1.1" 200 36257 "-" "check_http/v (monitoring-plugins 2.4.0)" 192.168.11.4 - - [03/Apr/2025:19:40:25 +0800] "GET / HTTP/1.1" 200 36257 "-" "check_http/v (monitoring-plugins 2.4.0)" 192.168.11.9 - - [03/Apr/2025:19:43:57 +0800] "GET / HTTP/1.1" 200 36259 "-" "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Mobile Safari/537.36" 192.168.11.4 - - [03/Apr/2025:19:43:58 +0800] "GET / HTTP/1.1" 200 36259 "-" "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Mobile Safari/537.36" 192.168.11.9 - - [03/Apr/2025:19:44:01 +0800] "GET / HTTP/1.1" 200 36259 "-" "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Mobile Safari/537.36" 192.168.11.4 - - [03/Apr/2025:19:44:16 +0800] "GET / HTTP/1.1" 200 36259 "-" "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Mobile Safari/537.36" 192.168.11.4 - - [03/Apr/2025:19:44:19 +0800] "GET / HTTP/1.1" 200 36259 "-" "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Mobile Safari/537.36" 192.168.11.4 - - [03/Apr/2025:19:44:31 +0800] "GET /modules/tadnews/page.php?nsn=86 HTTP/1.1" 200 25365 "-" "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Mobile Safari/537.36" 192.168.11.7 - - [03/Apr/2025:19:44:32 +0800] "GET /modules/tadnews/css/module.css HTTP/1.1" 200 4967 "https://lin.ichiayi.com/modules/tadnews/page.php?nsn=86" "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Mobile Safari/537.36" 192.168.11.4 - - [03/Apr/2025:19:44:32 +0800] "GET /modules/tadtools/css/iconize.css HTTP/1.1" 200 6483 "https://lin.ichiayi.com/modules/tadnews/page.php?nsn=86" "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Mobile Safari/537.36" :