返回 Webship 部落格

Webship 工程

TLS 終止還是直通?選擇正確的 Webship 反向代理邊界

TLS 終止解鎖了路由、快取和 HTTP 安全檢查;直通則保持明文和會話金鑰在原點。本指南說明了權衡、測量的性能以及實時 Webship 配置。

在 TLS 終止和 TLS 直通之間進行選擇並不是一個表面的代理設置。它決定了加密在哪裡結束、哪個系統持有會話密鑰、Webship 是否能檢查 HTTP,以及哪一層必須執行應用安全。

Webship 預設為直通模式。這可保持應用程式明文和活動的會話金鑰在原點。僅當邊緣必須理解並處理 HTTP 請求時才啟用終止。

一句話中的決定

當原始伺服器必須擁有 TLS 邊界時,使用 TLS 直通。當 Webship 必須路由、保護、轉換、快取或觀察 HTTP 流量時,使用 TLS 終止

兩種模式都不是普遍更安全的。直通模式減少了邊緣處理的敏感資料,但會移除邊緣的 HTTP 安全控制。終止模式增加了一個可檢查的執行點,但會使 Webship 成為受信任的 TLS 邊界的一部分。

| 關注點 | TLS 終止 | TLS 直通 | | --- | --- | --- | | TLS 端點 | Webship | 來源 | | 申請純文字於 Webship | 是 | 否 | | Webship 的活動下游會話金鑰 | 是 | 否 | | 透過 HTTP 路徑或方法路由 | 是 | 否 | | WAF、API 防護以及主體限制於 Webship | 是 | 否 | | 代理快取、重寫及轉發標頭 | 是 | 否 | | TCP 路由輸入 | HTTP 權限和路由策略 | ClientHello SNI | | HTTP/3 路由 | HTTP 請求數據 | 一個共享的 UDP 來源 | | 原點責任 | HTTP 或單獨配置的上游 TLS | 完整 TLS、ALPN 和 HTTP 堆疊 |

因此,重要的問題不是「哪個開關比較快?」而是「哪個元件必須被允許查看並控制這個請求?」

什麼終止給予 Webship

使用 tls_termination = true,Webship 完成下游 TLS,並將解密後的請求導入其 HTTP 反向代理管線。這使以下功能成為可能:

  • 路徑、主機及方法感知的路由;
  • WAF 和 API Shield 檢查;
  • 請求主體限制和政策超時;
  • 代理緩存與生成安全失效;
  • 轉發標頭管理和 HTTP 存取日誌欄位;
  • 具備體態感知的查詢處理、安全重試以及斷路器策略;
  • 客戶端對應連接與上游連接之間的協議轉換。

此模式也會改變安全責任。Webship 主機必須保護憑證私鑰、會話密鑰、解密的請求和回應資料、可觀察性輸出,以及任何快取的表示。如果下一跳必須保持加密,請單獨配置類型化的上游 TLS;否則 HTTP 上游為明文。

當 Webship 預期作為應用程式感知的邊緣,而不僅僅是加密傳輸中繼時,終止是右邊界。

通過式傳遞保留了什麼

使用 tls_termination = false——預設值——Webship 轉發加密的 TLS 或 QUIC 流量,而不解密 HTTP 請求或回應。應用程式明文和活動會話密鑰保留在來源端。

當證書必須保留在應用層、合規政策禁止邊緣解密,或必須將特定來源的 TLS 身份保持不變地傳送給客戶端時,那個較小的信任邊界是非常有價值的。它還可以將 HTTP 解析和策略工作從中繼路徑中移除。

權衡是嚴格的:Webship 無法檢查其無法解密的內容。它無法應用 HTTP WAF 規則、按路徑路由、重寫標頭、執行具體內容感知的 API 政策,或生成 HTTP 欄位訪問日誌。來源端必須自行提供所有這些控制功能。

因此,Pass-through 並不是「功能較少的終端」。它是一種具有不同安全擁有者的不同架構。

特定協議的限制很重要

