앞단에 로드 밸런서가 있으면 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 인증서 체인과 신뢰 오류는 어떻게 읽어야 할까요? — 인증서 오류가 이름, 만료, 체인, 신뢰 저장소 중 어디에서 멈췄는지 더 자세히 볼 수 있어요.