服务网格 20:mTLS 开启后哪些连接受到保护
一次 HTTP 调用可以经过不止一段连接
orders 请求 inventory 看上去只有一个 URL,实际却可能经过 orders 应用 → 本地出站代理 → 网络 → inventory 入站代理 → 库存应用。Istio 的工作负载 mTLS 验证的是代理之间的连接与身份;应用到同 Pod 代理、代理到本地应用的段仍要分别确认。把“服务之间启用了 mTLS”简写成“每个字节在每一段都加密”会遗漏这两段。第 09 篇的应用自己提供 TLS 的演示也不是此处代理 mTLS 的验收。
服务端 PeerAuthentication 决定入站能接受什么连接:PERMISSIVE 同时接受明文和 mTLS,STRICT 要求 mTLS。客户端代理是否真的发起 mTLS,则要看出站配置、目标是否识别为网格工作负载,以及是否存在显式 DestinationRule;不能只看服务端策略推断客户端行为。自动 mTLS 是在合适的发现和配置条件下帮助客户端选择 mTLS,不代表任意网外目标都自动升级。
先固定连接段,再讨论拒绝
在隔离命名空间中,只给 inventory 设置有明确工作负载 selector 的 PeerAuthentication,先使用 PERMISSIVE,分别由入网格的 orders 和不注入代理的测试客户端访问同一库存服务。对两组请求分别保存来源 Pod 是否实际注入、出站和入站代理的活跃 TLS 配置、握手/连接证据、带 ID 的请求结果;可用 Istio 的连接安全策略标签作辅助,不以单个指标替代连接证据。随后只将服务端入站模式改为 STRICT,重复相同请求集。按 Istio 的 mTLS 迁移语义,正常配置的网格内客户端应继续成功,明文客户端不应再直达库存应用;实际现象以代理捕获的拒绝位置为准。
再做一个单独的客户端负例:保留 STRICT,仅在测试用的出站规则中禁用该目标的 TLS。它与“未入网格客户端”不是同一种来源,错误可以在出站或目标握手处暴露。每次只改变一个变量,先撤回上一个测试策略,再测试下一项;不能让先前的授权策略、第 18 篇的出口策略或 Service 端点故障污染结果。
| 连接 | PERMISSIVE 待测 |
STRICT 待测 |
判据 |
|---|---|---|---|
orders 代理 → inventory 代理 |
NOT_RUN | NOT_RUN | 双方实际使用的证书/连接及应用结果一致 |
未注入客户端 → inventory 入站代理 |
NOT_RUN | NOT_RUN | 明文被接纳或被拒绝,定位在入站握手而非应用业务逻辑 |
orders 应用 → 本地代理 → 库存应用 |
NOT_RUN | NOT_RUN | 单独标注本地两段的协议,不能用跨 Pod 连接代替 |
STRICT 的负例可能表现为连接断开、TLS 握手失败或客户端收到代理生成的错误,不预设 HTTP 403。如果请求成功,应首先核对 selector 命中、端口级例外、Pod 是否真正注入以及是否绕过代理;成功本身不能证明策略实现失效。
练习与参考解答
- 服务端设置
STRICT,为什么仍要检查客户端出站配置?参考解答:服务端策略约束入站接收,不能指定客户端必然使用 mTLS;两端缺一不可。 - 对库存 Pod 内
localhost的应用端口做明文请求成功,是否推翻代理间 mTLS?参考解答:没有。它测的是本地应用段,不能直接推断跨 Pod 的代理间连接。
官方资料与系列导航
- Istio mTLS Migration:两种入站模式的迁移与验证方法。
- PeerAuthentication 参考:selector、模式与端口级规则。
- TLS 配置详解:出站
DestinationRule、入站策略与自动 mTLS 的分工。
系列导航:19 工作负载身份和证书怎样建立 → 20 mTLS 开启后哪些连接受到保护(本文)→ 21 认证成功为何仍会被拒绝。

