利用 Cloudflare Tunnel 和 DDNS 無需開放端口實現安全外網訪問
Published:Updated:
需要把 docker 服務讓外網存取,需要設定輕鬆、不花錢、連線安全,取交集就是使用 Cloudflare Tunnel 功能,其他都需要繁複設定或者花錢甚至又花錢設定又麻煩。使用 Cloudflare Tunnel 的優點還有一個是可以穿透社區網路。
本文和 ivonblog 的 Cloudflare Tunnel教學,從外網安全地存取內網的Linux伺服器一樣使用 Locally-managed tunnels,功能和 Cloudflare Dashboard,也就是在 Web 介面設定的完全一樣,只是改用命令行設定,當時這樣做的原因是 dashboard 設定方式無法連線,但是後來官方修復問題後就可以正常運行了,因此現在一般建議使用 dashboard 設定,尤其是需要查找教學文章的新手用戶。
使用 dashboard 設定的教學網路上非常多,筆者隨意搜尋了一下可以參考 無痛本地調試:使用 Cloudflare Tunnel 實現 HTTPS 和自定義主機名 是正確的設定方式,只是要把 cloudflared 安裝從 brew 安裝換成 apt 即可在 ubuntu 運行。
優點
- 不用租 VPS 伺服器,最便宜域名 5 usd per year。
- Cloudflared 的 reverse proxy 幫你擋DDoS,傳輸加密,隱藏主機 IP,免開本機 port。
- 如果域名在 Cloudflared 買還可以自動配好憑證,也不用每三個月自動更新。
- 可以穿透社區網路。
- 每個 port 的服務使用個別配置的子域名進入。
- 使用 tailscale 作內網穿透可存取包含 http / SMB / docker 等服務。
教學步驟
設定 Cloudflare Tunnel
需要更改的偏好設定如下,請更改為自己的環境:
TUNNEL_NAME=ubuntu-server
DomainName=zsl0621.cc
ServerLocalIP=192.168.50.100
PortPhotoprism=2342
PortImmich=2283
依照官方教學輸入指令,注意到第四步我們會先跑去設定 run as service 。以 Linux 為例:
安裝 Cloudflared
新增 GPG key、新增 Cloudflare apt repo、更新並安裝
sudo mkdir -p --mode=0755 /usr/share/keyrings curl -fsSL https://pkg.cloudflare.com/cloudflare-main.gpg | sudo tee /usr/share/keyrings/cloudflare-main.gpg >/dev/null echo "deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/cloudflared $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/cloudflared.list sudo apt-get update && sudo apt-get install cloudflared
設定 Tunnel
登入 Cloudflared,進入顯示的網址登入,此步驟 Cloudflare 會自動新增給 Tunnel 用的 API Token:
cloudflared tunnel login建立 Tunnel:
cloudflared tunnel create <ubuntu-server>列出 Tunnel UUID:
cloudflared tunnel list建立 config 檔案
在/home/leo中使用nano建立一個config.yml檔案,使用多 port 格式,可指定不同的 port 對應不同子域名:tunnel: <Tunnel-UUID> credentials-file: /home/leo/.cloudflared/<Tunnel-UUID>.json ingress: - hostname: <immich.zsl0621.cc> service: http://<localhost:2283> - hostname: <photoprism.zsl0621.cc> service: http://<localhost:2342> - service: http_status:404/etc/cloudflared中也要一份一模一樣的檔案,可使用cp指令直接複製一份到目標資料夾:sudo cp ~/.cloudflared/config.yml /etc/cloudflared/config.yml設定 run as service 在背景中運行 Tunnel
sudo cloudflared service install sudo systemctl start cloudflared sudo systemctl status cloudflared sudo systemctl restart cloudflared註冊 route dns
有幾個子域名就要註冊幾個 route dns。route dns只能到官網刪除,本地無法刪除
# <Tunnel-Name> / <hostname> cloudflared tunnel route dns <ubuntu-server> <immich.zsl0621.cc> cloudflared tunnel route dns <ubuntu-server> <photoprism.zsl0621.cc>大功告成
啟動 Tunnel
# cloudflared tunnel run <ubuntu-server> sudo systemctl restart cloudflared
在我設定的 2024/2025 年,這些一設定幾乎一分鐘後就可馬上啟用,所以如果連不上一定是設定出錯而不是 DNS 等還沒上線的問題。
設定 Zero Trust Access
Zero Trust Access 功能是 Cloudflare 會幫你擋下或是允許特定流量,一般我只使用 email 功能,加上 Cloudflare OIDC 就可以使用 Gmail 帳號直接登入不需密碼,實際設定方式可以參考 immich 教學 還有 Cloudflare 官方教學,只需要詳讀這兩份就可以成功設定不需要閱讀其他文章。
額外的選項
Cloudflare 免費版提供很多安全選項
- Quick Start Guide勾一勾
- DNS > DNS Settings > DNSSEC
- SSL/TLS > Overview > encryption Full (strict)
- SSL/TLS > Edge Certificates
- Security: WAF templete: mTLS-enforced authentication
- Security: WAF Zone lockdown Country not equal Taiwan
- Security: Bots 但是聽說有問題
- Security: DDoS > Block, High
- Security: Security Level, Browser Integrity Check
- Speed: Optimization HTTP/2 to Origin off, HTTP/3 (with QUIC)
- Network: WebSockets off, gRPC off, Onion Routing off
- Zero Trust > Settings > Network > Proxy
Notes
網路上使用 dashboard 的方法我都無法成功所以才用 CLI 方式建立。
網路上很多
"都變成“,複製貼上時請小心。A record=ipv4, AAAA record=ipv6。
查詢後發現使用no-ip無法轉移nameserver到Cloudflare上。
可使用以下指令管理Cloudflared
sudo systemctl status cloudflared sudo systemctl start cloudflared sudo systemctl restart cloudflared sudo systemctl enable cloudflared移除Cloudflared
# 依序移除service, auto start, config, cloudflared sudo cloudflared service uninstall sudo rm /etc/systemd/system/cloudflared.service sudo rm /etc/cloudflared/config.yml sudo rm -r ~/.cloudflared sudo apt-get remove cloudflaredUseful commands
cloudflared tunnel delete <Tunnel-UUID or NAME>