Verbindungsrücksetzungen während des TLS-Handshakes für Nicht-SNI-Clients

Symptom

Bei der Clientanwendung können während des TLS-Handshake beim Aufrufen des Apigee-Endpunkts Fehler wie „Verbindung zurückgesetzt“ oder „Verbindung abgelehnt“ auftreten.

Fehlermeldungen

  • Bei Postman- oder Node.js-Clients werden möglicherweise ECONRESET-Fehlermeldungen angezeigt.

  • Bei direkten HTTPS-Aufrufen an die Apigee Ingress-IP-Adresse kann in Curl die Meldung Connection reset by peer angezeigt werden. Beispiel:

    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 
  • Bei anderen Clients werden möglicherweise andere Fehler angezeigt. Das Muster wäre jedoch dasselbe: Der Client kann während des TLS-Handshake keine vollständige Verbindung herstellen.

Mögliche Ursachen

Das Ingress-Gateway von Apigee Hybrid ist standardmäßig für Server Name Indication (SNI) aktiviert. Dieses Problem kann auftreten, wenn Ihr Client nicht SNI-fähig ist und keine Apigee-Wildcard-Route konfiguriert ist, um Nicht-SNI-Clients zu aktivieren. In diesem Fall wird kein Standard-TLS-Serverzertifikat an den Client gesendet und es kommt zu einem TCP-Reset des Apigee-Ingress.

