你的 MacBook 上跑著 AI Agent,但家裡那台 iMac 閒置著 48GB 記憶體,風扇安安靜靜地吹著冷風。能不能讓它也加入工作?
這篇文章記錄我怎麼用 Cloudflare Tunnel 加上 Zero Trust Access,把一台 M1 iMac 變成 AI 系統的「分機」。它不只能 SSH 遠端操控,還能獨立接收 LINE Bot 的 Webhook 請求。整個過程免費,因為走的是 Tunnel,所以不需要固定 IP,也不用在路由器上另外開埠。
為什麼要多裝置?
單機跑 AI Agent 遲早會碰到天花板。我的情境是這樣的:
- 算力分散:MacBook 負責主要的 Claude Code 工作流,iMac 跑 Ollama 本地模型和 Hermes 閘道服務,兩邊各司其職
- 服務分離:LINE Bot 的 Webhook 需要一個穩定的公開端點。放在 iMac 上,就不會因為 MacBook 合蓋休眠而斷線
- 冗餘備援:萬一其中一台出狀況,另一台還能撐住基本服務
問題在於,這兩台機器都在家用網路的 NAT 後面。因為卡在 NAT 後面,所以從外面打不進來,從主機也沒辦法隨時連到分機。傳統做法是設定 port forwarding,但那需要固定 IP、要改路由器設定,而且每多開一個服務就要多開一個埠。
Cloudflare Tunnel 解決了這個問題。它從機器內部主動建立一條加密通道到 Cloudflare 的邊緣節點,外部流量因此透過 Cloudflare 的網路進來,完全不需要暴露任何埠。
架構全景
先看整體的樣子。這個架構有兩條通道,各走不同的 hostname:

SSH 通道(mac-node.example.com):
MacBook (主機, primary)
| ssh + cloudflared access proxy
v
Cloudflare Edge
| Zero Trust Access (身份驗證)
v
Cloudflare Tunnel
|
v
iMac :22 (SSH, 僅金鑰認證)
LINE Webhook 通道(line-hook.example.com):
LINE 平台
| POST /line/webhook
v
Cloudflare Edge
| Zero Trust Access (路徑分流)
v
Cloudflare Tunnel
|
v
iMac :8650 (Hermes Gateway, HMAC 驗簽)
兩條通道共用同一條 Tunnel,在 config 裡用不同的 hostname 對應不同的本機服務。所以 SSH 走 22 埠,LINE Webhook 走 8650 埠,各自分流。
Tunnel 建置五步驟
以下是在 iMac(分機端)的操作流程。先安裝 cloudflared 並登入,瀏覽器裡選你的 Cloudflare 帳號與你自己的網域(本文一律用 example.com 示意)。接著建立隧道(本文示意名 mac-node),把兩個 hostname 路由到這條隧道,再把設定寫進 config.yml,最後用 launchd 裝成開機常駐服務。憑證 JSON 會落在 ~/.cloudflared/,那是 Tunnel 的身份證明,請妥善保管。
流程骨架大致是:tunnel create → route dns(兩個 hostname)→ 寫 ingress → service install 並 load launchd。細節參數以官方文件為準,下面只留關鍵設定示意:
# ~/.cloudflared/config.yml(示意)
tunnel: <TUNNEL_ID>
credentials-file: /Users/youruser/.cloudflared/<TUNNEL_ID>.json
ingress:
- hostname: mac-node.example.com
service: ssh://localhost:22
- hostname: line-hook.example.com
service: http://localhost:8650
- service: http_status:404
ingress 最後那行 http_status:404 是必要的 catch-all:沒匹配到的請求都落到這裡。DNS 路由完成後,Cloudflare 會為兩個 hostname 建立指向這條 Tunnel 的 CNAME。服務裝好後,iMac 開機就會自動拉起 Tunnel。
別忘了把主機的 SSH 公鑰加到分機的 ~/.ssh/authorized_keys,並把目錄與檔案權限收緊到只有本機使用者可讀寫。
安全強化三件事
Tunnel 建好之後,你的機器就對全球可達了。這件事很重要,值得再強調一次:Cloudflare Tunnel 讓你的機器不再是 NAT 後面的隱形狀態。所以安全措施不是「建議」,是「必須」。

