Skip to main content

ZSL

利用 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

  1. 新增 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

  1. 登入 Cloudflared,進入顯示的網址登入,此步驟 Cloudflare 會自動新增給 Tunnel 用的 API Token:

    cloudflared tunnel login
    
  2. 建立 Tunnel:

    cloudflared tunnel create <ubuntu-server>
    
  3. 列出 Tunnel UUID:

    cloudflared tunnel list
    
  4. 建立 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
    
  5. 設定 run as service 在背景中運行 Tunnel

    sudo cloudflared service install
    sudo systemctl start cloudflared
    sudo systemctl status cloudflared
    sudo systemctl restart cloudflared
    
  6. 註冊 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>
    
  7. 大功告成

    啟動 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 免費版提供很多安全選項

  1. Quick Start Guide勾一勾
  2. DNS > DNS Settings > DNSSEC
  3. SSL/TLS > Overview > encryption Full (strict)
  4. SSL/TLS > Edge Certificates
  5. Security: WAF templete: mTLS-enforced authentication
  6. Security: WAF Zone lockdown Country not equal Taiwan
  7. Security: Bots 但是聽說有問題
  8. Security: DDoS > Block, High
  9. Security: Security Level, Browser Integrity Check
  10. Speed: Optimization HTTP/2 to Origin off, HTTP/3 (with QUIC)
  11. Network: WebSockets off, gRPC off, Onion Routing off
  12. Zero Trust > Settings > Network > Proxy

Notes

  1. 網路上使用 dashboard 的方法我都無法成功所以才用 CLI 方式建立。

  2. 網路上很多 " 都變成 ,複製貼上時請小心。

  3. A record=ipv4, AAAA record=ipv6。

  4. 查詢後發現使用no-ip無法轉移nameserver到Cloudflare上。

  5. 可使用以下指令管理Cloudflared

    sudo systemctl status cloudflared
    sudo systemctl start cloudflared
    sudo systemctl restart cloudflared
    sudo systemctl enable cloudflared
    
  6. 移除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 cloudflared
    
  7. Useful commands

    cloudflared tunnel delete <Tunnel-UUID or NAME>