藍圖風格插畫:沒有門的房子裡有一台主機,往上拉出通道連到加了門鎖的雲

不開 port 也能從外面連回家:用 Cloudflare Tunnel 架 n8n

用 Docker 在家裡的主機架 n8n,再用 Cloudflare Tunnel 和 Access 讓它從外面連得到:家裡不用開任何 port,只有自己的 Gmail 收得到登入驗證碼。加碼在公司也能用瀏覽器 SSH 連回家。

上一篇〈舊電腦變伺服器:Ubuntu Server 安裝、網路規劃與基本資安〉把舊電腦裝好了,這篇用 Cloudflare Tunnel 架 n8n。

目標是讓 n8n 跑起來,並且讓我在外面也能用自己的網址打開它,家裡的路由器不開任何 port。

用到的是 Cloudflare 的兩個免費功能:Tunnel 和 Access。版本以 2026 年 10 月為準(n8n 2.42.7、cloudflared 2026.10.0)。

Cloudflare 的介面常改版,選單名稱以你看到的畫面為準。文中的網域用 example.com 代替。

Cloudflare Tunnel 是怎麼運作的

一般要從外面連回家裡的主機,得在路由器「開 port」,等於在家門口開一扇門,全世界都能來敲。

Cloudflare Tunnel 反過來做:主機自己主動往外連到 Cloudflare,拉一條通道。外面的人只能從 Cloudflare 那頭進來,找不到家裡的真實 IP。

Access 則是在 Cloudflare 那頭加一道門禁:打開網址時要先輸入 Email,收驗證碼登入,只有我指定的 Gmail 收得到。

Cloudflare Tunnel 架構圖:手機和公司電腦連到加了門鎖的 Cloudflare,沒有門的房子裡,主機主動往外拉一條通道連到 Cloudflare
左邊的手機和公司電腦只能連到加了鎖的 Cloudflare(Access 門禁)。右邊的房子沒有門,代表家裡沒開 port;箭頭是主機自己往外拉的 Tunnel。

第一步:把網域的 DNS 搬到 Cloudflare

Tunnel 要用 n8n.example.com 這種子網域,網域的 DNS 必須交給 Cloudflare 管理。順便還能得到免費的 CDN 加速和 DDoS 防護。

  1. 註冊 Cloudflare、新增網域,它會自動匯入原本的 DNS 紀錄
  2. 到網域註冊商,把名稱伺服器改成 Cloudflare 給的兩組
  3. 生效後清理用不到的紀錄。我沒有用網域收信,所以刪掉 MX、autodiscover、autoconfig;不用 FTP,也一起刪掉
  4. SPF 要保留:WordPress 會寄忘記密碼、留言通知這類信,刪掉容易被當成垃圾信
  5. 新增 DMARC,防止別人冒用網域寄信:名稱 _dmarc、類型 TXT、內容 v=DMARC1; p=quarantine;
  6. SSL 模式設成「完整(嚴格)」,再用手機網路打開網站確認正常

我一開始設成「完整」,差一點點。「完整」不會檢查主機的憑證是不是有效,「完整(嚴格)」才會。

第二步:開通 Cloudflare Zero Trust

Tunnel 和 Access 都在 Zero Trust 裡。開通 Free 方案(50 人以內免費),取一個團隊名稱就好。

Cloudflare 帳號記得開兩步驟驗證,它是整套系統的大門之一。右側的「建議清單」有 8 項,不用全做,只需要 Tunnel 和 Access。

第三步:安裝 Docker

照 Docker 官方的 Ubuntu 安裝說明,用官方 apt 套件庫安裝 docker-ce 和 compose plugin。

裝好後把自己的帳號加進 docker 群組,登出再登入才會生效,再跑測試:

sudo usermod -aG docker $USER
# 登出再登入後
docker run --rm hello-world

加入 docker 群組等於拿到主機的最高權限,只加平常用的那一個帳號就好。

第四步:用 Docker 架 n8n

mkdir -p ~/n8n/data && cd ~/n8n
echo "N8N_ENCRYPTION_KEY=$(openssl rand -hex 32)" > .env
chmod 600 .env

這把加密金鑰要另外存進密碼管理器。n8n 裡所有的帳號密碼都用它加密,弄丟了,備份就還原不回來。

接著寫 compose.yaml,重點設定是這幾項:

  • ports: "127.0.0.1:5678:5678":只綁主機自己,連家裡區網都碰不到,只能經過 Tunnel 進來。Docker 一般的 port 寫法會繞過 Ubuntu 的防火牆,這樣寫才安全
  • N8N_HOST=n8n.example.com、WEBHOOK_URL=https://n8n.example.com/、N8N_PROXY_HOPS=1
  • 時區 Asia/Taipei
  • EXECUTIONS_DATA_PRUNE=true、EXECUTIONS_DATA_MAX_AGE=336:執行紀錄只留 14 天
  • 資料掛載到 ./data,方便備份
  • restart: unless-stopped:主機開機後自動啟動
docker compose up -d

先上鎖,再開門

n8n 第一次開啟時,誰先進來誰就是管理員。所以在對外公開之前,先用 SSH 通道從自己的電腦把帳號建好:

ssh -L 5678:localhost:5678 你的使用者名稱@192.168.1.250

連著不要關,瀏覽器打開 http://localhost:5678,就能建立管理員帳號。

註冊時可以選擇寄送免費的社群版授權金鑰,解鎖資料夾、除錯等功能。建好之後到 Settings → Personal 開啟兩步驟驗證(2FA)。

第五步:Cloudflare Access,只讓自己進門

在 Zero Trust 建兩個應用程式:

  1. n8n:類型選「自我裝載和私有」→ 公開 DNS → n8n.example.com。原則設「只允許我」:動作 Allow,包含「電子郵件=你的 Gmail」,登入方式用一次性 PIN
  2. n8n-webhook:同一個網域,路徑填 webhook/* 和 webhook-test/*,原則動作設 Bypass、包含「所有人」

第二個是因為 LINE、表單這些外部服務呼叫 n8n 時,沒辦法收驗證碼。Cloudflare 會優先套用路徑比較明確的規則,所以 Webhook 能通,其他頁面一樣要驗證。

也因為 Webhook 是公開的,自己取了好猜的路徑時,要在 Webhook 節點開啟 Header Auth。

Cloudflare Zero Trust 的應用程式清單:ssh、n8n-webhook、n8n 三個應用程式與各自的原則

第六步:建立 Cloudflare Tunnel,讓網址上線

  1. Zero Trust → 網路 → Tunnels → 建立 Cloudflared 通道 → 選 Debian 64-bit,複製安裝指令到主機執行
  2. 路由:已發布的應用程式 → n8n.example.com → HTTP localhost:5678
  3. 用手機網路(不要連家裡 Wi-Fi)打開網址:先過 Gmail 驗證碼,再過 n8n 的帳號密碼和 2FA
Cloudflare Tunnel 概覽頁,通道狀態正常、連接器已連線

我在這裡卡了一下:Cloudflare 一直顯示「未安裝連接器」。用這兩行檢查:

cloudflared --version
sudo systemctl status cloudflared

第一行有版本號,代表程式有裝;第二行出現 could not be found,代表系統服務沒有註冊。

原因是安裝指令最後一行 sudo cloudflared service install 沒執行到,補跑之後就連上了。這行指令後面接的 Token 等同密碼,不要貼到任何地方。

加碼:在外面也能 SSH 連回家

人在公司時,萬一主機有狀況也要能處理。Cloudflare 有「瀏覽器型 SSH」:任何電腦打開 ssh.example.com,通過 Gmail 驗證碼,就能在瀏覽器裡操作主機,電腦上不用放金鑰,也不用打密碼。

限制是:主機上的帳號名稱必須等於 Gmail @ 前面那段。對不上的話,另外建一個外出專用的帳號:

sudo useradd -m -s /bin/bash -G sudo 你的外出帳號
sudo passwd 你的外出帳號

這個帳號只加 sudo 群組,不要加 docker 群組。它登入只靠 Gmail,加了 docker 群組,Gmail 被盜就等於主機被拿走。

這是我做資安健檢時才發現的,細節寫在〈我不是資安本科,請 AI 幫家用伺服器做資安健檢,真的抓到漏洞〉。

  1. Access 新增 ssh 應用程式(公開 DNS → ssh.example.com),開啟「瀏覽器型 SSH」,套用「只允許我」原則
  2. Tunnel 路由:ssh.example.com → 服務類型 SSH、localhost:22。位置在「網路 → 連接器 → 選通道 → 已發布的應用程式路由」,我一開始點到「網路 → 路由 → CIDR」,那是私人網路用的
  3. Access → 服務認證 → SSH,為 ssh 應用程式產生短期憑證 CA,複製 CA 公鑰
  4. 讓主機信任這個 CA
echo '<CA 公鑰整行>' | sudo tee /etc/ssh/ca.pub
echo "TrustedUserCAKeys /etc/ssh/ca.pub" | sudo tee /etc/ssh/sshd_config.d/01-cloudflare-ca.conf
sudo sshd -t && sudo systemctl reload ssh
用瀏覽器型 SSH 登入家裡主機後的 Ubuntu 歡迎畫面

公司的 Mac 終端機也能連

不用 Homebrew,也不需要管理員權限:

mkdir -p ~/bin && cd ~/bin
curl -L -o cloudflared.tgz https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-darwin-arm64.tgz
tar -xzf cloudflared.tgz && rm cloudflared.tgz && chmod +x cloudflared
~/bin/cloudflared access ssh-config --hostname ssh.example.com --short-lived-cert
# 把印出的設定加進 ~/.ssh/config
ssh 你的外出帳號@ssh.example.com

最後一行我第一次打成只有網址,出現 command not found,前面要加 ssh 和帳號。

用公司電腦連回家之前,先確認公司允許;私鑰不要複製到公司電腦,也不要裝 VPN 類的軟體。

參考資料

這是舊電腦家用伺服器系列的第 3 篇。

上一篇:〈舊電腦變伺服器:Ubuntu Server 安裝、網路規劃與基本資安〉;

下一篇〈n8n 備份做兩份:本機硬碟+加密同步到 Google Drive〉已經上架,寫的是 n8n 每天自動備份到本機硬碟,再加密同步到 Google Drive。