第一件:關掉 SSH 密碼認證
sudo tee /etc/ssh/sshd_config.d/hardening.conf << 'EOF'
PasswordAuthentication no
ChallengeResponseAuthentication no
KbdInteractiveAuthentication no
EOF
# 改完後重載 sshd(macOS 用 launchctl unload/load ssh.plist)
為什麼家裡的機器也要關?因為暴力破解機器人不管你在哪裡,只要有個公開的 SSH 端點,它們幾分鐘內就會開始嘗試。所以只留金鑰認證,密碼攻擊就直接失效。驗證時可刻意關掉公鑰、只開密碼試連一次,預期應得到 Permission denied (publickey)。
第二件:StrictHostKeyChecking 設為 yes
alias ssh-macnode='ssh \
-o ProxyCommand="cloudflared access ssh --hostname mac-node.example.com" \
-o StrictHostKeyChecking=yes \
-i ~/.ssh/id_ed25519 \
youruser@mac-node.example.com'
很多教學會叫你設 StrictHostKeyChecking=no 來「避免麻煩」,但這等於放棄了中間人攻擊(MITM)的防護。其實只要第一次連線時確認一下主機指紋,之後就不用再煩了。
第三件:Zero Trust Access 路徑分流
這是最有趣的部分。line-hook.example.com 同時要服務兩種角色:LINE 平台打 Webhook 進來,以及我自己偶爾要上去看狀態。因為這兩者的安全需求完全不同,所以要分開處理。

