症状
您的客户端应用在调用 Apigee 端点时,可能会在 TLS 握手期间遇到连接重置、连接遭拒或类似错误。
错误消息
Postman 或 Node.js 客户端可能会看到 ECONRESET 错误消息。
当直接向 Apigee Ingress IP 地址发出 HTTPS 调用时,Curl 可能会显示 Connection reset by peer。例如:
curl https://1.2.3.4/basepath -H "Host: your.apigee.domain" -kv * Connected to 1.2.3.4 (1.2.3.4) port 443 * (304) (OUT), TLS handshake, Client hello (1): * Recv failure: Connection reset by peer * Closing connection
-
其他客户端可能会显示不同的错误。不过,模式是相同的;客户端在 TLS 握手期间无法完全建立连接。
可能的原因
Apigee Hybrid 的入站流量网关默认启用服务器名称指示 (SNI)。如果您的客户端未启用 SNI,并且未配置通配符 Apigee 路由来启用非 SNI 客户端,则可能会出现此问题。这会导致系统不会向客户端发送默认 TLS 服务器证书,并且 Apigee 入口 TCP 重置会发生。
诊断
确定您的客户端是否已启用 SNI。如果您已经知道未启用 SNI,请继续执行第 4 步,验证 Apigee Hybrid 配置。
查看 Apigee Ingress 访问日志,了解是否有客户端请求未包含 SNI 服务器名称,并检查虚拟主机是否未为非 SNI 客户端配置默认证书。
- 使用以下命令获取
apigee-ingressgateway
pod 的列表:kubectl -n apigee get pods -l app=apigee-ingressgateway
示例输出
NAME READY STATUS RESTARTS AGE apigee-ingressgateway-ext-ingress-myorg-hyb-8f2c412-dvrcp 2/2 Running 0 46h apigee-ingressgateway-ext-ingress-myorg-hyb-8f2c412-wg26k 2/2 Running 0 46h
- 获取
apigee-ingressgateway
pod 的日志。 其中,APIGEE_INGRESSGATEWAY_POD 是上一个命令输出中列出的kubectl -n apigee logs APIGEE_INGRESSGATEWAY_POD
apigee-ingressgateway
pod。 - 访问日志可能如下所示:
{ "request_time": 1, "tls_protocol": null, "upstream_service_time": null, "request_method": null, "request_protocol": null, "upstream_response_time": null, "bytes_sent": 0, "start_time": "2025-05-19T04:46:20.117Z", "bytes_received": 0, "host": null, "upstream_cluster": null, "upstream_address": null, "remote_address": "10.138.0.28:19432", "request_path": null, "request_id": null, "user_agent": null, "status_details": "filter_chain_not_found", "request": "- - -", "status": 0, "x_forwarded_for": null, "apigee_dynamic_data": null, "upstream_response_flags": "NR", "sni_host": null }
- 通过分析上述日志,您可以推断出以下信息:
"sni_host": null
:客户端未启用 SNI,因为没有 SNI 主机名。例如,api-test.mydomain.com
与此请求相关联。"status_details": "filter_chain_not_found"
:服务器证书是根据sni_host
中的filter chain
选择的。如果不存在sni_host
且未配置默认值,则找不到filter chain
。这意味着不会返回任何服务器证书,如示例客户端请求所示。"status": 0
:由于连接已重置,因此没有状态代码。
- 除了查看日志之外,还可以通过在 Apigee Ingress 前面或 Apigee Ingress 本身捕获数据包,更精确地检查客户端是否已启用 SNI。这有助于确定客户端是否在 TLS 握手时发送 SNI 标头。
- 若要在 Google Kubernetes Engine 上运行 Apigee Ingress,您需要通过 SSH 连接到运行 Ingress 网关的节点,并安装 toolbox 和 tcpdump。
tcpdump -n -i any -s 0 'host IP_Address' -w FILE_NAME
其中,FILE_NAME 是您要保存数据包捕获输出的文件名(包括路径)。
- 使用 Wireshark 或类似工具分析捕获的数据包。
- 以下是使用 Wireshark 在 Apigee Ingress 上捕获的数据包的分析示例。
。
- 在数据包捕获输出中,消息 #83 表示客户端(来源)向 Apigee Ingress(目的地)发送了“Client Hello”消息。
- 当您选择 Client Hello 消息并检查 Handshake Protocol: Client Hello 时,会发现缺少 Extension: server_name。
- 例如,启用 SNI 的客户端将在输出中显示 Extension: server_name,如以下示例所示。
- 这确认了客户端未将 server_name 发送到 Apigee Ingress。
- 由于 Client Hello 消息中未包含任何 SNI server_name,因此不会返回任何服务器证书,并且 Apigee Ingress 会使用 RST 数据包关闭连接。
- 在数据包捕获输出中,消息 #83 表示客户端(来源)向 Apigee Ingress(目的地)发送了“Client Hello”消息。
- 通过使用 OpenSSL 等工具测试 Apigee 端点来检查是否支持非 SNI 客户端,以发送带有或不带有 SNI 标头的请求。al。
- 检查非 SNI 客户端是否已启用。
openssl s_client -connect api-test.mydomain.com:443 -noservername
输出示例
Connecting to 1.2.3.4 CONNECTED(00000005) write:errno=54 --- no peer certificate available --- No client certificate CA names sent --- SSL handshake has read 0 bytes and written 299 bytes Verification: OK --- New, (NONE), Cipher is (NONE) This TLS version forbids renegotiation. Compression: NONE Expansion: NONE No ALPN negotiated Early data was not sent Verify return code: 0 (ok) ---
- 上述响应显示没有可用的对等证书,这意味着 Apigee 路由中未启用 SNI 客户端,因为我们在命令中传递了 -noservername 选项。如果在使用 -noservername 标志时返回了对等证书,则表明已配置通配符路由。
- 检查非 SNI 客户端是否已启用。
- 查看当前的 Apigee 路由配置,了解虚拟主机上是否已配置并启用通配符路由。
- 使用以下命令获取已定义的 Apigee 路由的列表:
kubectl -n apigee get apigeeroutes
示例输出
NAME STATE AGE myorg-hyb-dev-grp-000-33620d0 running 2d1h non-sni running 17s
- 检查每个 Apigee 路由中是否包含通配符主机名。
对于每个 Apigee 路由,执行提供的命令以检索其已定义主机名的 JSON 数组。输出中会使用星号 (
*
) 指示通配符路由。kubectl -n apigee get apigeeroute APIGEE_ROUTE_NAME
myorg-hyb-dev-grp-000-33620d0
路线的示例:kubectl -n apigee get apigeeroute myorg-hyb-dev-grp-000-33620d0 -o jsonpath='{.spec.hostnames}'
示例输出
["api-test.mydomain.com"]
non-sni
路线的示例:kubectl -n apigee get apigeeroute non-sni -o jsonpath='{.spec.hostnames}'
示例输出
["*"]
non-sni
apigeeroute 是通配符路由,因为它包含 (*
) 作为主机名。 - 如果配置了通配符路由,则会启用非 SNI 客户端。
- 对于通配符路由,请确保
enableNonSniClient
标志设置为 true。以下命令在具有non-sni
客户端的通配符路由上运行。kubectl -n apigee get apigeeroute non-sni -o jsonpath='{.spec.enableNonSniClient}'
示例输出
true
- 如果通配符路由存在且非 SNI 客户端已启用,请查看
overrides.yaml
文件中的虚拟主机配置,确保通配符路由列在additionalGateways
中。virtualhosts: - name: dev-grp selector: app: apigee-ingressgateway ingress_name: ext-ingress sslCertPath: ./certs/keystore_dev-grp.pem sslKeyPath: ./certs/keystore_dev-grp.key additionalGateways: ["non-sni"]
additionalGateways
将显示在虚拟主机配置定义的 Apigee 路由中。 使用以下命令确认您配置的additionalGateway
是否显示在 Apigee 路由配置中。kubectl -n apigee get apigeeroute APIGEE_ROUTE_NAME -o jsonpath='{.spec.additionalGateways}
例如,
myorg-hyb-dev-grp-000-33620d0
路线应将non-sni
路线显示为additionalGateway
。kubectl -n apigee get apigeeroute myorg-hyb-dev-grp-000-33620d0 -o jsonpath='{.spec.additionalGateways}'
示例输出
["non-sni"]
解决方法
如果诊断步骤表明您的客户端是已启用非 SNI 的客户端,但您的 Apigee Hybrid 安装中未启用或未正确配置非 SNI 客户端,请按照启用非 SNI 客户端文档中的说明操作,以允许来自非 SNI 客户端的流量。
必须收集的诊断信息
如果按照上述说明操作后问题仍然存在,请收集以下诊断信息,然后与 Google Cloud Customer Care 联系:Overrides.yaml
- 以下命令的输出
kubectl -n apigee get apigeeroutes
- 针对每个声明的路由,运行:
kubectl -n apigee describe apigeeroute
- 出现问题的环境组
- 使用以下命令获取已定义的 Apigee 路由的列表: