앞단에 로드 밸런서가 있으면 HTTPS도 다 같은 방식으로 지나갈 것 같죠? 사실은 암호를 어디서 푸느냐에 따라 완전히 다른 장면이 돼요.Proxy, Reverse Proxy, 그리고 Load Balancer에서는 서버 앞단이 요청을 먼저 받고 뒤쪽 서버로 넘길 수 있다는 큰 그림을 봤어요. 그리고 TLS, SSL, 인증서는 뭐가 다를까요?에서는 HTTPS가 TCP 연결 위에서 TLS 보호 통로를 만든 뒤 HTTP를 주고받는다는 감각을 잡았죠. 이번 글은 그 둘이 만나는 지점을 볼게요. 운영 설정을 보다 보면 이런 표현을 만나요.
https://example.com에 접속해요. 그런데 앞단이 HTTP path를 볼 수 있는지, 인증서를 어디에 설치해야 하는지, 오류가 어느 로그에 남는지는 달라져요.
오늘의 질문은 이거예요.
“HTTPS의 암호는 앞단에서 풀렸을까요, 아니면 뒤쪽 서버까지 그대로 갔을까요?”
여기서는 특정 제품 설정법보다 TLS 종료(termination), 재암호화(re-encryption), TLS 패스스루(passthrough) 를 장애 해석과 라우팅 관점에서 읽어요. 실제 제품은 SNI 기반 TCP 라우팅, mTLS, PROXY protocol 같은 기능을 섞어 제공할 수 있으니, 이름보다 어느 지점에서 TLS 세션이 끝나는지를 먼저 보세요.
봉투를 안내 데스크에서 열 수도, 그대로 넘길 수도 있어요
회사 안내 데스크에 잠긴 봉투가 도착했다고 해볼게요.- 안내 데스크가 열쇠를 가지고 있으면 봉투를 열어 내용을 읽고, 부서별로 다시 나눌 수 있어요.
- 안내 데스크가 열쇠를 가지고 있지 않으면 봉투 겉면만 보고 안쪽 담당자에게 그대로 넘겨야 해요.
- 안내 데스크가 봉투를 열어본 뒤, 안쪽 부서로 보낼 때 새 봉투에 다시 봉해서 보낼 수도 있어요.
핵심은 TLS가 어디서 한 번 끝났는지예요. TLS가 끝난 지점은 HTTP 메시지를 평문으로 볼 수 있고, 그래서 L7 정책을 적용할 수 있어요. 반대로 TLS를 그대로 통과시키는 지점은 HTTP path나 header를 보지 못해요.
이 그림에서 “종료”는 연결이 끊긴다는 뜻이 아니에요. 클라이언트와 앞단 사이의 TLS 세션이 앞단에서 끝난다는 뜻이에요. 그 뒤에는 앞단이 오리진과 별도의 HTTP 또는 HTTPS 연결을 만들 수 있어요.
TLS 종료는 앞단이 HTTPS를 풀어 읽는 방식이에요
TLS 종료에서는 클라이언트가 앞단과 TLS 핸드셰이크를 해요. 브라우저가 보는 인증서도 앞단이 내밀어요. 이 방식에서는 앞단이 HTTP 요청을 읽을 수 있어요. 그래서 이런 일이 가능해져요.
이건 L4와 L7 로드 밸런서에서 본 L7 장면과 이어져요. HTTPS 요청의 Host, path, header는 TLS 안쪽에 있으니, 앞단이 그것을 기준으로 라우팅하려면 보통 TLS를 앞단에서 끝내야 해요.
- 인증서를 한 곳에서 관리하기 쉬워요.
- path 기반 라우팅, 리다이렉트, WAF, 압축, 캐시 같은 L7 기능을 앞단에서 적용할 수 있어요.
- 앱은 내부 HTTP로 단순하게 받을 수 있어요.
- 앞단이
X-Forwarded-Proto: https,X-Forwarded-For같은 헤더를 붙여줄 수 있어요.
재암호화는 앞단에서 한 번 풀고, 뒤쪽으로 다시 HTTPS를 여는 방식이에요
TLS 종료라고 해서 앞단 뒤가 꼭 평문이어야 하는 건 아니에요. 앞단이 클라이언트와의 TLS를 끝낸 뒤, 오리진과 새 HTTPS 연결을 다시 만들 수도 있어요. 이걸 보통 TLS 재암호화 또는 TLS re-encryption이라고 불러요. 겉으로 보면 “끝까지 HTTPS”처럼 보이지만, 실제로는 TLS 세션이 두 개예요.
이 방식의 장점은 두 가지를 같이 얻는 거예요.
- 앞단은 HTTP 요청을 읽고 L7 정책을 적용할 수 있어요.
- 앞단과 오리진 사이도 다시 암호화할 수 있어요.
TLS 패스스루는 앞단이 암호화된 연결을 그대로 넘기는 방식이에요
TLS 패스스루에서는 앞단이 HTTPS 내용을 풀지 않아요. 클라이언트가 최종 오리진 서버와 TLS 핸드셰이크를 하고, 앞단은 암호화된 바이트 흐름을 전달하는 쪽에 가까워요. 이 장면에서는 오리진이 인증서를 내밀어요. 앞단에는 공개 인증서와 개인키가 없어도 될 수 있어요. 그래서 규정상 키를 오리진 밖에 두기 어렵거나, 앞단이 HTTP를 알 필요가 없는 TCP 서비스라면 패스스루가 잘 맞을 수 있어요. 하지만 앞단이 HTTP를 읽지 않으니 할 수 없는 일도 분명해요.
여기서 SNI가 살짝 헷갈릴 수 있어요. SNI는 TLS 핸드셰이크 초반의 ClientHello에 들어 있는 서버 이름 신호예요. 그래서 어떤 앞단은 TLS를 끝내지 않고도 SNI 값을 보고
api.example.com은 서버 A로, www.example.com은 서버 B로 보낼 수 있어요.
하지만 SNI는 HTTP path가 아니에요. api.example.com이라는 이름은 볼 수 있어도, 그 안쪽의 /v1/orders 같은 path는 TLS를 풀기 전에는 보통 볼 수 없어요.
세 방식을 한 화면에서 비교해볼게요
운영 문서에서는 이름이 조금씩 다르게 쓰일 수 있어요. 그래서 단어보다 아래 질문으로 보면 덜 흔들려요.“클라이언트의 TLS 세션이 어디서 끝났나요?”
이 표에서 “패스스루면 앱이 진짜 클라이언트 IP를 자동으로 본다”라고 생각하면 안 돼요. 앞단이 TCP를 중계하거나 NAT하면 오리진이 보는 상대 주소는 여전히 앞단일 수 있어요. 이때는 HTTP 헤더를 앞단이 붙이기 어렵기 때문에, 원래 클라이언트 주소를 전하려면 PROXY protocol 같은 별도 방식이 쓰이기도 해요.
X-Forwarded 헤더는 HTTP 요청을 읽고 수정할 수 있는 앞단에서 자주 쓰는 방식이에요. 패스스루처럼 HTTP를 열지 않는 구조에서는 그 헤더를 앞단이 자연스럽게 끼워 넣기 어렵다는 점을 같이 기억해두면 좋아요.
장애를 볼 때는 실패한 TLS가 어느 구간인지 먼저 나눠요
TLS 경계가 헷갈리면 인증서 오류나 502를 엉뚱한 곳에서 찾게 돼요. 예를 들어 사용자가 브라우저에서 인증서 이름 오류를 본다면 보통 클라이언트가 직접 본 인증서가 문제예요.
여기서 핵심은 “TLS 오류”라는 말 하나로 끝내지 않는 거예요. 같은 TLS라도 클라이언트-앞단 구간인지, 앞단-오리진 구간인지, 아니면 오리진이 직접 끝내는 패스스루 구간인지에 따라 봐야 할 로그와 인증서가 달라져요.
설정 예시는 이렇게 읽어보면 돼요
다음은 실제 제품 문법이 아니라, 읽는 감각을 보여주기 위한 예시예요.
물론 실제 제품에서는 단어가 다를 수 있어요. 그래도 읽는 순서는 같아요. 인증서가 어디 있고, HTTP 조건을 쓰는지, 오리진으로 어떤 프로토콜을 여는지를 보면 구조가 보이기 시작해요.
잘못 읽기 쉬운 함정
”끝까지 HTTPS”라는 말을 한 구간으로 생각하기
사용자 화면에서는 주소창이 계속 HTTPS예요. 하지만 내부에서는 클라이언트-앞단 TLS와 앞단-오리진 TLS가 분리될 수 있어요. 그래서 “끝까지 HTTPS”라고만 쓰인 문서를 보면, 한 TLS 세션이 끝까지 간다는 뜻인지, 구간마다 HTTPS를 쓴다는 뜻인지를 다시 확인해야 해요.TLS 종료를 하면 무조건 안전하지 않다고 보기
TLS 종료 자체가 나쁜 건 아니에요. 앞단에서 WAF, 라우팅, 캐시, 인증서 관리를 하기 위해 꼭 필요한 선택일 수 있어요. 다만 종료 지점 뒤쪽을 평문으로 둘지, 재암호화할지, 내부망 접근을 어떻게 제한할지는 별도 설계예요.패스스루면 앞단이 아무것도 못 본다고 단정하기
패스스루에서는 HTTP 내용은 못 보지만, TCP 연결 정보나 SNI 같은 일부 TLS 초반 신호는 볼 수 있어요. 그래서 “아무것도 못 본다”보다 HTTP 안쪽을 읽지 않는다고 표현하는 편이 정확해요.인증서 오류를 항상 오리진에서 찾기
TLS 종료 구조에서는 브라우저가 본 인증서가 앞단 인증서일 수 있어요. 반대로 재암호화 구조에서는 브라우저는 정상인데 앞단이 오리진 인증서를 못 믿어서 502를 만들 수도 있어요. 어떤 인증서가 누구에게 제시됐는지부터 나눠야 해요.자, 정리해볼까요?
- TLS 종료는 클라이언트와 앞단 사이의 TLS를 앞단에서 끝내고, 그 안의 HTTP 요청을 읽을 수 있게 만드는 방식이에요.
- 재암호화는 앞단에서 HTTP를 읽은 뒤, 오리진과 별도의 HTTPS 연결을 다시 여는 방식이에요.
- TLS 패스스루는 앞단이 HTTP 내용을 풀지 않고 암호화된 흐름을 오리진 쪽으로 넘기는 방식이에요.
- path, header, cookie 기반 라우팅은 보통 TLS 종료가 필요하고, SNI 기반 분기는 패스스루에서도 가능할 수 있어요.
- 인증서 오류와 502를 볼 때는 먼저 어느 TLS 구간에서 실패했는지를 나눠야 해요.
이어서 보면 좋은 글
- L4와 L7 로드 밸런서는 무엇을 보고 나눠 보낼까요? — TLS 경계가 L4/L7 판단과 어떻게 이어지는지 같이 보면 좋아요.
- X-Forwarded 헤더에서 진짜 클라이언트 IP는 어떻게 읽을까요? — TLS 종료 뒤 앱이 보는 scheme, host, client IP가 왜 달라지는지 이어서 볼 수 있어요.
- TLS 인증서 체인과 신뢰 오류는 어떻게 읽어야 할까요? — 인증서 오류가 이름, 만료, 체인, 신뢰 저장소 중 어디에서 멈췄는지 더 자세히 볼 수 있어요.