﻿# 使用 Cloudflare Tunnel 的 TryCloudflare 取代 ngrok

最近在嘗試 [Cloudflare Tunnel](https://www.cloudflare.com/zh-tw/products/tunnel/) 服務，這是一套免費的服務，可以讓你在本機網路與 Cloudflare 網路之間建立一個隧道(Tunnel)，讓外部的網路可以透過 Cloudflare 的端點(Edge)連線到你的本機端服務。不過 Cloudflare Tunnel 在設定上稍微有點麻煩，步驟有點多，而且要事先建立好 Cloudflare 帳號。不過，我發現 Cloudflare 還有提供一個 `TryCloudflare` 或 `Quick Tunnels` 服務，也是免費的，但使用這個服務連 Cloudflare 帳號都不用建立，只要安裝 `cloudflared` 工具就可以直接開始使用，對於臨時想要從外網測試一個服務來說非常的方便，尤其是你想用手機測試電腦桌機網站的時候。

![cloudflared](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/e2113f400f6f1c17f2a6-16af76c2-c194-4d63-b4ad-24712dff1a80.webp)

使用 `TryCloudflare` 服務有以下優點：

-   完全免費
-   安裝簡便
-   內建 SSL/TLS 加密連線
-   免註冊帳號，安裝後即可使用

使用 `TryCloudflare` 服務有以下缺點：

-   每次連線都會產生一個新的網址，重新建立通道就會產生新的網址
-   連線最多只能維持 24 小時，如需更長時間請改用完整版的 Cloudflare Tunnel 設定

### 安裝 `cloudflared` 工具

-   Windows + [Windows Package Manager](https://github.com/microsoft/winget-cli) (`winget`)
    
    ```bash
    winget install --id Cloudflare.cloudflared
    ```
    
-   Windows + [Chocolatey](https://chocolatey.org/install)
    
    ```powershell
    choco install cloudflared -y
    ```
    
-   macOS + [Homebrew](https://brew.sh/zh-tw/)
    
    ```bash
    brew install cloudflared
    ```
    
-   Linux
    
    請直接到 [Downloads](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/downloads/) 頁面下載 Binary 可執行檔。
    
-   Docker
    
    請直接到 [cloudflare/cloudflared - Docker Image | Docker Hub](https://hub.docker.com/r/cloudflare/cloudflared) 查看使用說明。
    
    ```bash
    docker run cloudflare/cloudflared:latest tunnel --no-autoupdate --hello-world
    ```
    

### 更新 `cloudflared` 工具

你可以透過以下命令快速更新到最新版：

```bash
cloudflared update
```

### 使用 `cloudflared` 工具

這套 `cloudflared` 工具其實涵蓋了 [Cloudflare Tunnel](https://www.cloudflare.com/zh-tw/products/tunnel/) 的完整功能，參數與選項特別多，有興趣深入研究可參考[官網文件](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/)或現有的許多[部落格文章](https://editor.leonh.space/2021/cloudflare-tunnel/)。

以下是一些常用的範例：

1.  啟動一個 Cloudflare Tunnel 並使用內建的 `hello-world` 服務
    
    通常我們想建立 Tunnel 都是因為本機有個 Web 服務，需要立即讓外網連線到這個服務，但是如果你還沒有 Web 服務，又想測試 Cloudflare Tunnel 的功能怎麼辦？那就啟動內建的 Hello World 網站即可！
    
    ```bash
    cloudflared tunnel --hello-world
    ```
    
    ![cloudflared tunnel --hello-world](https://stwillblogassets.blob.core.windows.net/files/images/external/github.com/0544bff8346f20d963ec-3022ab4a-2fbe-4d70-a17d-cc9fdc3ada13.png)
    
    建立好 Quick Tunnel 之後，會在 Terminal 視窗中看到一個網址，透過那個網址就可以快速連到你本機的 Hello World 網站：
    
    ![Congrats! You created a tunnel!](https://stwillblogassets.blob.core.windows.net/files/images/external/github.com/b9486d3b5860b606023d-219a00fa-c90d-48a7-8e31-f9277f3f0816.png)
    
2.  透過 Cloudflare Tunnel 網路連接到本機的 `localhost:4200` 網站
    
    我以 Angular Live Development Server 為例，先啟動本機伺服器：
    
    ```bash
    ng serve
    ```
    
    然後啟動 Cloudflare Tunnel：
    
    ```bash
    cloudflared tunnel --url http://localhost:4200
    ```
    
    連到網頁後，你會立刻發現網頁上會顯示 `Invalid Host header` 字樣，網站完全無法連線。這是因為 Angular Live Development Server 預設只允許 `localhost` 這個 Hostname 連線，但是 Cloudflare Tunnel 會使用一個隨機的 Hostname 來連線，所以連線會被拒絕。
    
    解決方法有兩種：
    
    -   調整 `ng serve` 的啟動參數，特別加上 `--disable-host-check` 參數
        
        這個參數可以避免 Angular Live Development Server 檢查 HTTP 要求的 `Host` 標頭，這樣就可以讓任何 Hostname 連線到本機網站。
        
        ```bash
        ng serve --disable-host-check
        ```
        
    -   調整 `cloudflared tunnel` 的啟動參數，特別加上 `--http-host-header="localhost"` 參數
        
        這個參數可以指定從 Cloudflare 的 Edge 連線到本機網站時要使用的 Hostname 名稱，這樣就可以讓本機網站正常運作。
        
        ```bash
        cloudflared tunnel --url "http://localhost:4200" --http-host-header="localhost"
        ```
        
3.  透過 Cloudflare Tunnel 網路連接到本機再跳轉到外部網站
    
    這種用法如同建立一個快速的 VPN 通道，讓外部網路可以先透過 Cloudflare Tunnel 連線到本機，然後再透過本機的網路連線到外部網站，使用你目前的網路連到目的網站。有許多網站可能有鎖定 IP 才能存取，如果臨時想要存取這些網站，就可以透過這種方式來達成，不用撥接 VPN 就可以做到。
    
    ```bash
    cloudflared tunnel --url "ifconfig.co" --http-host-header="ifconfig.co"
    ```
    

### 快速啟動命令

由於 `ngrok` 在啟動網站時非常方便，一般來說啟動的命令如下：

```bash
ngrok http 4200
```

我也如法炮製，寫了一個 `C:\Windows\cok.cmd` 批次檔，其內容如下：

```batch
@ECHO OFF
cloudflared tunnel --config NUL --url "%1://localhost:%2" --http-host-header="localhost" --loglevel debug
```

> 注意: 這個 `--config NUL` 參數是為了避免 `cloudflared` 工具去尋找預設的 `config.yml` 設定檔案。因為當你設定了 Cloudflare Tunnel 後，`cloudflared` 工具會自動去讀取 `config.yml` 檔案，這樣會影響到 `TryCloudflare` 的使用。

今後你只要這樣下指令，就可以快速啟動 Cloudflare Tunnel 並測試本機的 `http://localhost:4200` 網站了：

```bash
cok http 4200
```

### 相關連結

-   Cloudflare Zero Trust docs
    -   [Cloudflare Tunnel](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/)
    -   [Quick Tunnels](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/do-more-with-tunnels/trycloudflare/)
    -   [Downloads](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/downloads/)
-   Cloudflare Blog
    -   [Argo Tunnels that live forever](https://blog.cloudflare.com/argo-tunnels-that-live-forever/)
-   Cloudflare Tunnel 教學文章
    -   [Cloudflare Tunnel 簡介 | 六小編 Editor Leon](https://editor.leonh.space/2021/cloudflare-tunnel/)
    -   [使用 Cloudflare Tunnel 作為低成本的 ngrok 替代品：可自訂 domain 的 reverse tunneling 解決方案，讓外網連上本地 server | Medium](https://medium.com/@zetavg/%E4%BD%BF%E7%94%A8-cloudflare-tunnel-%E4%BD%9C%E7%82%BA%E4%BD%8E%E6%88%90%E6%9C%AC%E7%9A%84-ngrok-%E6%9B%BF%E4%BB%A3%E5%93%81-6b0aaef97557)
