Cloudflare Tunnel 與應用層端對端加密(E2EE)技術白皮書

當我們透過 Cloudflare Tunnel 遠端控管伺服器的動態 IP 白名單工具時,控制平面的認證安全性至關重要。本文件深度剖析逆向代理環境下的信任鏈邊界,並詳細闡述如何利用 ECDH 與 AES-256-GCM 構建零信任應用層加密通道。

1. 為什麼需要 Payload 加密

在標準的 Cloudflare Tunnel 部署中,邊界節點需要對客戶端 HTTPS 流量進行認證、路由與清洗。

⚠️ 邊界信任宣告:Cloudflare 因此具備存取 HTTP 明文內容的能力。如果管理端 API 直接傳輸明文帳號密碼或敏感的 Ingest Token,這些敏感資產將在邊界節點的記憶體中以明文形式暴露,這在嚴格的零信任架構中是不被允許的。

2. 威脅模型 (Threat Model)

本系統的密碼學架構設計有着明確的防禦邊界:

本系統設計防範 (In-Scope) 本系統不防範 (Out-of-Scope)
全球背景惡意掃描 (Internet Background Scan) 伺服器主機作業系統已被攻陷 (Host Compromised)
針對未開放端口的精準掃描 (Port Scan) 核心態惡意代碼植入 (Kernel Rootkit)
中間人側錄與未授權 Publish 嘗試 上游軟體供應鏈污染 (Supply Chain Attack)
管理端入口的字典爆破與密碼撞庫 密碼學基礎算法的 0-Day 漏洞
邊界逆向代理節點對敏感數據的直接讀取 瀏覽器端被惡意擴充套件側錄

3. Cloudflare Tunnel 傳輸拓撲

分析數據在網絡傳輸過程中的加密狀態轉變:

flowchart LR
A[授權用戶瀏覽器] -->|1. 外部 HTTPS 加密| B[Cloudflare Edge]
B -->|2. 內部 Tunnel 加密| C[cloudflared 守護進程]
C -->|3. 127.0.0.1 本機明文| D[Node.js 控管服務]
          
🔒 本機通訊安全:第三段明文傳輸僅發生在主機內部的環回網絡介面(Loopback Interface),外部線路無法對其進行網絡嗅探。

4. 為什麼傳統 TLS 還不夠

傳統 TLS(HTTPS)僅能保證「瀏覽器到 Cloudflare Edge」這段線路上的機密性。在 Edge 執行 TLS Termination(TLS 解密截斷) 之後,應用層數據包暴露。這就像用上鎖的保險箱運送一份沒上鎖的文件:保險箱確實鎖住了,但保管鑰匙的逆向代理服務商本來就有鑰匙。

5. ECDH 密鑰交換原理

為了實現真正的端對端安全,我們必須讓敏感 Payload 在瀏覽器端就地加密,直到進入本機 Node.js 後才允許解密。

系統採用 ECDH (橢圓曲線迪菲-赫爾曼密鑰交換) P-256 曲線。伺服器持有固定的密鑰對,客戶端每次發起請求時臨時生成一對短暫密鑰(Ephemeral Key,確保前向安全性)。

🛡️ 密碼學隔離結論:雙方經由數學運算導出相同的共享秘密(Shared Secret),並衍生出對稱加密密鑰。Cloudflare 無法直接取得應用層 Payload 的明文內容。

6. AES-256-GCM 應用層對稱加密

導出共享密鑰後,系統放棄傳統安全性較低的 CBC 模式,全面採用 AES-256-GCM(伽羅瓦/反饋計數器模式)

  • 認證加密 (AEAD):GCM 模式在加密的同時生成 128-bit 的認證標籤 (Authentication Tag),能有效防範密文被惡意篡改或重放攻擊。
  • 唯一隨機向量:每次加密強制配給 96-bit 唯一的初始化向量 (IV/Nonce),徹底消除密文特徵規律。

7. Web Crypto API 原生實作

本系統完全調用環境原生的密碼學核心,拒絕使用任何未經審查的第三方自刻加密庫:

// 前端瀏覽器端調用標準 Web Crypto API 進行加密
const sharedSecret = await window.crypto.subtle.deriveBits(
  { name: "ECDH", public: serverPublicKey },
  clientPrivateKey,
  256
);

const aesKey = await window.crypto.subtle.importKey(
  "raw", sharedSecret, { name: "AES-GCM" }, false, ["encrypt"]
);

const ciphertext = await window.crypto.subtle.encrypt(
  { name: "AES-GCM", iv: nonce },
  aesKey,
  new TextEncoder().encode(JSON.stringify(apiBody))
);

8. 完整數據時序流圖

sequenceDiagram
  autonumber
  participant B as 瀏覽器 (Client)
  participant CF as Cloudflare Edge
  participant S as Node.js 伺服器 (Origin)

  B->>S: 獲取伺服器 ECDH 公鑰
  S-->>B: 返回公鑰 (固定)
  Note over B: 1. 本地生成臨時密鑰對
2. 計算出 Shared Secret
3. AES-GCM 加密明文 Payload B->>CF: 發送 HTTP POST (Body 已成密文) Note over CF: TLS Termination 解密
僅能看見密文外殼與隨機公鑰 CF->>S: 經由 Tunnel 轉發加密 Body Note over S: 1. 提取客戶端臨時公鑰
2. 計算出 Shared Secret
3. AES-GCM 解密並驗證 Tag
4. Hot Reload 寫入設定檔

9. 密碼學安全性分析

逆向代理節點(Cloudflare)可知資產 逆向代理節點(Cloudflare)不可知資產
請求 URL 路徑、HTTP Method、HTTP Headers 用戶輸入的明文管理員密碼
現場端瀏覽器的真實來源公網 IP 由密鑰衍生出的 Session Token
通訊發生的時間點與精確的數據包大小 即將寫入 MediaMTX 配置的真實 IP 數據池
TLS SNI 特徵標記 任何結構化的內部 JSON 配置對象

10. 系統限制與潛在威脅

  • 初次信任風險 (TOFU):若客戶端在首次獲取伺服器靜態公鑰時遭受了高度精準的中間人攻擊(MITM),則端對端加密鏈路存在被破解的理論可能。
  • 元數據洩漏 (Metadata Leakage):雖然 Payload 內容得到完美保護,但攻擊者仍能通過大數據流量分析(Traffic Analysis),依據封包大小與時序特徵推斷出控制行為的發生。

11. 密鑰管理維護檢查清單

  • 伺服器私鑰檔案 server-ecdh-keys.json 必須嚴格限定權限為 chmod 600
  • 嚴禁將包含伺服器真實私鑰的配置上傳至任何公開的 GitHub 倉庫或非加密的雲端備份盤。
  • 建議每隔 180 天執行一次伺服器端 ECDH 密鑰對的主動輪換(Key Rotation)。
  • 控制端 API 入口必須配置速率限制(Rate Limit),防止針對密文標籤的主動重放探測。