對於 HTTP/1.1 TLS 和 HTTP/2 TLS,Webship 只檢查 ClientHello 到足以根據 SNI 選擇已配置的 TCP 目標。每個直通域都需要一個 catch-all path_prefix = "/" 路由,因為實際的請求路徑保持加密。只有配置中有一個域時,才接受沒有 SNI 的客戶端。

源端必須協商客戶端的 ALPN 並支持所選協議。Webship 無法在 TLS 會話保持不變的情況下,將 HTTP/2 客戶端轉換為 HTTP/1.1 源端。

HTTP/3 使用基於 UDP 的 QUIC,並且具有更嚴格的邊界。直通無法安全地根據加密的 HTTP 權限進行路由,因此每個配置的 HTTP/3 路由必須解析到相同的 IP-socket UDP 原點。Webship 在配置驗證期間拒絕 Unix 套接字和多個 HTTP/3 直通原點,而不是默默地模糊路由。

明文 HTTP/1.1 和 h2c 不受 reverse_proxy.tls_termination 的影響。此設定僅控制下游 HTTP/1.1 TLS、HTTP/2 TLS 和 HTTP/3 TLS。

測量請求容量

Webship 1.3.1 Debian 容量基準測試分別測量了兩種加密反向代理模式。每個被接受的樣本都要求零 HTTP、套接字、協議、代理、主要頁面錯誤以及 HTTP/3 封包丟失錯誤。

| 反向代理模式 | HTTP/1.1 TLS | HTTP/2 TLS | HTTP/3 TLS | | --- | ---: | ---: | ---: | | TLS 終止 | 123,344 RPS | 124,957 RPS | 131,529 RPS | | TLS 直通 | 203,950 次請求/秒 | 266,845 次請求/秒 | 167,010 次請求/秒 |

小型回應穿透需要執行的應用工作較少:它轉發加密的傳輸數據,而不是終止 TLS、解析 HTTP、評估策略或產生新的下游 TLS 流。較高的穿透請求速率反映了這個較窄的工作範圍。

這些列並不代表相同的功能集,且不應用來聲稱某個安全架構普遍優於其他架構。終端處理支付了 HTTP 感知功能的費用,而通過式無法提供這些功能。

大量串流會改變結果

同一基準測試對 100 MB 流式矩陣使用了精確的 99,943,778 字節回應主體。在這裡,TLS 終止對所有三種協議產生了更高的中位有效載荷吞吐量:

| 反向代理模式 | HTTP/1.1 TLS | HTTP/2 TLS | HTTP/3 TLS | | --- | ---: | ---: | ---: | | TLS 終止 | 3,585.7 MiB/s | 3,355.0 MiB/s | 1,938.6 MiB/s | | TLS 直通 | 2,783.2 MiB/s | 2,135.0 MiB/s | 1,748.5 MiB/s |

為什麼方向會改變?在終止模式下,基準源向 Webship 發送明文 HTTP,而 Webship 擁有優化的下游批量路徑。大型 HTTP/1.1 和 HTTP/2 回應可以使用自適應 Linux kTLS 以及有界的傳輸專用緩衝。HTTP/3 使用 QUIC 節拍、DPLPMTUD,以及每個反應器的批次處理,而不是 kTLS。

在直通模式下,來源擁有下游 TLS,並Webship轉發加密的串流或 QUIC 封包。這會保留來源 TLS 邊界,但無法使用 Webship 的 HTTP 感知批量回應路徑。

七樣本 HTTP/3 資格測試也檢查了穩定性。終止串流達到 1,938.6 MiB/s 的中位數,變異係數為 2.12%;直通達到 1,748.5 MiB/s,變異係數為 1.65%。兩者都輸出了完全相同的內容,沒有客戶端、協議和封包遺失錯誤。

故意配置直通

一個最小的直通配置會保持 TLS 身份階段化,以便操作員可以在不更改證書路徑的情況下稍後啟用終止:

[reverse_proxy]
enabled = true
tls_termination = false

[reverse_proxy.protocols]
h1 = true
h2 = true
h3 = true

[reverse_proxy.tls]
cert = "/etc/webship/proxy-cert.pem"
key = "/etc/webship/proxy-key.pem"

