使用 Cloudflare Tunnel 取代 Ngrok,免費的反向代理工具及存取控管

前言

反向代理是網頁開發環境上常見到的工具,在開發過程如果需要讓其他人存取區網內的伺服器,除了進一層又一層的 router 開防火牆權限讓外面連進來之外,最簡單的方法就是直接從 local 端建立一條連線到外部,讓其他人可以透過這條連線存取 local 端的資源。

常見的應用場合像是 Line Bot 或第三方金流 API,我們需要接收它們所發送的 Webhook,而且必須是 https

還有可以用來繞過 Secure Context,在做網頁開發時通常為了方便都會直接走 http protocol,在 http://localhost 存取不會有問題,但當要用區網內其它裝置連去測試時,就容易被 Secure Context 搞到,拿個 MediaDevices 都不行 😥。

使用反向代理還有一個好處,就是可以避免伺服器的 IP 洩漏,對方只會看到代理伺服器的 IP,且大多數反向代理都至少會幫你做一點點 🤏 的防護,比較不容易被打爛。

Cloudflare Tunnel

Cloudflare Tunnel 是 Cloudflare 提供的一個免費服務,可以讓你在 local 端建立一條連線到 Cloudflare 的伺服器,讓外部的人可以透過 Cloudflare 的伺服器存取 local 端的資源。

Cloudflare Tunnel Structure (圖片來源: Cloudflare Blog)

Ngrok 相比,Cloudflare 擁有自己的全球骨幹,連線品質相對穩定,而且免費方案的功能很完整,但需要擁有自己的 domain 才能把它用到極致。

實際使用

要用這酷酷的東西,首先要去 Cloudflare GitHub 下載 cloudflared,之後直接對它下指令就可以了。

在沒有登入的情況下,Cloudflare 會給你一個隨機的 <some-random-words>.trycloudflare.com 網域,以下以建立一個反向代理到 http://localhost:3000 為例:

bash
$ cloudflared tunnel --url http://localhost:3000
2024-03-01T00:00:00Z INF Thank you for trying Cloudflare Tunnel. Doing so, without a Cloudflare account, is a quick way to experiment and try it out. However, be aware that these account-less Tunnels have no uptime guarantee. If you intend to use Tunnels in production you should use a pre-created named tunnel by following: https://developers.cloudflare.com/cloudflare-one/connections/connect-apps
2024-03-01T00:00:00Z INF Requesting new quick Tunnel on trycloudflare.com...
2024-03-01T00:00:00Z INF +--------------------------------------------------------------------------------------------+
2024-03-01T00:00:00Z INF | Your quick Tunnel has been created! Visit it at (it may take some time to be reachable): |
2024-03-01T00:00:00Z INF | https://pad-supplier-bailey-representative.trycloudflare.com |
2024-03-01T00:00:00Z INF +--------------------------------------------------------------------------------------------+
...

大概2秒後就會看到 Your quick Tunnel has been created! ,然後就可以用下方的網址去存取你的網站了,非常快速。

自訂網域

以下步驟需要: 自己的網域、Cloudflare 帳號及大人的卡片(免費方案需填寫付款方式)

如果你有自己的網域,且 Name Server 為 Cloudflare,那就可以搭配 Cloudflare 的 Zero Trust 服務,將你的主機加入到 Zero Trust Network 中,這樣就可在控制台直接管理 Tunnel 及設定路由。

首先,登入 Cloudflare Dashboard 並點選 Zero Trust,照畫面指示開通免費方案。

Cloudflare dashboard

建立 Tunnel

點選 Networks => Tunnels => Create a tunnel 來建立新 Tunnel。

Create tunnels

Connector 選擇 Cloudflared,輸入 Tunnel name,最後複製下方 cloudflared 的指令,並用系統管理員執行。執行後會在主機上建立一個常駐 service,負責與 cloudflare 連線。

成功後會在 Connectors 看到你的主機,之後便可以直接透過網頁來管理這台主機上的路由。

每個 Tunnel 都可以同時設定多個路由,也就是多個 domain 可以指到 local 端不同的 port。舉例來說:

alpha.example.com => http://localhost:3000
beta.example.com => https://192.168.1.1:443
ssh.example.com => ssh://localhost:22

除了常見的 http、https 協定外,ssh、rdp、tcp 等都是可以使用,但需要在存取端安裝 cloudflared,詳細可參考 Cloudflare Docs。若連線到的是 ssh 或 vnc,下方存取控管章節有提到瀏覽器直接渲染的功能。

首先選擇要設定的 Tunnel,進入 Public Hostname => Add a public hostname 來設定 domain 及路由。

Setup public hostname

Additional application settings 內還有許多細節可以做設定,儲存後即可開啟網站測試連線。要設定多個 domain 就重複上述步驟繼續新增 Public hostname。

存取控管

Cloudflare Access 可用於管理網頁存取權限,透過指定使用者的 email address,並藉由 Google、Github 等常見的 OAuth 管道,或是內建的 One-Time Pin 來進行驗證。

Cloudflare Access Login Page

設定 Login methods

首先選擇 Settings => Authentication => Login methods => Add new ,點選要使用的驗證方式,並照各平台的指示設定。

Setup login methods

建立 Application

設定完成後,我們需要將要做存取控管的 domain 加入到 Access 中,選擇 Access => Applications => Add application ,我們的 Tunnel 屬於 Self-hosted application ,選擇這個選項後填入 Application name(會顯示於登入頁面上) 及 domain,其他設定保持預設即可,並進入下一步。

Setup access application

接下來我們需要設定 Access Policy,預設是 Allow(白名單) 模式,只有符合 Policy 的人可以存取,以下舉例只允許 user1@example.comuser2@example.com 存取,且存取國家必須是 Taiwan。

Setup access policy

除了上述所用的條件外,還可以透過 IP range、是否於 Github Organization 中,甚至呼叫外部 API(External Evaluation) 來進行驗證,詳細可參考 Cloudflare Docs

BTW,若要一次設定多個 email address,可在 My Team => Lists 建立 User Emails List,之後在 Policy 中選擇這個 List 即可。

設定完後,下一步還有 CORS、Cookie 的詳細設定,這邊就不贅述,但 Additional settings 中有一個很強大的功能叫 Browser rendering,若這個 tunnel 的目標服務是 ssh 或是 vnc,開啟此功能後就可以直接在瀏覽器渲染 SSH Terminal 或是 VNC 畫面。

Browser rendering

結語

在 Cloudflare Tunnel 推出前,原本自已的伺服器是走種花固定 IP 出去,並掛一層 Cloudflare proxy 來架 web server,但這樣畢竟還是有個公開 IP 在網路上晃,難免還是會被機器人掃到,很怕哪天被打爛。現在直接在機器上跑一個 cloudflared,全部連線都走 tunnel 出去,連固定 IP 都不需要,超級快樂。

Cloudflare Tunnel 跟 Access 只是其中的一部分,還有許多騷操作可以玩,像是拿它來擋廣告、在多裝置建立虛擬私有網路等,後續會在寫幾篇文章來分享。