증상
Apigee 엔드포인트를 호출할 때 TLS 핸드셰이크 중에 클라이언트 애플리케이션에 연결 재설정, 연결 거부 또는 유사한 오류가 발생할 수 있습니다.
오류 메시지
Postman 또는 Node.js 클라이언트에 ECONRESET 오류 메시지가 표시될 수 있습니다.
Apigee 인그레스 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의 인그레스 게이트웨이는 기본적으로 서버 이름 표시 (SNI)가 사용 설정되어 있습니다. 이 문제는 클라이언트에 SNI가 사용 설정되어 있지 않고 SNI 이외의 클라이언트를 사용 설정하도록 구성된 와일드카드 Apigee 경로가 없는 경우 발생할 수 있습니다. 이로 인해 기본 TLS 서버 인증서가 클라이언트로 전송되지 않고 Apigee 인그레스 TCP 재설정이 발생합니다.
진단
클라이언트에서 SNI가 사용 설정되어 있는지 확인합니다. SNI가 사용 설정되어 있지 않다는 것을 이미 알고 있다면 4단계로 진행하여 Apigee Hybrid 구성을 검증하세요.
SNI 서버 이름이 없는 클라이언트 요청의 징후가 있는지 Apigee 인그레스 액세스 로그를 검토하고 가상 호스트가 SNI 이외의 클라이언트의 기본 인증서로 구성되어 있지 않은지 확인합니다.
- 다음 명령어를 사용하여
apigee-ingressgateway
포드 목록을 가져옵니다.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
포드의 로그를 가져옵니다. 여기서 APIGEE_INGRESSGATEWAY_POD는 이전 명령어 출력에 나열된kubectl -n apigee logs APIGEE_INGRESSGATEWAY_POD
apigee-ingressgateway
포드입니다.- 액세스 로그는 다음과 같이 표시될 수 있습니다.
{ "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"
: 서버 인증서는sni_host
를 기반으로 하는filter chain
에 따라 선택됩니다.sni_host
가 없고 기본값이 구성되지 않은 경우filter chain
를 찾을 수 없습니다. 클라이언트 요청 예시에서 볼 수 있듯이 서버 인증서가 반환되지 않습니다."status": 0
: 연결이 재설정되었으므로 상태 코드가 없습니다.
- 로그를 검토하는 대신 클라이언트가 SNI를 사용 설정했는지 확인하는 더 정확한 방법은 Apigee 인그레스 앞이나 Apigee 인그레스 자체에서 패킷 캡처를 실행하는 것입니다. 이를 통해 클라이언트가 TLS 핸드셰이크를 위해 SNI 헤더를 전송하는지 확인할 수 있습니다.
- Google Kubernetes Engine의 Apigee Ingress에서 실행하려면 인그레스 게이트웨이를 실행하는 노드에 SSH를 연결하고 toolbox와 tcpdump를 설치해야 합니다.
tcpdump -n -i any -s 0 'host IP_Address' -w FILE_NAME
여기서 FILE_NAME은 패킷 캡처 출력을 저장할 파일의 이름(경로 포함)입니다.
- Wireshark 또는 유사한 도구를 사용하여 패킷 캡처를 분석합니다.
- 다음은 Apigee 인그레스에서 Wireshark를 사용하여 캡처한 패킷의 샘플 분석입니다.
.
- 패킷 캡처 출력에서 메시지 #83은 클라이언트 (소스)가 Apigee 인그레스 (대상)에 'Client Hello' 메시지를 보냈음을 나타냅니다.
- Client Hello 메시지를 선택하고 Handshake Protocol: Client Hello를 검사하면 Extension: server_name이 누락된 것을 확인할 수 있습니다.
- 예를 들어 SNI 지원 클라이언트는 다음 예와 같이 출력에 Extension: server_name을 표시합니다.
- 이는 클라이언트가 Apigee 인그레스에 server_name을 전송하지 않았음을 확인합니다.
- Client Hello 메시지에 SNI server_name이 포함되지 않으므로 서버 인증서가 반환되지 않고 Apigee Ingress가 RST 패킷으로 연결을 닫습니다.
- 패킷 캡처 출력에서 메시지 #83은 클라이언트 (소스)가 Apigee 인그레스 (대상)에 'Client Hello' 메시지를 보냈음을 나타냅니다.
- OpenSSL과 같은 도구로 Apigee 엔드포인트를 테스트하여 SNI 헤더가 있거나 없는 요청을 전송하여 SNI 이외의 클라이언트가 지원되는지 확인합니다.al.
- 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) ---
- 위 응답에는 사용 가능한 피어 인증서가 없음이 표시됩니다. 이는 명령에 -noservername 옵션을 전달했으므로 Apigee 경로 내에서 SNI 클라이언트가 사용 설정되지 않았음을 의미합니다. -noservername 플래그를 사용하는 동안 피어 인증서가 반환된 경우 와일드카드 경로가 구성되었음을 나타냅니다.
- 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
- 와일드카드 경로가 있고 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 Customer Care에 문의하세요.Overrides.yaml
- 다음 명령어의 출력
kubectl -n apigee get apigeeroutes
- 명시된 각 경로에 대해 다음을 실행합니다.
kubectl -n apigee describe apigeeroute
- 문제가 발생하는 환경 그룹
- 다음 명령어를 사용하여 정의된 Apigee 경로 목록을 가져옵니다.