客户端说的是 HTTP,代理看得到路径吗

orders 要把 sku=paper 请求送到库存服务:应用协议、连接的传输加密、代理是否能看见请求路径,是三个独立问题。第 03 篇中的 route 要求 Envoy 能读 HTTP 的 host/path;若所见的只是透传 TLS 密文,代理可以依据连接层可见信息决定去向,但不能凭空读取加密后的 /quote。本篇先用同一个 inventory-v1 实测 TLS 主机名校验和 ALPN,再说明 HTTP/2、gRPC 与 TLS 终止/透传的边界;未声称已运行 sidecar 协议识别。

明文 HTTP 与 TLS 握手、SNI、ALPN 分层后代理可能终止或透传,再由上游处理请求

图中的 SNI 是 TLS 握手给服务器提示的名称,ALPN 是协商应用协议的扩展;它们不等于 HTTP Host、gRPC method 或最终用户 JWT。代理只有在终止相应 TLS 连接并解析上层协议时,才可能按 HTTP 路径或 gRPC 请求元数据作七层治理。TLS 透传和 HTTP 路由适用于不同可见范围。

两条连接不一定采用同一协议

调用方到代理是下游连接,代理到后端是上游连接。客户端至入口网关可以 TLS 终止后以另一条连接转发;sidecar 场景可能有应用到本地代理的明文、两个代理之间的 mTLS,以及远端代理到应用的连接。不能由某一段使用 TLS 就宣称其余连接段都加密,也不能把最终用户认证与代理间工作负载身份混为一谈。具体部署的 TLS mode 需要逐段核对第 19–21 篇的身份、认证和授权证据。

HTTP/1.1 可以在一个 TCP 连接上复用请求;HTTP/2 用流多路复用,gRPC 在常见模式下依赖 HTTP/2,并在其上定义调用消息和状态。Envoy 能识别的协议受端口声明、检测与连接协商影响:将 TLS 端口当作明文 HTTP 端口,或把不支持的 HTTP/2 链路误标成 gRPC,都可能让七层策略不生效。版本相关的自动检测、ALPN 行为和特性支持必须和冻结的 Istio/Envoy 配置核对,不能用端口号猜。

在 TLS 透传时,可见的 SNI 可以用于连接级路由,但 HTTP Host、路径及 gRPC 方法对这个未解密的代理不可见;在 TLS 终止后,代理可按相应协议解析请求,而证书信任、名称校验和请求是否已获授权仍是不同步骤。更改 SNI、HTTP Host 或目标端口应分别设计测试,不能把它们当同一字段。

对同一个库存进程做 TLS 直连对照

examples/service-mesh/apps/mesh-demo/main.go 现在支持可选的 -tls-cert/-tls-key,原有无网格 HTTP 路径保持不变。在 examples/service-mesh/ 运行:

1
GO_BIN=/tmp/service-mesh-tools/go/bin/go bash scripts/run-09.sh

脚本在 /tmp 临时生成仅用于合成实验的自签名证书和不提交的私钥,SAN 只包含 inventory.mesh.invalid;服务绑定 127.0.0.1,证书与私钥仅用于本次进程,退出时删除。curl 显式信任该实验公钥并把正确域名解析到 loopback:sm-09-valid 返回 HTTP 200、inventory_version=v1;把 URL 主机名改成 wrong.mesh.invalid,仍指向同一 IP/端口,则 curl 在证书名称校验处退出 60,没有业务响应。openssl s_client 使用正确 SNI、验证主机名并提供 h2,http/1.1,该次握手输出 ALPN protocol: h2。GET /ledger 仍为 []。

成功的一轮原始输出与全部命令、退出码、Go/OpenSSL 版本及源码 SHA-256 在 examples/service-mesh/evidence/09/20261001T133502Z-2578825/,四项断言 PASS。此前两轮因 openssl s_client -brief 不展示 ALPN 文本而使断言返回非零,保留在同一 evidence/09/ 下;取消 -brief 后重新运行并检查原始协商输出。该失败是采证格式选择失误,不是“服务器不支持 HTTP/2”的证据。

这个进程实验没有 Envoy TLS listener、sidecar、gRPC 服务或客户端证书,协议识别、TLS 终止/透传、mTLS、gRPC method 路由及各代理连接段均 NOT_RUN。端到端实验须在隔离集群中分别保存 listener/route/cluster、客户端协商协议与验证结果、代理访问日志与上游请求 ID,再为 gRPC 补入固定版本依赖和同一 SKU 的真实 RPC 请求;不把 openssl 握手冒充应用 gRPC 请求。需要先解决 writing-plans/service-mesh/CONTINUE.md 中缺失的环境。

练习与参考解答

  1. 同一 IP 和端口上,inventory.mesh.invalid 成功而 wrong.mesh.invalid 失败,能否推断服务端业务拒绝了后者?参考解答:不能。失败发生在客户端验证证书的名称阶段,业务 HTTP handler 没收到后者的请求。核对 curl 退出 60、客户端 TLS 错误及没有对应应用请求 ID;换成代理路径时还要确认 TLS 在哪一段终止。
  2. 在透传 TLS 的入口上加一条仅匹配 HTTP /quote 的策略,预期如何设计反例?参考解答:入口若不终止 TLS,无法看到加密后的路径;分别测试两个相同 SNI、不同 HTTP 路径的合成请求,保存代理 TLS 配置、路由匹配/访问记录与应用日志。若想按路径治理,须在合适的可信边界终止 TLS,再检查新的上下游连接及身份约束。当前环境未运行此反例,不填具体状态码。

官方资料与系列导航

系列导航:00 基线 → 08 发现 → 09 HTTP、gRPC 与 TLS(本文)→ 10 按版本和请求属性选择后端。