Diagnose

  1. Ermitteln Sie, ob Ihr Client SNI-fähig ist. Wenn Sie bereits wissen, dass SNI nicht aktiviert ist, fahren Sie mit Schritt 4 fort, um die Apigee Hybrid-Konfiguration zu validieren.

    Prüfen Sie die Apigee Ingress-Zugriffsprotokolle auf Anzeichen von Clientanfragen ohne SNI-Servernamen und prüfen Sie, ob virtuelle Hosts nicht mit einem Standardzertifikat für Nicht-SNI-Clients konfiguriert sind.

    • Rufen Sie mit dem folgenden Befehl eine Liste Ihrer apigee-ingressgateway-Pods ab:
      kubectl -n apigee get pods -l app=apigee-ingressgateway

      Beispielausgabe:

      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
      
    • Rufen Sie die Logs für einen apigee-ingressgateway-Pod ab.
      kubectl -n apigee logs APIGEE_INGRESSGATEWAY_POD
      Dabei ist APIGEE_INGRESSGATEWAY_POD ein apigee-ingressgateway-Pod, der in der Ausgabe des vorherigen Befehls aufgeführt ist.
    • Ein Zugriffslog könnte so aussehen:
      {
        "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
      }
      
    • Wenn Sie das vorherige Log analysieren, können Sie Folgendes ableiten:
      1. "sni_host": null: Der Client ist nicht SNI-fähig, da kein SNI-Hostname vorhanden ist. Beispiel: api-test.mydomain.com ist dieser Anfrage zugeordnet.
      2. "status_details": "filter_chain_not_found" : Serverzertifikate werden anhand eines filter chain ausgewählt, das auf dem sni_host basiert. Wenn keine sni_host vorhanden ist und kein Standardwert konfiguriert ist, kann die filter chain nicht gefunden werden. Das bedeutet, dass kein Serverzertifikat zurückgegeben wird, wie in der Beispiel-Clientanfrage zu sehen ist.
      3. "status": 0: Es gibt keinen Statuscode, da die Verbindung zurückgesetzt wurde.
  2. Anstatt Protokolle zu prüfen, ist es genauer, ein Paket vor Apigee Ingress oder auf Apigee Ingress selbst zu erfassen, um festzustellen, ob ein Client SNI-fähig ist. So können Sie feststellen, ob der Client den SNI-Header für den TLS-Handshake sendet.
    1. Wenn Sie Apigee Ingress in Google Kubernetes Engine ausführen möchten, benötigen Sie eine SSH-Verbindung zum Knoten, auf dem das Ingress-Gateway ausgeführt wird, und müssen toolbox und tcpdump installieren.
      tcpdump -n -i any -s 0 'host IP_Address' -w FILE_NAME

      Dabei ist FILE_NAME der Name der Datei, einschließlich des Pfads, in der die Paketaufzeichnungsausgabe gespeichert werden soll.

    2. Analysieren Sie die Paketerfassung mit Wireshark oder einem ähnlichen Tool.
    3. Hier sehen Sie eine Beispielanalyse einer Paketerfassung mit Wireshark, die auf Apigee Ingress durchgeführt wurde. .
      • In der Ausgabe der Paketerfassung gibt die Nachricht #83 an, dass der Client (Quelle) eine „Client Hello“-Nachricht an Apigee Ingress (Ziel) gesendet hat. client-hello.png
      • Wenn Sie die Nachricht Client Hello auswählen und Handshake Protocol: Client Hello untersuchen, sehen Sie, dass die Extension: server_name fehlt. client-hello-extension.png
      • Ein SNI-fähiger Client zeigt beispielsweise Extension: server_name in der Ausgabe an, wie im folgenden Beispiel zu sehen ist. client-hello-extension-sni.png
      • Das bestätigt, dass der Client den server_name nicht an Apigee Ingress gesendet hat.
      • Da in der Client Hello-Nachricht kein SNI server_name enthalten ist, wird kein Serverzertifikat zurückgegeben und Apigee Ingress schließt die Verbindung mit einem RST-Paket.
  3. Prüfen Sie, ob Nicht-SNI-Clients unterstützt werden, indem Sie einen Apigee-Endpunkt mit einem Tool wie OpenSSL testen, um Anfragen mit oder ohne SNI-Header zu senden.al.
    1. Prüfen, ob Nicht-SNI-Clients aktiviert sind
      openssl s_client -connect api-test.mydomain.com:443 -noservername

      Beispielausgabe

      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)
      ---
      
      
    2. Die obige Antwort zeigt no peer certificate available (kein Peer-Zertifikat verfügbar). Das bedeutet, dass SNI-Clients nicht innerhalb der Apigee-Route aktiviert sind, da wir die Option -noservername im Befehl übergeben haben. Wenn bei Verwendung des Flags -noservername ein Peer-Zertifikat zurückgegeben wurde, deutet dies darauf hin, dass eine Platzhalterroute konfiguriert ist.
  4. Prüfen Sie die aktuelle Apigee-Routenkonfiguration, um festzustellen, ob eine Platzhalterroute für den virtuellen Host konfiguriert und aktiviert ist.
    1. Rufen Sie mit dem folgenden Befehl eine Liste der definierten Apigee-Routen ab:
      kubectl -n apigee get apigeeroutes 

      Beispielausgabe:

      NAME                                  STATE     AGE
      myorg-hyb-dev-grp-000-33620d0         running   2d1h
      non-sni                               running   17s
      
    2. Prüfen Sie jede Apigee-Route auf Hostnamen, die einen Platzhalter enthalten.

      Führen Sie für jede Apigee-Route den angegebenen Befehl aus, um ein JSON-Array der definierten Hostnamen abzurufen. Eine Platzhalterroute wird in der Ausgabe durch ein Sternchen (*) gekennzeichnet.

      kubectl -n apigee get apigeeroute APIGEE_ROUTE_NAME

      Beispiel für eine myorg-hyb-dev-grp-000-33620d0-Route:

      kubectl -n apigee get apigeeroute myorg-hyb-dev-grp-000-33620d0 -o jsonpath='{.spec.hostnames}'

      Beispielausgabe:

      ["api-test.mydomain.com"]

      Beispiel für eine non-sni-Route:

      kubectl -n apigee get apigeeroute non-sni -o jsonpath='{.spec.hostnames}'

      Beispielausgabe:

      ["*"]

      Die non-sni-ApigeeRoute ist eine Platzhalterroute, da sie (*) als Hostnamen enthält.

    3. Wenn eine Platzhalterroute konfiguriert ist, sind Nicht-SNI-Clients aktiviert.
    4. Prüfen Sie bei der Platzhalterroute, ob das Flag enableNonSniClient auf „true“ gesetzt ist. Der folgende Befehl wird auf der Platzhalterroute mit dem non-sni-Client ausgeführt.
      kubectl -n apigee get apigeeroute non-sni -o jsonpath='{.spec.enableNonSniClient}'

      Beispielausgabe:

      true
    5. Wenn die Platzhalterroute vorhanden und Nicht-SNI-Clients aktiviert sind, prüfen Sie die Konfiguration des virtuellen Hosts in der Datei overrides.yaml, um sicherzustellen, dass die Platzhalterroute in additionalGateways aufgeführt ist.
      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"]
        
    6. Der additionalGateways wird in der Apigee-Route angezeigt, die durch die Konfiguration des virtuellen Hosts definiert ist. Verwenden Sie den folgenden Befehl, um zu bestätigen, dass Ihre konfigurierte additionalGateway in der Apigee-Routenkonfiguration angezeigt wird.
        kubectl -n apigee get apigeeroute APIGEE_ROUTE_NAME -o jsonpath='{.spec.additionalGateways}

      Beispielsweise sollte die Route myorg-hyb-dev-grp-000-33620d0 die Route non-sni als additionalGateway anzeigen.

        kubectl -n apigee get apigeeroute myorg-hyb-dev-grp-000-33620d0 -o jsonpath='{.spec.additionalGateways}'

      Beispielausgabe:

      ["non-sni"]

    Lösung

    Wenn die Diagnoseschritte darauf hindeuten, dass Ihr Client ein Nicht-SNI-Client ist und Nicht-SNI-Clients in Ihrer Apigee Hybrid-Installation nicht aktiviert oder richtig konfiguriert sind, folgen Sie der Dokumentation zum Aktivieren von Nicht-SNI-Clients, um Traffic von Nicht-SNI-Clients zuzulassen.

    Erfassen von Diagnoseinformationen erforderlich

    Wenn das Problem auch nach Befolgen der obigen Anweisungen weiterhin besteht, sammeln Sie die folgenden Diagnoseinformationen und wenden Sie sich dann an den Google Cloud Customer Care:
    • Overrides.yaml
    • Ausgabe der folgenden Befehle
      • kubectl -n apigee get apigeeroutes
      • Führen Sie für jede der angegebenen Routen Folgendes aus: kubectl -n apigee describe apigeeroute
    • Umgebungsgruppe(n), in der/denen das Problem auftritt