使用Cloudflare Tunnel進行內網穿透

A. 什麼是內網穿透

內網穿透是一種技術,讓外部網路可以存取位於內部網絡(通常是公司、家庭路由器後)的服務和設備。通常,內部網絡的設備是隱藏在防火牆或路由器後的 NAT(網絡地址轉換)下,這意味着外部的請求不能直達內網中的設備。

內網穿透技術通過多種方式實現,常見的方法包括:服務器中轉、P2P 連接和反向代理等。其中,Cloudflare Tunnel 提供的服務則使用了一種安全的反向代理技術,讓內網服務經由外部服務器或網絡平台(如 Cloudflare)來轉發請求。

這樣一來,使用者無需手動配置複雜的路由器設置或暴露公共 IP 地址,就可以讓內網中的服務能夠被外部訪問。這在提供遠程訪問支持、搭建家庭服務器、公開開發環境等場景下特別有用。

B. 什麼是Cloudflare Tunnel

Cloudflare Tunnel 是一項由 Cloudflare 提供的服務,旨在為用戶提供安全的方式來從外部網絡訪問內部網絡服務,無需公開暴露公共 IP 地址。這項技術的核心是通過在用戶的服務器或電腦上運行一個名為cloudflared的輕量化應用應用程式,與 Cloudflare 的全球網絡建立一個outbound-only的連接。

這種方法允許 HTTP 網頁服務器、SSH 服務器、遠程桌面以及其他協議安全地連接到 Cloudflare。借助 Cloudflare Tunnel,內部服務可以經由 Cloudflare 提供的保護來處理流量,而不必擔心被那些試圖繞過 Cloudflare 的攻擊所侵害。

詳細說明可參考Cloudflare官方文件

Cloudflare運作流程 | https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/

C. 基礎設定

首先,我們需要申請一個Cloudflare帳號,並啟用Cloudflare Zero Trust,測試的過程使用免費方案就可以了;另外,還需要有一個透過Cloudflare代管的網域。

完成前面兩個步驟後,進入Cloudflare Zero Trust,並選擇Networks > Tunnels > Create a tunnel > Selected Cloudflared。

Tunnel的名字以我們方便記憶即可,接著你可以看到以下畫面:

安裝Cloudflared並執行連接器 | Alfred's CyberLoom

介紹Cloudflare Tunnel時,有提到我們要在我們的伺服器上安裝Cloudflared,這個步驟就是在安裝Cloudflared,根據你的伺服器或電腦的作業環境安裝方式有些許不同,依照網頁的指示安裝。

安裝成功後檢查一下安裝說明頁面下方的Connectors是否出現資料,有就代表成功了。

Cloudflared及連接器設定成功

下一步就是設定domain跟本地服務的對應,此時可以先離開這個頁面,當本地服務(如:Web伺服器)建立好後,再從Networks > Tunnels中,修改對應設定。

D. 應用範例

1. Web伺服器

剛剛設定好了Cloudflared,接著讓我們在伺服器上啟動一個簡易的Wordpress伺服器,並讓這個Wordpress能夠透過公網訪問。

首先在伺服器上建立一個專案資料夾,並建立一個docker-compose.yml,並貼上以下內容:

services:
  mariadb:
    image: docker.io/bitnami/mariadb:11.4
    volumes:
      - ./mariadb_data:/bitnami/mariadb
    environment:
      # ALLOW_EMPTY_PASSWORD is recommended only for development.
      - ALLOW_EMPTY_PASSWORD=yes
      - MARIADB_USER=bn_wordpress
      - MARIADB_DATABASE=bitnami_wordpress
  wordpress:
    image: docker.io/bitnami/wordpress:6
    ports:
      - '80:8080'
      - '443:8443'
    volumes:
      - ./wordpress_data:/bitnami/wordpress
    depends_on:
      - mariadb
    environment:
      # ALLOW_EMPTY_PASSWORD is recommended only for development.
      - ALLOW_EMPTY_PASSWORD=yes
      - WORDPRESS_DATABASE_HOST=mariadb
      - WORDPRESS_DATABASE_PORT_NUMBER=3306
      - WORDPRESS_DATABASE_USER=bn_wordpress
      - WORDPRESS_DATABASE_NAME=bitnami_wordpress

接著建立one_click.sh,記得透過

sudo chmod +x one_click.sh

讓這個檔案可被執行,同時第一行的USER也不要忘記修改成你自己:

USER="username"
GROUP="1001"

DIR="./mariadb_data"
if [ ! -d "$DIR" ]; then
    echo "Directory $DIR does not exist. Creating..."
    mkdir -p "$DIR"
fi
echo "Changing owner of $DIR to UID $GROUP..."
sudo chown -R "$GROUP":"$GROUP" "$DIR"
echo "Setting permissions for $DIR..."
sudo chmod -R 775 "$DIR"
echo "Adding user $USER to group $GROUP..."
sudo usermod -aG "$GROUP" "$USER"

DIR="./wordpress_data"
if [ ! -d "$DIR" ]; then
    echo "Directory $DIR does not exist. Creating..."
    mkdir -p "$DIR"
fi
echo "Changing owner of $DIR to UID $GROUP..."
sudo chown -R "$GROUP":"$GROUP" "$DIR"
echo "Setting permissions for $DIR..."
sudo chmod -R 775 "$DIR"
echo "Adding user $USER to group $GROUP..."
sudo usermod -aG "$GROUP" "$USER"

echo "docker-compose running ..."
docker-compose -f ./docker-compose.yml up --build -d
echo "All operations completed successfully."

詳細內容可以參考使用 Bitnami 的Docker Image快速部署 WordPress

回到Cloudflare Zero Trust,在Networks > Tunnels下選擇剛剛建立的Tunnel,並切換到Public Hostname,點選Add a public hostname,其中設定方式如下圖:

Cloudflare Tunnel設定Public Hostname存取

網域的部分選擇你在Cloudflare代管的網域,子網域看你想用哪個都可以。

儲存後在網址列輸入你設定的網域,就能看到你的網站了。

Cloudflare Tunnel成功連結本地Web伺服器

2. SSH

除了HTTP服務,Cloudflare也支援SSH,回到Cloudflare Zero Trust,在Networks > Tunnels下選擇剛剛建立的Tunnel,並切換到Public Hostname,點選Add a public hostname,其中設定方式如下圖:

透過Cloudflare Tunnel進行SSH訪問

儲存後就可以透過指令ssh username@domain訪問你的伺服器。請注意,設定完成後即可訪問,但此時不管是誰都能夠直接透過SSH存取你的主機,非常危險,此處設定完成後,請接著閱讀讓Cloudflare Access幫你管理網站存取

E. 總結

文章首先解釋了內網穿透的概念,接著在本地運行Cloudflared,就能建立與 Cloudflare 的全球網絡建立Tunnel安全連接,不必擔心公共 IP 的暴露問題。文章中也分享了實際使用範例,比如如何輕鬆地將 Web 伺服器公開給外部網絡,這讓內網穿透變得簡單。