在 Cloudflare Zero Trust 後台建立 Access Application:
| 設定項目 | 值 |
|---|---|
| Hostname | line-hook.example.com |
| Policy 1 | Bypass / Everyone / path: /line/webhook |
| Policy 2 | Allow / 指定使用者(我自己) |
這樣一來,LINE 平台打 /line/webhook 時直接放行(靠 Hermes 閘道的 HMAC 驗簽做第二層驗證),其他路徑則需要 Cloudflare 身份驗證才能存取。
SSH 那邊(mac-node.example.com)也加入 Access Application,用同一組 Allow 政策。第一次連線時 cloudflared access ssh 會開瀏覽器要求登入,驗證 token 會快取一段時間,我這邊實測大約一週,實際長度取決於你 Access 政策裡的 session duration 設定。之後用 ssh-macnode alias 直接連,不用重複驗證。
雙層防護的效果:
攻擊者
-> Cloudflare Access(沒有 token,直接拒絕)
-> SSH 金鑰認證(沒有 ed25519 key,再次拒絕)
要突破必須同時拿到我的 Cloudflare 帳號和我的 SSH 私鑰。因為這兩個東西不在同一個地方,所以被同時攻破的機率極低。
踩坑記錄:Bypass 路徑設錯
建置過程中最令人困擾的一個坑:LINE Bot 的 Webhook 突然收不到訊息了。
症狀:LINE 平台送出的 Webhook 請求被 Cloudflare Access 攔截,回傳 302 導向登入頁面。LINE 平台不會去登入,於是 Webhook 全部失敗。
根因:我把 Bypass 的路徑設成了 /webhook/line,因為 Hermes 設定檔裡的 webhook_path 就是這樣寫的。但實際上 LINE 平台打過來的路徑是 /line/webhook。路徑反了。
解法:在 Zero Trust 後台把 Bypass 路徑改成 /line/webhook。
驗證:
# 應穿過 Access 到達 Hermes(無合法簽章時常見 401)
curl -s -X POST https://line-hook.example.com/line/webhook \
-H "Content-Type: application/json" -d '{"probe": true}'
看到 Webhook 路徑回 401 而不是 302,就代表請求成功穿過了 Cloudflare Access,到達了 Hermes 閘道。根路徑若被 Access 攔截,通常會導向登入(302),可與 Webhook 路徑對照判斷。問題解決。
這個坑的教訓是:設定 Bypass 路徑時,一定要以「外部實際打進來的路徑」為準,不是以內部程式設定的路徑為準,因為兩者可能不一樣。
主機端操作介面
一切就緒之後,在 MacBook 上操作 iMac 就跟操作本機差不多。互動 shell 用 ssh-macnode,單次指令可掛在後面執行;要看 Hermes 是否聽在 8650、或重載 Tunnel 的 launchd 服務,也一樣走這條 alias。日常在 iMac 本機可用 launchctl list 查 cloudflared 是否在跑,並用 log show 看最近幾分鐘的 tunnel 記錄。
ssh-macnode
ssh-macnode "whoami && uname -a"
# 查閘道、重載 Tunnel 服務:同樣透過 alias 遠端執行
未來展望:主從 Agent 對話架構
這條通道現在主要做三件事:遠端執行指令、管理服務、搬移檔案。但它真正的價值在於開啟了一個可能性。
如果 iMac 上也安裝 Claude Code,就能形成真正的主從 Agent 架構:
workspace (Claude Code, primary)
| SSH Tunnel
v
第二台 Mac (Claude Code, secondary)
|
+-- Ollama 本地模型推理
+-- Hermes LINE Bot 閘道
主機上的 Agent 可以透過 SSH 把特定的推理任務派給分機上的本地模型,或者請分機上的 Agent 處理需要長時間運算的工作。因為分機只做被交派的事情,不會主動寫入共享資源,所以能避免衝突。
這就像是辦公室裡的分機系統。總機接電話、分派任務,分機各自處理自己負責的業務。差別在於這些「分機」是 AI Agent,而「電話線」是一條穿越 Cloudflare 全球網路的加密通道。
安全模型小結
最後整理一下這個架構的安全分層,確保每一層都各司其職:
| 層級 | 防護對象 | 機制 |
|---|---|---|
| 第一層 | 網路存取 | Cloudflare Tunnel(不暴露任何埠) |
| 第二層 | 身份驗證 | Zero Trust Access(Cloudflare 帳號登入) |
| 第三層 | SSH 認證 | ed25519 金鑰(禁用密碼) |
| 第四層 | 應用層驗證 | Hermes HMAC 簽章驗證(LINE Webhook 專用) |
四層防護,每一層各自獨立。因為彼此獨立,所以即使其中一層被繞過,後面的層級仍然在守著。
免費方案就能做到這些。Cloudflare Tunnel 免費,Zero Trust 也有免費方案,席次對個人或小團隊來說完全夠用。確切的席次上限我不寫死在這裡,Cloudflare 這幾年調整過幾次,你要用之前去官方定價頁確認一下最準。
把閒置的硬體變成 AI 基礎設施的一部分,不需要花錢買新伺服器,也不需要搞複雜的 VPN。一條 Tunnel 對應兩個 hostname,再配上四層防護,多裝置 Agent 協作就是從這裡開始的。
常見問題
Cloudflare Tunnel 要錢嗎?
不用。Cloudflare Tunnel 本身完全免費,包含在所有 Cloudflare 方案中。搭配的 Zero Trust Access 免費方案支援最多 50 位使用者,對個人或小團隊來說綽綽有餘。你唯一需要的是一個自己的網域(用來設定 DNS CNAME),網域本身可以在任何註冊商購買,一年幾百塊台幣就有了。
分機可以用 Linux 或 Windows 嗎?
可以。cloudflared 支援 macOS、Linux、Windows 三個平台。安裝方式不同(Linux 用 apt/yum,Windows 用 MSI 安裝檔或 winget),但 config.yml 的寫法和 Tunnel 運作邏輯完全一樣。差別在於自動啟動的機制:macOS 用 launchd,Linux 用 systemd,Windows 用服務管理員。SSH 的部分,Linux 原生支援,Windows 則需要啟用 OpenSSH Server(Windows 10 以上內建)。
跟 Tailscale 或 WireGuard 比,哪個適合?
看你的需求。簡單比較: | 面向 | Cloudflare Tunnel | Tailscale | WireGuard | |------|-------------------|-----------|-----------| | 公開端點 | 有(可接外部 Webhook) | 無(僅內網互連) | 需自架中繼伺服器 | | 設定難度 | 中等 | 極低 | 較高 | | 安全模型 | Zero Trust + 應用層 | WireGuard + ACL | WireGuard | | 費用 | 免費 | 個人免費 / 商用付費 | 免費 | 如果你只需要兩台機器互相連線,Tailscale 最簡單。但如果你需要從外部接收流量(像 LINE Webhook 這種場景),Cloudflare Tunnel 是更合適的選擇,因為它能提供公開的 hostname 並搭配路徑分流的存取控制。
延遲會影響 AI 回應速度嗎?
SSH 走 Cloudflare Tunnel 的延遲大約在 10-30ms(取決於你跟最近的 Cloudflare 邊緣節點的距離)。對於下指令、管理服務這類操作來說幾乎感覺不到。LINE Bot 的 Webhook 也是走 HTTP,延遲同樣在毫秒等級。 真正影響 AI 回應速度的是模型推理本身的時間,通常是數百毫秒到數秒。相較之下,Tunnel 增加的網路延遲可以忽略不計。如果你要做的是大量檔案傳輸(例如用 scp 搬模型權重檔案),建議走區域網路直連會快很多。
如果 Tunnel 斷了,LINE Bot 會怎樣?
LINE 平台會在 Webhook 送出失敗時自動重試。根據 LINE 官方文件,重試機制會持續一段時間。所以如果 Tunnel 只是短暫中斷(例如 iMac 重開機),訊息不會遺失,只是會延遲送達。 如果 Tunnel 長時間斷線,LINE 平台最終會放棄重試,那些訊息就會丟失。解決方式有幾種: - 用 `launchd` 確保 cloudflared 在 iMac 開機時自動啟動 - 設定健康檢查腳本,定期確認 Tunnel 狀態 - 在主機端設定告警,Tunnel 斷線時發通知 實務上,cloudflared 本身有重連機制,大多數的短暫網路中斷它都能自動恢復。