Redefinições de conexão durante o handshake do TLS para clientes não SNI

Sintoma

Seu aplicativo cliente pode apresentar erros de redefinição ou recusa de conexão ou semelhantes durante o handshake de TLS ao chamar o endpoint da Apigee.

Mensagens de erro

  • Os clientes do Postman ou do Node.js podem receber mensagens de erro ECONRESET.

  • O Curl pode mostrar Connection reset by peer ao fazer chamadas HTTPS diretamente para o endereço IP do Apigee Ingress. Exemplo:

    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 
  • Outros clientes podem mostrar erros diferentes. No entanto, o padrão seria o mesmo: o cliente não consegue estabelecer uma conexão completa durante o handshake TLS.

Causas possíveis

O gateway de entrada do Apigee Hybrid é ativado por padrão com a indicação de nome do servidor (SNI). Esse problema pode ocorrer se o cliente não estiver ativado para SNI e não houver uma rota curinga da Apigee configurada para ativar clientes não SNI. Isso resulta no envio de nenhum certificado de servidor TLS padrão ao cliente e em uma redefinição de TCP de entrada da Apigee.

Diagnóstico

  1. Determine se o cliente está ativado para SNI. Se você já sabe que ele não está ativado, vá para a etapa 4 para validar a configuração do Apigee híbrido.

    Analise os registros de acesso do Apigee Ingress em busca de sinais de solicitações de clientes sem o nome do servidor SNI e verifique se os hosts virtuais não estão configurados com um certificado padrão para clientes não SNI.

    • Confira uma lista dos seus pods apigee-ingressgateway com o seguinte comando:
      kubectl -n apigee get pods -l app=apigee-ingressgateway

      Exemplo de saída

      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
      
    • Acesse os registros de um pod apigee-ingressgateway.
      kubectl -n apigee logs APIGEE_INGRESSGATEWAY_POD
      em que APIGEE_INGRESSGATEWAY_POD é um pod apigee-ingressgateway listado na resposta ao comando anterior.
    • Um registro de acesso pode ter esta aparência:
      {
        "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
      }
      
    • Ao analisar o registro anterior, é possível inferir o seguinte:
      1. "sni_host": null: o cliente não está ativado para SNI porque não há um nome de host SNI. Por exemplo, api-test.mydomain.com está associado a esta solicitação.
      2. "status_details": "filter_chain_not_found" : os certificados do servidor são selecionados com base em um filter chain, que é baseado no sni_host. Se não houver sni_host e nenhum padrão estiver configurado, o filter chain não será encontrado. Isso significa que nenhum certificado de servidor é retornado, como visto no exemplo de solicitação do cliente.
      3. "status": 0: não há código de status porque a conexão foi redefinida.
  2. Em vez de analisar os registros, uma maneira mais precisa de verificar se um cliente está com o SNI ativado é fazer uma captura de pacote na frente da entrada da Apigee ou na própria entrada da Apigee. Isso ajuda a determinar se o cliente está enviando o cabeçalho SNI para o handshake de TLS.
    1. Para executar o Apigee Ingress no Google Kubernetes Engine, é necessário usar SSH no nó que executa o gateway de entrada e instalar a caixa de ferramentas e o tcpdump.
      tcpdump -n -i any -s 0 'host IP_Address' -w FILE_NAME

      Em que FILE_NAME é o nome do arquivo, incluindo o caminho, em que você quer salvar a saída da captura de pacote.

    2. Analise a captura de pacotes usando o Wireshark ou uma ferramenta semelhante.
    3. Confira um exemplo de análise de uma captura de pacote usando o Wireshark no Apigee Ingress. .
      • Na saída de captura de pacote, a mensagem nº 83 indica que o cliente (origem) enviou uma mensagem "Client Hello" para o Apigee Ingress (destino). client-hello.png
      • Quando você seleciona a mensagem Client Hello e examina o Handshake Protocol: Client Hello, percebe que a Extension: server_name está faltando. client-hello-extension.png
      • Por exemplo, um cliente ativado para SNI vai mostrar Extensão: server_name na saída, conforme mostrado no exemplo a seguir. client-hello-extension-sni.png
      • Isso confirma que o cliente não enviou o server_name para o Apigee Ingress.
      • Como nenhum server_name da SNI está incluído na mensagem Client Hello, nenhum certificado de servidor é retornado, e o Apigee Ingress fecha a conexão com um pacote RST.
  3. Verifique se os clientes não SNI são compatíveis testando um endpoint da Apigee com uma ferramenta como o OpenSSL para enviar solicitações com ou sem o cabeçalho SNI.al.
    1. Verifique se os clientes não SNI estão ativados.
      openssl s_client -connect api-test.mydomain.com:443 -noservername

      Exemplo de saída

      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. A resposta acima mostra no peer certificate available, o que significa que os clientes SNI não estão ativados na rota do Apigee, já que transmitimos a opção -noservername no comando. Se um certificado de peer for retornado ao usar a flag -noservername, isso indicará que uma rota curinga está configurada.
  4. Analise a configuração de rota atual da Apigee para verificar se uma rota curinga está configurada e ativada no host virtual.
    1. Receba uma lista das rotas definidas da Apigee com o seguinte comando:
      kubectl -n apigee get apigeeroutes 

      Exemplo de saída

      NAME                                  STATE     AGE
      myorg-hyb-dev-grp-000-33620d0         running   2d1h
      non-sni                               running   17s
      
    2. Verifique cada rota do Apigee em busca de nomes de host que incluam um caractere curinga.

      Para cada rota do Apigee, execute o comando fornecido para extrair uma matriz JSON dos nomes de host definidos. Uma rota curinga será indicada por um asterisco (*) na saída.

      kubectl -n apigee get apigeeroute APIGEE_ROUTE_NAME

      Exemplo de rota myorg-hyb-dev-grp-000-33620d0:

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

      Exemplo de saída

      ["api-test.mydomain.com"]

      Exemplo de rota non-sni:

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

      Exemplo de saída

      ["*"]

      A non-sni apigeeroute é uma rota curinga porque contém (*) como nome do host.

    3. Se uma rota curinga estiver configurada, os clientes não SNI serão ativados.
    4. Para a rota curinga, verifique se a flag enableNonSniClient está definida como "true". O comando a seguir é executado na rota curinga com o cliente non-sni.
      kubectl -n apigee get apigeeroute non-sni -o jsonpath='{.spec.enableNonSniClient}'

      Exemplo de saída

      true
    5. Se a rota curinga existir e os clientes não SNI estiverem ativados, revise a configuração do host virtual no arquivo overrides.yaml para garantir que a rota curinga esteja listada no 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. O additionalGateways vai aparecer na rota da Apigee definida pela configuração do host virtual. Use o comando a seguir para confirmar se o additionalGateway configurado está aparecendo na configuração de rota da Apigee.
        kubectl -n apigee get apigeeroute APIGEE_ROUTE_NAME -o jsonpath='{.spec.additionalGateways}

      Por exemplo, a rota myorg-hyb-dev-grp-000-33620d0 deve mostrar a rota non-sni como um additionalGateway.

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

      Exemplo de saída

      ["non-sni"]

    Resolução

    Se as etapas de diagnóstico indicarem que seu cliente não é compatível com SNI e que os clientes não SNI não estão ativados ou configurados corretamente na instalação do Apigee híbrida, siga a documentação ativar clientes não SNI para permitir o tráfego desses clientes.

    É necessário coletar informações de diagnóstico

    Se o problema persistir mesmo depois de seguir as instruções acima, reúna as seguintes informações de diagnóstico e entre em contato com o Suporte do Google Cloud:
    • Overrides.yaml
    • Saída dos seguintes comandos
      • kubectl -n apigee get apigeeroutes
      • Para cada uma das rotas declaradas, execute: kubectl -n apigee describe apigeeroute
    • Grupos de ambientes que apresentam o problema