Nginx에서 TLS 1.3 핸드셰이크 실패로 인한 연결 지연과 리트라이 증가 해결 가이드
문제 정의 — TLS 1.3 핸드셰이크 실패가 서비스 지연과 재시도를 증가시키는 방식
TLS 1.3은 ClientHello와 ServerHello로 1~2 RTT만에 핸드셰이크를 완료할 수 있도록 설계되었지만, key_share 불일치나 지원 그룹 미스매치 등으로 서버가 HelloRetryRequest(HRR)를 보내면 추가 왕복이 발생해 지연이 커진다. 핸드셰이크가 아예 실패하면 클라이언트나 로드밸런서가 즉시 재시도하거나 TCP 재접속을 반복해 전체 요청 지연과 오류율이 급격히 상승할 수 있다. 특히 Nginx TLS 1.3 핸드셰이크 실패로 연결 지연과 리트라이 증가 문제가 자주 관찰된다. 실무 체크리스트 예: 서버와 클라이언트의 지원 그룹과 key_share 설정을 일치시키고, TLS 라이브러리 버전을 통일하며, 로드밸런서의 재시도 정책과 타임아웃을 점검하라.
- 원인: 키 교환 파라미터의 불일치, TLS 라이브러리 간 버전 차이, 또는 클라이언트 구현의 제한으로 HRR이 발생하거나 핸드셰이크가 실패함.
- 영향: 추가 RTT로 응답 지연이 증가한다. 반복 연결과 재시도로 동시 연결 수, CPU 사용량, 포트 소모가 늘어나며, LB나 리버스 프록시는 즉시 재시도하면서 오류율과 타임아웃이 악화될 수 있다.
TLS 1.3 핸드셰이크 핵심 메커니즘과 실패 모드 요약
TLS 1.3 핸드셰이크는 ClientHello(키‑셰어와 알고리즘 제안) → ServerHello(선택한 그룹과 암호) → 키 확정의 순서로 빠르게 암호화 채널을 확립한다. 실패는 주로 클라이언트와 서버 또는 OpenSSL 구현 간 제안 불일치나 재시도 흐름에서 발생하며, 그 결과 추가 왕복(RTT)이나 연결 재시도가 늘어나 지연이 커질 수 있다. 현장에서는 Nginx TLS 1.3 핸드셰이크 실패로 연결 지연과 리트라이 증가 현상이 자주 보고된다.
- 키‑셰어 불일치: 클라이언트가 제안한 그룹을 서버가 지원하지 않으면 서버는 HelloRetryRequest(HRR)로 응답하고, 그로 인해 추가 RTT가 발생한다.
- HelloRetryRequest: HRR을 잘못 처리하거나 클라이언트가 재전송에 실패하면 지연이 늘고 재시도가 촉발된다. 실무 체크리스트: 서버 로그의 HRR 발생 여부를 확인하고, 지원하는 그룹 목록과 클라이언트의 키셰어 재전송 동작을 점검하세요.
- 0‑RTT·세션 재개: 서버가 0‑RTT를 거부하면 세션은 풀 핸드셰이크로 폴백되어 지연과 재전송이 증가한다.
- ALPN·암호 스위트 불일치: 응용 프로토콜(ALPN)이나 암호 스위트 우선순위가 맞지 않으면 연결이 거부되거나 재시도가 발생할 수 있다.
- OpenSSL/클라이언트 버그: 비표준 메시지, 타임아웃 처리 오류 또는 부적절한 복구 로직이 핸드셰이크 실패와 중복 시도를 유발할 수 있다.
문제 진단 방법 — 로그·패킷·도구로 원인 좁히기
핸드셰이크 실패로 인한 지연과 재시도가 늘어날 때는 로그 → 패킷 → 클라이언트 도구 순으로 교차 검증해 원인을 좁혀갑니다. 특히 Nginx TLS 1.3 핸드셰이크 실패로 연결 지연과 리트라이 증가가 의심되면 각 단계에서 단서를 빠짐없이 확인하세요.
- nginx error.log / ssl_error_log — "ssl handshake failure", "no shared cipher", 클라이언트 IP, 타임스탬프, session reuse 실패 같은 패턴을 찾아냅니다. access_log의 타임스탬프와 대조해 실제 지연이 시작된 시점을 확인하세요.
- 패킷 캡처 —
tcpdump로 ClientHello/ServerHello를 캡처(예:tcpdump -s 0 -w handshakes.pcap port 443 and host X)한 뒤 Wireshark로 HelloRetryRequest(추가 RTT), TLSv1.3 레코드, 선택된 키교환·암호를 점검합니다. - 클라이언트 디버그 —
openssl s_client -connect host:443 -tls1_3 -msg -debug,curl -v --tlsv1.3 --trace-ascii등으로 재현해 실패 원인(알고리즘 불일치, ALPN 미스매치(h2/http/1.1) 등)을 확인합니다. - ALPN·HRR 점검 — ServerHello에서 ALPN 선택 여부와 HelloRetryRequest 존재 유무를 반드시 확인합니다. 불필요한 HRR은 클라이언트 재시도와 추가 RTT를 유발하므로 우선排除 대상입니다.
- 각 로그·패킷의 타임스탬프를 비교해 지연 구간(첫 ClientHello → 최종 실패/성공)과 리트라이 원인을 분리한 뒤 우선순위로 대응합니다. 실무 체크리스트 예: 1) 로그에서 "no shared cipher" 확인 → 2) 패킷에서 HRR 존재 여부 확인 → 3) 클라이언트에서 TLS1.3으로 재현해 원인 규명.
Nginx·OpenSSL 구성과 패치로 해결하기 — 실무 적용 체크리스트
- 버전/패치: 운영 중인 nginx와 OpenSSL을 취약점과 버그가 수정된 최신 안정화 릴리스로 업데이트하세요. 패키지 방식이든 소스 빌드든 동일한 OpenSSL 버전을 사용하고 있는지 반드시 확인합니다.
- ssl_protocols: 우선
ssl_protocols TLSv1.2 TLSv1.3;로 설정하세요. 문제 추적을 위해 일시적으로 TLS1.3을 비활성화하려면ssl_protocols TLSv1.2;로 바꾼 뒤 동작을 검증합니다. - 키/곡선 조정:
ssl_ecdh_curve X25519:secp256r1;을 권장합니다. TLS1.3의 키쉐어 이슈가 의심되면 OpenSSL 또는 OS 레벨의 key_share 설정과 곡선 순서도 점검해보세요. - 검증 절차: 변경 사항 적용 후에는
nginx -t로 설정을 검증하고systemctl reload nginx로 반영합니다. 클라이언트 핸드셰이크 로그는openssl s_client -connect host:443 -tls1_3 -msg로 확인하세요. 실무 체크리스트 예시 — 1)nginx -t통과, 2) 재로드 후 error/access 로그에 이상 없음 확인, 3)openssl s_client로 TLS1.3 핸드셰이크 정상 확인. - 롤백/모니터링: TLS1.3을 비활성화하면 지연 지표(응답시간)와 재시도율을 면밀히 모니터링하세요. 문제 해결 후에는 캔리 배포로 점진적으로 재활성화하며 영향도를 관찰합니다. 특히 Nginx TLS 1.3 핸드셰이크 실패로 연결 지연과 리트라이 증가 같은 증상이 보이면 우선적으로 조사하세요.
운영 완화책과 관찰성 설계 — 재시도 정책, 메트릭, 알림
클라이언트 재시도는 지수 백오프와 랜덤 지터를 기본으로 하며 재시도 횟수에 상한을 두어 전체적인 연결 지연과 트래픽 스파이크를 억제합니다. 서비스 측에서는 회로 차단기를 도입해 연속 실패 임계치(예: 50% 실패 · 1분)를 설정하고, 열린 상태에서는 슬라이딩 윈도우 기반 샘플링과 점진적 반개방 복구를 사용합니다. 이러한 조합은 Nginx TLS 1.3 핸드셰이크 실패로 연결 지연과 리트라이 증가 같은 문제를 완화하는 데 특히 유용합니다.
- 핸드셰이크 메트릭: TLS 1.3 실패 카운트, 성공률, 소요시간 분포(p50/p95/p99)
- 재시도·회로 메트릭: 클라이언트 재시도 횟수, 재시도로 인한 전체 요청 비율 변화, 회로 차단기 상태(열림·닫힘·반개방)
- 탐지 규칙 예시: 최근 5분간 TLS 1.3 핸드셰이크 실패율 > 0.5%이고 재시도율이 직전 기간 대비 2배 이상 증가하면 경고(작업자/온콜)
- 지연 임계값 예시: p95 핸드셰이크 시간 > 200ms가 3분 이상 지속되면 고중요 알림
- 운영 프로세스: 캔리어/그레이드 배포(1→10→100%), 릴리스 토글로 빠른 롤백; 롤백 트리거는 치명적 알림 또는 회로 차단기 대량 발생. 안정화 체크리스트: 배포 전 헬스체크 통과, 모니터링 알람 설정, 롤백 경로 확인
문제 정의 — TLS 1.3 핸드셰이크 실패가 서비스 지연과 재시도를 증가시키는 방식
TLS 1.3은 ClientHello와 ServerHello로 1~2 RTT만에 핸드셰이크를 완료할 수 있도록 설계되었지만, key_share 불일치나 지원 그룹 미스매치 등으로 서버가 HelloRetryRequest(HRR)를 보내면 추가 왕복이 발생해 지연이 커진다. 핸드셰이크가 아예 실패하면 클라이언트나 로드밸런서가 즉시 재시도하거나 TCP 재접속을 반복해 전체 요청 지연과 오류율이 급격히 상승할 수 있다. 특히 Nginx TLS 1.3 핸드셰이크 실패로 연결 지연과 리트라이 증가 문제가 자주 관찰된다. 실무 체크리스트 예: 서버와 클라이언트의 지원 그룹과 key_share 설정을 일치시키고, TLS 라이브러리 버전을 통일하며, 로드밸런서의 재시도 정책과 타임아웃을 점검하라.
- 원인: 키 교환 파라미터의 불일치, TLS 라이브러리 간 버전 차이, 또는 클라이언트 구현의 제한으로 HRR이 발생하거나 핸드셰이크가 실패함.
- 영향: 추가 RTT로 응답 지연이 증가한다. 반복 연결과 재시도로 동시 연결 수, CPU 사용량, 포트 소모가 늘어나며, LB나 리버스 프록시는 즉시 재시도하면서 오류율과 타임아웃이 악화될 수 있다.
경험에서 배운 점
TLS 1.3 핸드셰이크 실패로 인한 연결 지연과 클라이언트 리트라이 증가는 단일 문제가 아니라 구성·인프라·모니터링이 결합되어 발생하는 경우가 많습니다. 실무에서 흔히 보이는 실수는 Nginx가 TLS 1.3을 지원하는 OpenSSL로 빌드되지 않았거나, 세션 캐시·세션 티켓·ALPN 등 TLS 관련 설정을 검증하지 않고 배포하는 것입니다. 여기에 인증서 체인·OCSP 스테이플링 문제, ALPN 불일치, 핸드셰이크 시의 CPU 급증(특히 동시 연결이 많은 상황), 그리고 부적절한 타임아웃·프록시 설정이 겹치면 클라이언트가 타임아웃 후 반복적으로 재시도하며 문제가 악화됩니다. 문제를 발견하면 섣불리 TLS를 비활성화하거나 임시 패치만 적용하지 마세요. 클라이언트→Nginx→업스트림으로 이어지는 핸드셰이크 경로를 좁히고, 재현 가능한 테스트로 원인을 규명하는 것이 중요합니다. 운영 환경에서는 로그와 캡처를 기반으로 단계적으로 대응해야 합니다.
간단 체크리스트:
• Nginx와 OpenSSL 버전 및 빌드 옵션을 확인해 실제로 TLS1.3을 지원하는지 검증하고, 배포 전 빌드 검증을 수행하세요.
• 재현 환경에서 다양한 클라이언트(브라우저·OS·라이브러리)와 부하를 적용해 문제를 반복 재현해 보세요.
• openssl s_client, curl --http2/--tlsv1_3, 패킷 캡처(tshark/wireshark)로 핸드셰이크 타임라인과 ALPN·키교환 실패 여부를 확인합니다.
• ssl_session_cache/ssl_session_tickets를 활성화해 세션 재사용을 유도하고, 필요하면 세션 타임아웃을 조정하세요.
• 인증서 체인과 OCSP 스테이플링을 점검하고, OCSP 조회 등 관련 타임아웃 설정을 검토합니다.
• ALPN 설정(h2/http/1.1)과 암호화 스위트가 클라이언트와 호환되는지 확인합니다. (특히 TLS1.3은 별도 취급 필요)
• Nginx의 worker_processes·worker_connections, accept_mutex와 TLS 관련 CPU 사용량을 모니터링하세요. 필요 시 TLS 오프로드나 하드웨어 가속을 고려합니다.
• keepalive_timeout, proxy_connect_timeout, proxy_read_timeout, proxy_next_upstream 등 타임아웃과 리트라이 정책을 조정해 클라이언트 재시도 폭주를 방지합니다.
• 핸드셰이크 실패 로그와 관련 메트릭(거절·타임아웃·CPU 등)으로 알림을 구성하고, 합성 트랜잭션으로 회귀·성능을 모니터링하세요.
• 변경은 단계적 롤아웃(A/B 또는 캔리어)으로 적용하고, 영향을 관찰하며 즉시 롤백할 준비를 갖춥니다.
댓글
댓글 쓰기