返回 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 Shield 和主体限制在 Webship | 是 | 否 | | 代理缓存、重写和转发头 | 是 | 否 | | TCP 路由输入 | HTTP 权限和路由策略 | ClientHello SNI | | HTTP/3 路由 | HTTP 请求数据 | 一个共享的 UDP 来源 | | 源头责任 | HTTP 或单独配置的上游 TLS | 完整的 TLS、ALPN 和 HTTP 堆栈 |

因此,重要的问题不是“哪个开关更快?”而是“必须允许哪个组件查看并控制请求?”

什么终止符给 Webship

借助 tls_termination = true,Webship 完成下游 TLS 并将解密后的请求输入其 HTTP 反向代理管道。这使以下功能成为可能:

  • 路径、主机和方法感知的路由;
  • WAF 和 API 保护检查;
  • 请求体限制和策略超时;
  • 代理缓存和生成安全失效;
  • 转发头管理和 HTTP 访问日志字段;
  • 支持主体感知的查询处理,在安全的情况下重试,并采用断路器策略;
  • 客户端连接和上游连接之间的协议转换。

此模式还会改变安全责任。Webship 主机必须保护证书私钥、会话密钥、解密的请求和响应数据、可观测性输出以及任何缓存的表示。如果下一跳必须保持加密,请单独配置类型化的上游 TLS;否则 HTTP 上游为明文。

当期望 Webship 作为具有应用感知能力的边缘,而不仅仅作为加密传输中继时,终止是右边界。

通行费用保护什么

使用 tls_termination = false——默认设置——Webship 转发加密的 TLS 或 QUIC 流量,而不会解密 HTTP 请求或响应。应用程序明文和活动会话密钥保留在源端。

当证书必须保留在应用层、合规政策禁止边缘解密,或特定源的 TLS 身份必须以不变的形式传递给客户端时,这个较小的信任边界是有价值的。它还从中继路径中移除了 HTTP 解析和策略工作。

权衡是严格的:Webship 无法检查其无法解密的内容。它无法应用 HTTP WAF 规则,按路径路由,重写头信息,执行对主体内容感知的 API 策略,或填充 HTTP 字段访问日志。源端必须自行提供所有这些控制。

因此,直通并不是“功能更少的终端”。它是一种具有不同安全所有者的不同架构。

特定协议的限制很重要

对于 HTTP/1.1 TLS 和 HTTP/2 TLS,Webship 仅检查 ClientHello 到足以通过 SNI 选择配置的 TCP 目标的程度。每个直通域都需要一个通配的 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 Shield 检查请求。
  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 数据包丢失错误。