問題
呼叫 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 的 Ingress 閘道預設會啟用伺服器名稱指示 (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"
:系統會根據filter chain
選取伺服器憑證,而filter chain
則是以sni_host
為依據。如果沒有sni_host
,且未設定預設值,系統就找不到filter chain
。這表示系統不會傳回任何伺服器憑證,如範例用戶端要求所示。"status": 0
:連線已重設,因此沒有狀態碼。
- 如要更準確地檢查用戶端是否已啟用 SNI,請在 Apigee Ingress 前方或 Apigee Ingress 本身擷取封包,而非查看記錄。這有助於判斷用戶端是否傳送 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 表示用戶端 (來源) 將「Client Hello」訊息傳送至 Apigee Ingress (目的地)。
- 選取「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 表示用戶端 (來源) 將「Client Hello」訊息傳送至 Apigee Ingress (目的地)。
- 如要測試 Apigee 端點是否支援非 SNI 用戶端,請使用 OpenSSL 等工具傳送含有或不含 SNI 標頭的請求。al.
- 檢查是否已啟用 non-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) ---
- 上述回應顯示「no peer certificate available」(沒有可用的對等互連憑證),表示我們在指令中傳遞 -noservername 選項,因此 Apigee 路由中未啟用 SNI 用戶端。如果在使用 -noservername 標記時傳回對等互連憑證,表示已設定萬用字元路徑。
- 檢查是否已啟用 non-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
- 如果萬用字元路徑存在且已啟用 non-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 的用戶端,且未啟用 SNI 的用戶端未在 Apigee Hybrid 安裝中啟用或正確設定,請按照啟用未啟用 SNI 的用戶端文件操作,允許來自未啟用 SNI 用戶端的流量。
必須收集診斷資訊
如果按照上述操作說明後問題仍未解決,請收集下列診斷資訊,然後與 Google Cloud 客服團隊聯絡:Overrides.yaml
- 下列指令的輸出內容
kubectl -n apigee get apigeeroutes
- 針對每個列出的路徑執行下列指令:
kubectl -n apigee describe apigeeroute
- 發生問題的環境群組
- 使用下列指令取得已定義的 Apigee 路徑清單: