HTTPS / TLS / 인증서
3줄 요약
- HTTPS는 HTTP 메시지를 TLS 연결 위에 싣는 방식이고, TLS는 암호화뿐 아니라 서버 신원 검증과 무결성 보호를 함께 제공한다.
- TLS 장애는 앱 로그에 남지 않는 경우가 많아서 DNS, TCP 연결, handshake, 인증서 chain, SNI, ALPN, termination 위치를 순서대로 분리해야 한다.
- 백엔드 개발자는
curl -v, openssl s_client, LB/proxy access log, Java truststore 오류를 읽고 인프라 팀과 같은 증거로 대화할 수 있어야 한다.
핵심 정리
- TLS handshake는 client hello에서 지원 버전, cipher suite, SNI, ALPN을 제시하고 서버가 인증서와 키 교환 방식으로 응답하면서 암호화된 HTTP 세션을 만든다.
- 인증서 검증은 leaf 인증서 하나만 보는 일이 아니다. 접속 hostname이 SAN에 있는지, 중간 인증서가 빠지지 않았는지, 신뢰 가능한 root까지 이어지는지, 만료와 key usage가 맞는지 확인한다.
- SNI는 같은 IP와 port에서 여러 도메인의 인증서를 골라 주는 신호다. SNI가 빠지거나 Host/SNI가 어긋나면 기본 인증서가 내려와 특정 클라이언트만 실패할 수 있다.
- TLS termination은 암호화가 어디서 풀리는지 정하는 설계다. CDN/LB에서 종료하는지, backend까지 재암호화하는지, mTLS로 client 인증까지 하는지에 따라 로그와 책임 경계가 달라진다.
- Java/Spring 백엔드의 외부 API 호출 실패는
PKIX path building failed, hostname mismatch, 내부 CA 미등록, TLS version/cipher 정책 차이로 나타나는 경우가 많다.
헷갈리는 지점
- 브라우저에서 자물쇠가 보이면 전체 경로가 안전하다고 생각하기 쉽다.
- 핵심 판단 포인트는 client-to-edge 구간과 edge-to-app 구간의 TLS 정책, 인증서, trust boundary를 따로 확인하는 것이다.
- 인증서 만료만 모니터링하면 충분하다고 생각하기 쉽다.
- 핵심 판단 포인트는 만료일 외에도 중간 인증서 누락, 잘못된 SAN, SNI 미전달, root CA 교체, 자동 갱신 후 reload 실패를 함께 본다.
- TLS 오류를 무조건 인프라 문제로 넘기기 쉽다.
- 핵심 판단 포인트는 백엔드가 어떤 hostname으로 호출하는지, truststore에 어떤 CA가 있는지, proxy 뒤에서
https scheme을 제대로 인식하는지 확인하는 것이다.
- mTLS를 켜면 내부 보안이 자동으로 완성된다고 생각하기 쉽다.
- 핵심 판단 포인트는 인증서 발급, 배포, 폐기, 회전, revocation, client identity 매핑, 장애 시 우회 정책까지 운영 절차가 있어야 한다.
확인 질문
- TLS handshake가 앱 로그 없이 실패할 수 있는 이유는 무엇인가?
- HTTP 요청이 애플리케이션에 도달하기 전에 암호화 협상이나 인증서 검증 단계에서 끊기기 때문이다.
openssl s_client -connect host:443 -servername host에서 -servername을 넣는 이유는 무엇인가?
- SNI를 명시해 서버나 LB가 해당 hostname에 맞는 인증서를 선택하게 하기 위해서다.
- TLS termination 위치가 쿠키, redirect, 보안 판단에 영향을 주는 이유는 무엇인가?
- 앱 앞단에서 HTTPS가 종료되면 앱은 직접 TLS를 보지 못하므로
X-Forwarded-Proto 같은 신뢰 가능한 forwarded header를 기준으로 secure cookie와 redirect URL을 판단해야 한다.
- 내부 API 호출에서
PKIX path building failed가 나면 무엇을 먼저 확인해야 하는가?
- 호출 hostname, 서버 인증서 SAN, 인증서 chain, 내부 CA가 JVM truststore나 애플리케이션 truststore에 등록되어 있는지 확인한다.