As ligações são repostas durante o handshake do TLS para clientes não SNI

Sintoma

A sua aplicação cliente pode ter problemas de reposição da ligação, ligação recusada ou erros semelhantes durante a negociação de TLS quando chama o ponto final do Apigee.

Mensagens de erro

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

  • O Curl pode apresentar a mensagem Connection reset by peer quando faz chamadas HTTPS diretamente para o endereço IP de entrada do Apigee. Por 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 apresentar erros diferentes. No entanto, o padrão seria o mesmo: o cliente não consegue estabelecer uma ligação completa durante o handshake TLS.

Causas possíveis

O gateway de entrada do Apigee Hybrid tem a Indicação do nome do servidor (SNI) ativada por predefinição. Este problema pode ocorrer se o seu cliente não tiver o SNI ativado e não existir uma rota Apigee com carateres universais configurada para ativar clientes sem SNI. Isto resulta no não envio de um certificado de servidor TLS predefinido para o cliente e ocorre uma reposição de TCP de entrada do Apigee.

Diagnóstico

  1. Determine se o seu cliente tem o SNI ativado. Se já souber que não está ativado, avance para o passo 4 para validar a configuração do Apigee Hybrid.

    Reveja os registos de acesso do Apigee Ingress para verificar se existem sinais de pedidos de clientes sem o nome do servidor SNI e verifique se os anfitriões virtuais não estão configurados com um certificado predefinido para clientes não SNI.

    • Aceda a 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
      
    • Obtenha os registos de um pod do apigee-ingressgateway.
      kubectl -n apigee logs APIGEE_INGRESSGATEWAY_POD
      Onde APIGEE_INGRESSGATEWAY_POD é um pod apigee-ingressgateway apresentado na saída do comando anterior.
    • Um registo de acesso pode ter o seguinte aspeto:
      {
        "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
      }
      
    • Analisando o registo anterior, pode inferir o seguinte:
      1. "sni_host": null: o cliente não tem o SNI ativado porque não existe um nome de anfitrião SNI. Por exemplo, api-test.mydomain.com está associado a este pedido.
      2. "status_details": "filter_chain_not_found" : os certificados do servidor são selecionados com base num filter chain, que se baseia no sni_host. Se não existir nenhum sni_host e não estiver configurada nenhuma predefinição, não é possível encontrar o filter chain. Isto significa que não é devolvido nenhum certificado de servidor, como se vê no pedido do cliente de exemplo.
      3. "status": 0: não existe um código de estado porque a ligação foi reposta.
  2. Em vez de rever os registos, uma forma mais precisa de verificar se um cliente tem o SNI ativado é fazer uma captura de pacotes em frente do Apigee Ingress ou no próprio Apigee Ingress. Isto ajuda a determinar se o cliente está a enviar o cabeçalho SNI para a negociação TLS.
    1. Para executar no Apigee Ingress no Google Kubernetes Engine, precisa de SSH para o 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 ficheiro, incluindo o caminho, onde quer guardar o resultado da captura de pacotes.

    2. Analise a captura de pacotes com o Wireshark ou uma ferramenta semelhante.
    3. Segue-se uma análise de exemplo de uma captura de pacotes com o Wireshark feita na entrada do Apigee. .
      • No resultado da captura de pacotes, a mensagem n.º 83 indica que o cliente (origem) enviou uma mensagem "Client Hello" para o Apigee Ingress (destino). client-hello.png
      • Quando seleciona a mensagem Client Hello e examina o Handshake Protocol: Client Hello, vê que a Extension: server_name está em falta. client-hello-extension.png
      • Por exemplo, um cliente com SNI ativado mostra Extension: server_name na saída, conforme mostrado no exemplo seguinte. client-hello-extension-sni.png
      • Isto confirma que o cliente não enviou o server_name para o Apigee Ingress.
      • Uma vez que não é incluído nenhum server_name SNI na mensagem Client Hello, não é devolvido nenhum certificado de servidor e o Apigee Ingress fecha a ligação com um pacote RST.
  3. Verifique se os clientes não SNI são suportados testando um ponto final do Apigee com uma ferramenta como o OpenSSL para enviar pedidos com ou sem o cabeçalho SNI.
    1. Verifique se os clientes não SNI estão ativados.
      openssl s_client -connect api-test.mydomain.com:443 -noservername

      Exemplo de resultado

      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 que não está disponível nenhum certificado de pares, o que significa que os clientes SNI não estão ativados na rota do Apigee, uma vez que transmitimos a opção -noservername no comando. Se foi devolvido um certificado de pares durante a utilização da flag -noservername, isto indica que está configurado um caminho de caráter universal.
  4. Reveja a configuração da rota do Apigee atual para ver se uma rota com carateres universais está configurada e ativada no anfitrião virtual.
    1. Aceda a uma lista das rotas do Apigee definidas 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 para nomes de anfitrião que incluam um caráter universal.

      Para cada rota do Apigee, execute o comando fornecido para obter uma matriz JSON dos respetivos nomes de anfitrião definidos. Um trajeto com caráter universal é indicado por um asterisco (*) no resultado.

      kubectl -n apigee get apigeeroute APIGEE_ROUTE_NAME

      Exemplo para o trajeto 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 para o trajeto non-sni:

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

      Exemplo de saída

      ["*"]

      A non-sni apigeeroute é uma rota com caráter universal, uma vez que contém (*) como nome de anfitrião.

    3. Se estiver configurada uma rota com carateres universais, os clientes não SNI são ativados.
    4. Para a rota de caráter universal, certifique-se de que a flag enableNonSniClient está definida como verdadeira. O seguinte comando é executado na rota com carateres universais com o cliente non-sni.
      kubectl -n apigee get apigeeroute non-sni -o jsonpath='{.spec.enableNonSniClient}'

      Exemplo de saída

      true
    5. Se o trajeto com carateres universais existir e os clientes sem SNI estiverem ativados, reveja a configuração do anfitrião virtual no ficheiro overrides.yaml para se certificar de que o trajeto com carateres universais está listado em 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 é apresentado na rota do Apigee definida pela configuração do anfitrião virtual. Use o seguinte comando para confirmar que o additionalGateway configurado está a ser apresentado na configuração da rota do Apigee.
        kubectl -n apigee get apigeeroute APIGEE_ROUTE_NAME -o jsonpath='{.spec.additionalGateways}

      Por exemplo, o trajeto myorg-hyb-dev-grp-000-33620d0 deve mostrar o trajeto 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 os passos de diagnóstico indicarem que o seu cliente é um cliente não ativado para SNI e os clientes não ativados para SNI não estiverem ativados ou configurados corretamente na sua instalação do Apigee Hybrid, siga a documentação ativar clientes não ativados para SNI para permitir o tráfego de clientes não ativados para SNI.

    Tem de recolher informações de diagnóstico

    Se o problema persistir mesmo depois de seguir as instruções anteriores, recolha as seguintes informações de diagnóstico e, em seguida, contacte o apoio ao cliente do Google Cloud:
    • Overrides.yaml
    • Resultado dos seguintes comandos
      • kubectl -n apigee get apigeeroutes
      • Para cada uma das rotas indicadas, execute: kubectl -n apigee describe apigeeroute
    • Grupos de ambientes que apresentam o problema