[[reverse_proxy.routes]]
domain = "app.example.com"
path_prefix = "/"
upstreams = ["10.0.0.20:443"]

[[reverse_proxy.policies]]
name = "default"
path_prefixes = ["/"]
total_timeout_ms = 30000

暫存的 Webship 憑證已驗證,但未被活動的直通會話使用。位於 10.0.0.20:443 的來源必須終止 TLS 並支援客戶端協商的協議。

當邊緣需要 HTTP 時啟用終止

對於應用程式感知的邊緣,啟用終止並將產生的 HTTP 流量發送到選定的來源:

[reverse_proxy]
enabled = true
tls_termination = true

[reverse_proxy.protocols]
h1 = true
h2 = true
h3 = true

[reverse_proxy.tls]
cert = "/etc/webship/proxy-cert.pem"
key = "/etc/webship/proxy-key.pem"

[[reverse_proxy.routes]]
domain = "app.example.com"
path_prefix = "/api"
strip_path_prefix = true
upstreams = ["10.0.0.20:8080", "10.0.0.21:8080"]

[[reverse_proxy.policies]]
name = "default"
hosts = ["app.example.com"]
path_prefixes = ["/"]
max_body_bytes = 1048576
request_body_idle_timeout_ms = 5000
upstream_header_timeout_ms = 5000
response_body_idle_timeout_ms = 5000
downstream_write_idle_timeout_ms = 5000
total_timeout_ms = 30000

此配置可以路由和檢查 HTTP。當 Webship 與源之間的網路尚未被信任或隔離時,請添加上游 TLS。

切換模式而無需重新啟動 Webship

Webship 可以透過重新載入配置檔或版本檢查的 webship.reverse_proxy.apply_config MCP 工具更改 tls_termination。使用 webship.reverse_proxy.get_config 讀取當前物件和版本,只更改完整返回物件中預期的欄位,並使用對應的 expected_version_id 提交。

新的 TCP 連接使用新模式。HTTP/3 客戶端重新連接到被替換的 UDP 傳輸。證書和金鑰路徑的更改仍然與進程綁定,需要重啟,因此在進行實時切換前,請保持一個有效的終止身份準備好。

版本檢查可以防止一個操作員覆蓋同時發生的配置更改。被拒絕的更新會保持當前運行時和已保存的配置不變。

實用的選擇清單

當以下所有條件都成立時,選擇通過

  1. 來源端必須保留憑證邊界和會話密鑰。
  2. SNI 級別的 TCP 路由——或一個共用的 HTTP/3 UDP 來源——就足夠了。
  3. 來源提供所需的 WAF、授權、日誌記錄、正文限制和濫用控制。
  4. 不需要邊緣緩存、路徑重寫、轉發標頭策略或 HTTP 協議轉換。

當在 Webship 需要以下任意項目時,請選擇終止:

  1. 依據主機、路徑或方法進行路由。
  2. 使用 WAF 或 API 盾牌檢查請求。
  3. 強制執行主體限制、HTTP 超時或邊緣身份驗證。
  4. 快取回應或重寫 HTTP 標頭。
  5. 在下游和上游 HTTP 協議之間進行轉換。
  6. 在代理邊界觀察 HTTP 欄位。

無論您選擇哪種模式,都要測試 SNI、ALPN、證書身份、客戶端取消、上游半關閉,以及精確的回應完整性。請分別測量請求容量和串流吞吐量:對於小回應最快的模式,不一定是處理 100 MB 主體最快的模式。

Webship 將通過設為預設,因為代理不應該默默地擴大其信任範圍。當 HTTP 感知的邊緣行為值得承擔這個責任時,終止仍然是一個有效的、明確的操作選擇。

閱讀完整的 [反向代理文件](/docs/1.3.1)、比較接受的 [基準矩陣](/benchmarks),或從 [下載](/downloads) 下載 Webship。

來源與內容方法

性能值是來自 Webship 1.3.1 統一 Debian 容量基準測試(2026 年 9 月 11 日)的公認中位數;其接受標準要求零客戶端、HTTP、套接字、協議、代理、主要頁面錯誤,以及 HTTP/3 封包丟失錯誤。