Se restablecen las conexiones durante el protocolo de enlace TLS para los clientes que no son SNI

Síntoma

Es posible que tu aplicación cliente experimente errores de restablecimiento de conexión, rechazo de conexión o similares durante el protocolo de enlace TLS cuando llame al extremo de Apigee.

Mensajes de error

  • Es posible que los clientes de Postman o Node.js vean mensajes de error de ECONRESET.

  • Curl puede mostrar Connection reset by peer cuando se realizan llamadas HTTPS directamente a la dirección IP de Apigee Ingress. Por ejemplo:

    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 
  • Es posible que otros clientes muestren errores diferentes. Sin embargo, el patrón sería el mismo: el cliente no puede establecer una conexión por completo durante el protocolo de enlace TLS.

Causas posibles

La puerta de enlace de entrada de Apigee Hybrid tiene habilitada la indicación de nombre del servidor (SNI) de forma predeterminada. Este problema puede ocurrir si tu cliente no tiene habilitado SNI y no hay una ruta de Apigee con comodín configurada para habilitar clientes que no sean SNI. Esto hace que no se envíe ningún certificado de servidor TLS predeterminado al cliente y se produzca un restablecimiento de TCP de entrada de Apigee.

Diagnóstico

  1. Determina si tu cliente tiene habilitado el SNI. Si ya sabes que no está habilitado para SNI, continúa con el paso 4 para validar la configuración de Apigee Hybrid.

    Revisa los registros de acceso de Apigee Ingress para detectar signos de solicitudes de clientes sin el nombre del servidor SNI y verifica si los hosts virtuales no están configurados con un certificado predeterminado para los clientes que no son SNI.

    • Obtén una lista de tus Pods apigee-ingressgateway con el siguiente comando:
      kubectl -n apigee get pods -l app=apigee-ingressgateway

      Ejemplo de resultado

      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
      
    • Obtén los registros de un pod apigee-ingressgateway.
      kubectl -n apigee logs APIGEE_INGRESSGATEWAY_POD
      Aquí, APIGEE_INGRESSGATEWAY_POD es un Pod de apigee-ingressgateway que aparece en el resultado del comando anterior.
    • Un registro de acceso puede verse de la siguiente manera:
      {
        "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
      }
      
    • Si analizas el registro anterior, puedes inferir lo siguiente:
      1. "sni_host": null: El cliente no tiene habilitada la SNI, ya que no hay un nombre de host de SNI. Por ejemplo, api-test.mydomain.com está asociado con esta solicitud.
      2. "status_details": "filter_chain_not_found" : Los certificados de servidor se seleccionan según un filter chain que se basa en el sni_host. Si no existe ningún sni_host y no se configuró ningún valor predeterminado, no se podrá encontrar el filter chain. Esto significa que no se devuelve ningún certificado de servidor, como se ve en la solicitud del cliente de ejemplo.
      3. "status": 0: No hay código de estado, ya que se restableció la conexión.
  2. En lugar de revisar los registros, una forma más precisa de verificar si un cliente tiene habilitado el SNI sería capturar paquetes delante de Apigee Ingress o en Apigee Ingress. Esto ayudará a determinar si el cliente envía el encabezado SNI para el protocolo de enlace de TLS.
    1. Para ejecutar Apigee Ingress en Google Kubernetes Engine, necesitarás SSH para el nodo que ejecuta la puerta de enlace de entrada y, luego, instalar toolbox y tcpdump.
      tcpdump -n -i any -s 0 'host IP_Address' -w FILE_NAME

      Aquí, FILE_NAME es el nombre del archivo, incluida la ruta de acceso, en el que deseas guardar el resultado de la captura de paquetes.

    2. Analiza la captura de paquetes con Wireshark o una herramienta similar.
    3. A continuación, se muestra un ejemplo de análisis de una captura de paquetes con Wireshark en Apigee Ingress. .
      • En el resultado de la captura de paquetes, el mensaje núm. 83 indica que el cliente (origen) envió un mensaje "Client Hello" a Apigee Ingress (destino). client-hello.png
      • Cuando selecciones el mensaje Client Hello y examines el Handshake Protocol: Client Hello, verás que falta la Extension: server_name. client-hello-extension.png
      • Como ejemplo, un cliente habilitado para SNI mostrará Extension: server_name en el resultado, como se muestra en el siguiente ejemplo. client-hello-extension-sni.png
      • Esto confirma que el cliente no envió server_name a Apigee Ingress.
      • Dado que no se incluye ningún server_name de SNI en el mensaje Client Hello, no se devuelve ningún certificado de servidor y Apigee Ingress cierra la conexión con un paquete RST.
  3. Para verificar si los clientes que no son SNI son compatibles, prueba un extremo de Apigee con una herramienta como OpenSSL para enviar solicitudes con el encabezado SNI o sin él.
    1. Verifica si los clientes que no son SNI están habilitados.
      openssl s_client -connect api-test.mydomain.com:443 -noservername

      Resultado de ejemplo

      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. La respuesta anterior muestra que no hay ningún certificado de par disponible, lo que significa que los clientes de SNI no están habilitados en la ruta de Apigee, ya que pasamos la opción -noservername en el comando. Si se devolvió un certificado de par cuando se usó la marca -noservername, esto indicaría que se configuró una ruta de comodín.
  4. Revisa la configuración actual de la ruta de Apigee para ver si hay una ruta comodín configurada y habilitada en el host virtual.
    1. Obtén una lista de las rutas de Apigee definidas con el siguiente comando:
      kubectl -n apigee get apigeeroutes 

      Ejemplo de resultado

      NAME                                  STATE     AGE
      myorg-hyb-dev-grp-000-33620d0         running   2d1h
      non-sni                               running   17s
      
    2. Verifica cada ruta de Apigee para detectar nombres de host que incluyan un comodín.

      Para cada ruta de Apigee, ejecuta el comando proporcionado para recuperar un array JSON de sus nombres de host definidos. Una ruta comodín se indicará con un asterisco (*) en el resultado.

      kubectl -n apigee get apigeeroute APIGEE_ROUTE_NAME

      Ejemplo de ruta myorg-hyb-dev-grp-000-33620d0:

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

      Ejemplo de resultado

      ["api-test.mydomain.com"]

      Ejemplo de ruta non-sni:

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

      Ejemplo de resultado

      ["*"]

      La ruta non-sni de ApigeeRoute es una ruta comodín, ya que contiene (*) como nombre de host.

    3. Si se configura una ruta comodín, se habilitan los clientes que no son SNI.
    4. Para la ruta de comodín, asegúrate de que la marca enableNonSniClient esté configurada como verdadera. El siguiente comando se ejecuta en la ruta comodín con el cliente non-sni.
      kubectl -n apigee get apigeeroute non-sni -o jsonpath='{.spec.enableNonSniClient}'

      Ejemplo de resultado

      true
    5. Si existe la ruta comodín y los clientes que no son SNI están habilitados, revisa la configuración del host virtual en el archivo overrides.yaml para asegurarte de que la ruta comodín aparezca en 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"]
        
    6. additionalGateways aparecerá en la ruta de Apigee definida por la configuración de tu host virtual. Usa el siguiente comando para confirmar que tu additionalGateway configurado aparece en la configuración de rutas de Apigee.
        kubectl -n apigee get apigeeroute APIGEE_ROUTE_NAME -o jsonpath='{.spec.additionalGateways}

      Por ejemplo, la ruta myorg-hyb-dev-grp-000-33620d0 debe mostrar la ruta non-sni como un additionalGateway.

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

      Ejemplo de resultado

      ["non-sni"]

    Solución

    Si los pasos de diagnóstico indican que tu cliente no tiene habilitada la SNI y los clientes que no son SNI no están habilitados o configurados correctamente en tu instalación de Apigee Hybrid, sigue la documentación para habilitar clientes que no sean SNI y permitir el tráfico de clientes que no sean SNI.

    Se debe recopilar información de diagnóstico

    Si el problema persiste incluso después de seguir las instrucciones anteriores, recopila la siguiente información de diagnóstico y, luego, comunícate con Atención al cliente de Google Cloud:
    • Overrides.yaml
    • Resultado de los siguientes comandos
      • kubectl -n apigee get apigeeroutes
      • Para cada una de las rutas indicadas, ejecuta el siguiente comando: kubectl -n apigee describe apigeeroute
    • Grupo(s) de entornos que presentan el problema