整體架構
要解決的問題:家用浮動 IP 經常變動,而中國各地的 DNS 快取更新太慢。因此朋友端常常連不上。解決方法是讓朋友端不再依賴「網域解析」,改用訂閱機制。App 定時自動抓取目前最新的 IP。整個過程不需要人工通知,也不受 DNS 傳播速度影響。
核心是一個 Cloudflare Worker。Worker 依網址路徑判斷是哪個朋友或哪組裝置,再去 KV 讀取目前的 IP。Worker 再依 ?v= 參數決定輸出格式(v2ray、Clash、裸 xray-core config 或一鍵安裝腳本),並即時產生對應的內容回傳。KV 只儲存一個共用值(目前 IP)。所有朋友共用同一個值。每個朋友不同的資料(UUID、shortId、路徑、名稱)直接寫在 Worker 程式碼裡,並由人工維護。
flowchart TD
A["DDNS PowerShell 腳本"] -->|更新 A 記錄| B["Cloudflare DNS"]
A -->|寫入 current_ip| C["Cloudflare KV"]
C --> D["Cloudflare Worker"]
D -->|"依路徑判斷 client"| E["讀取 KV 目前 IP"]
E -->|"?v=v2ray(預設)"| F["base64 vless 連結"]
E -->|"?v=clash"| G["完整 Clash config.yaml"]
E -->|"?v=xrayclient"| H["裸 xray-core config.json"]
E -->|"?v=install"| I["PowerShell 一鍵安裝腳本"]
F --> J["Shadowrocket / v2rayN 訂閱"]
G --> K["Clash / Mihomo 訂閱"]
H --> L["irm 下載後手動跑 xray-core"]
I --> M["irm ... | iex 一鍵安裝/更新"]
另外還有一組獨立的 IP_TOKENS 路徑空間,和節點使用的 CLIENTS 完全分開。這組路徑只回傳目前 IP 的純文字,不含任何節點資訊。用途是只需要知道「目前 IP 是多少」的情況。
延伸閱讀:Cloudflare 的 KV 和 Worker 在 AWS、GCP 和 Azure 的對應服務,見雲端服務對照表。
目前的伺服器環境
伺服器端的 Windows 電腦執行 xray + config.json。設定中實際有 4 個 inbound:
| Inbound | 監聽 | 用途 |
|---|---|---|
| ① VLESS Reality Vision(對外) | 區網 IP:443 | 供所有外部朋友直連。主要入口 |
| ② VLESS Reality(本機 Loopback) | 127.0.0.1:12345 | 用於客戶端設定中的 Loopback 測試。不對外開放 |
| ③ VLESS + WebSocket | 127.0.0.1:8080 | 經過 Cloudflare CDN 中轉的備援線路 |
| ④ SOCKS(供 WARP 使用) | 127.0.0.1:50000 | 流量經由 wgcf-warp outbound 出去的入口 |
路由規則依 client 的 email 欄位分流。指定給 warp 分組的 user,全部流量經由 Cloudflare WARP 出去。指定給 direct 分組的 user,直接從家裡出去。其他沒有指定的 client,使用 fallback 規則:TCP 經由 warp,UDP 經由 wgcf-warp。email 只是內部路由比對用的識別字。識別字的值和朋友實際看到的訂閱節點名稱不同。兩者可以不一樣。建議保持對應關係,比較容易維護。
config.json(含 4 個 inbound、routing 規則、wireguard/warp outbound 設定)很長。點下方可以展開,查看佔位結構。實際部署時,對照原始檔案,整段貼回即可。本文不會改變設定的結構。
點擊展開/收起:伺服器端完整 config.json(佔位,稍後貼回)
// ===== 伺服器端完整 config.json(佔位,稍後貼回)=====
// {
// "log": { "loglevel": "warning" },
// "inbounds": [
// // ① VLESS Reality Vision,監聽區網 IP:443,clients 陣列含所有朋友的 uuid/email/flow
// // ② VLESS Reality,監聽 127.0.0.1:12345,僅供本機 Loopback 測試
// // ③ VLESS + WebSocket,監聽 127.0.0.1:8080,path 隨機字串,經過 CF CDN 中轉
// // ④ SOCKS,監聽 127.0.0.1:50000,tag: wgcf-socks-in,供 wgcf-warp outbound 使用
// ],
// "dns": { "servers": [ /* 1.1.1.1 / 1.0.0.1 / 8.8.8.8 / 8.8.4.4 DoH */ ] },
// "routing": {
// "domainStrategy": "IPIfNonMatch",
// "rules": [ /* 依 user(email)分流 warp / direct,詳見本節文字說明 */ ]
// },
// "outbounds": [
// // wireguard(tag: wgcf-warp,Cloudflare WARP 端點)
// // socks(tag: warp,轉給本機 wgcf 代理)
// // freedom(tag: direct,sendThrough 綁定區網 IP)
// // blackhole(tag: block)
// ]
// }
//
// 完整內容見「Cloudflare KV Worker 訂閱自動更新 建置指南 v2.md」,之後直接整段貼回這裡。
建置步驟
1. 建立 Cloudflare KV Namespace(只需做一次)
- 在 Dashboard 的「Workers 和 Pages」→「KV」,建立 namespace(例如
vpn-sub) - 記錄 Namespace ID 和 Account ID
- API Token 必須有
Workers KV Storage:Edit權限。可以在 DDNS 腳本現有的 Token 上加入同一個權限。
這一步完成後,KV 就設定好了。之後,腳本只會透過 API 自動更新 KV 的值。不需要再手動修改 KV。
2. 部署 Worker(四種輸出格式)
路徑格式一覽:
| 路徑寫法 | 功能 | 使用對象 |
|---|---|---|
/{token} 或 ?v=v2ray | base64 編碼的 vless 連結(多個節點用多行) | Shadowrocket / v2rayN |
?v=clash | 完整 Mihomo / Clash config.yaml | Clash 系列 App |
?v=xrayclient | 裸 xray-core config.json(?i= 可以指定多節點群組中的第幾個) | 桌機直接執行 xray-core |
?v=install | PowerShell 一鍵安裝/更新腳本 | irm ... | iex 直接執行 |
/{ip_token}(獨立於 CLIENTS) | 純文字,只回傳目前 IP | 其他只需要知道目前 IP 的用途 |
CLIENTS 物件支援兩種寫法。單一 client 直接寫
{ uuid, sid, name }。多節點群組(例如同一人需要 direct 和 warp 兩個節點,放在同一份訂閱裡)寫成 { clients: [ {...}, {...} ] }。Worker 內部統一用
client.clients || [client] 轉成陣列處理。
點擊展開/收起:Cloudflare Worker 完整程式碼(佔位,稍後貼回)
// ===== Cloudflare Worker 完整程式碼(佔位,稍後貼回)=====
// 內容包含:
// - const IP_TOKENS = { "隨機字串": { name } }
// - const CLIENTS = { "隨機路徑": { uuid, sid, name } | { clients: [...] } }
// - const SNI / PBK 共用參數
// - export default { async fetch(request, env) { ... } }
// 依 path 比對 IP_TOKENS → 純文字回傳 IP
// 依 ?v= 參數分流到 buildXrayConfig() / buildInstallScript() / buildClashConfig()
// 預設輸出 base64 編碼的 vless 連結
// - function buildXrayConfig(client, ip) { ... } 裸 xray-core config.json
// - function buildInstallScript(token, origin) { ... } 一鍵安裝 PowerShell 腳本
// - function buildClashConfig(clients, ip) { ... } 完整 Clash config.yaml
// - const RULES_BODY = `...` 628 條分流規則本體(從 Shadowrocket 遷移)
//
// 完整版本見「Cloudflare KV Worker 訂閱自動更新 建置指南 v2.md」,之後直接整段貼回這裡。
部署後,到 Worker 的「設定 → 繫結」,新增 KV 命名空間繫結。變數名稱設為 VPN_SUB。
[guid]::NewGuid().ToString("N") 獨立產生路徑。路徑和 UUID 完全無關。
3. 更新 DDNS PowerShell 腳本
在原本「更新 Cloudflare A 記錄成功」的程式碼後面,加入 Update-SubscriptionKV 函式。函式把目前 IP PUT 到 KV 的 current_ip key。
點擊展開/收起:DDNS 腳本新增段落(佔位,稍後貼回)
// ===== DDNS 腳本新增段落(佔位,稍後貼回)=====
// function Update-SubscriptionKV { param($NewIP, $AccountId, $NamespaceId, $ApiToken) ... }
// 呼叫 Cloudflare API: PUT /accounts/{id}/storage/kv/namespaces/{id}/values/current_ip
// 完整程式碼見建置指南 v2.md 第三節。
4. 一鍵安裝腳本的使用方式
Windows 桌機直接執行 xray-core(不透過 App)時,可以在資料夾中(已放好 xray.exe)執行:
irm https://auto-update.doggycxj.com/{token}?v=install | iex
腳本會自動執行下列動作:檢查 xray.exe 是否存在 → 從 ?v=xrayclient 端點下載最新設定,寫入
config.json → 找到同資料夾中舊的 xray 行程並關閉 → 用新設定重新啟動,並顯示 SOCKS5 監聽位址(127.0.0.1:10808)。任何一步失敗時,腳本會顯示明確的錯誤訊息並暫停視窗。
5. 驗證
- v2ray 格式:解碼 base64 後,應該得到正確的
vless://...連結。連結中的 IP 是最新的 - clash 格式:檢查
proxies區塊的server是否為最新 IP - xrayclient 格式:JSON 語法正確
- install 格式:顯示 PowerShell 腳本的原始文字(瀏覽器不會執行腳本)
- IP_TOKENS:直接顯示純文字 IP,不含其他資訊
- App 端設定「訂閱自動更新」。建議間隔為 15~30 分鐘
日常維運 SOP
新增一個朋友(單一節點)
config.json的clients加入一組新 UUID,再存檔並重啟 Xray- Worker 的
CLIENTS加入一行{ uuid, sid, name },再重新部署 - 把訂閱網址(不是 QR code)私下傳給新朋友
新增一組多節點群組(例如 direct + warp)
config.json加入兩組 UUID,對應不同的email。兩組使用不同的路由分流,再重啟 Xray- Worker 的
CLIENTS加入群組格式{ clients: [ {...}, {...} ] },再重新部署 - 訂閱後 App 端會看到兩個可選節點
停用一個朋友
順序相反。先移除 Worker 的 CLIENTS(訂閱立刻失效),再重新部署。然後刪除 config.json 裡的 UUID,並重啟 Xray(徹底收回連線權限)。
IP 變動
不需要手動處理。DDNS 腳本自動處理,KV 自動更新。四種格式都即時讀取同一個 KV 值。
調整 Clash 分流規則
規則寫在獨立的 RULES_BODY 常數裡。修改後,存檔並重新部署即可。這不影響其他三種格式。
安全性重點提醒
- 訂閱網址等同完整的連線憑據。解碼後包含完整 UUID。必須透過私下的一對一管道傳遞。不可以公開貼出。
?v=xrayclient/?v=install格式也包含完整 UUID 和目前 IP。敏感等級相同。- IP_TOKENS 路徑不含 UUID,但會洩漏真實 IP。IP_TOKENS 路徑也必須使用隨機路徑。
- 路徑建議至少 32 字元(
[guid]::NewGuid().ToString("N"))。每個朋友使用獨立的一組路徑。 - 懷疑外流時:先移除 Worker 中對應的那一行,讓訂閱立即失效。再刪除
config.json的 UUID,並重啟 Xray
是否保留 DDNS 網域
要,繼續保留。訂閱機制上線後,朋友端不再依賴網域。但是,建議 DDNS 腳本照常運作。原因有兩個。第一,如果自己的裝置仍然用網域連線,就需要 DDNS。第二,DDNS 可以當備援。Worker 或 KV 出問題時,DDNS 網域至少是一個人工可以查詢、可以排除問題的管道。兩條線並行,互不影響。成本幾乎是零。
待辦清單
- 建立 KV namespace,記錄 Namespace ID 和 Account ID
- Token 加上
Workers KV Storage:Edit權限 - 部署 Worker(四種格式版),先放一個朋友測試
- Worker 綁定 KV(變數名
VPN_SUB) - 手動寫入一筆
current_ip測試值到 KV,驗證四種格式都能正確輸出 - 修改 DDNS PowerShell 腳本,加入
Update-SubscriptionKV呼叫 - 觸發一次 IP 變動,確認 KV 已被自動更新
- Shadowrocket / Clash App 實測訂閱,確認能正常連線
- 桌機實測
irm ...?v=install | iex一鍵安裝流程 - 開啟訂閱自動更新,間隔設為 15~30 分鐘
- 其餘朋友依 SOP 逐一加入
- 【待補】把 Clash
RULES_BODY裡刪減的 628 條規則貼回