TLS 1.3 over HTTP Tunneling via Squid — 무엇이 문제인가
배경
기업 환경에서 Squid 같은 Forward Proxy는 보안·감사·캐싱 목적으로 HTTPS 트래픽을 관찰하거나 검사한다. 그런데 TLS 1.3이 도입되면서, 기존에 프록시가 의존하던 여러 관찰 포인트가 사라졌다.
이 문서는 Squid를 통한 HTTP CONNECT 터널 위에서 TLS 1.3이 동작할 때 발생하는 문제들을 정리한다.
먼저: CONNECT 터널에서 Squid가 할 수 있는 일
Client ──CONNECT──▶ Squid ──TCP──▶ Server
(평문) │
│ 터널 수립 후:
Client ◀═══════════TLS═══════════▶ Server
│
Squid는 바이트를
그대로 릴레이만 함
CONNECT 터널이 수립되면 Squid는 기본적으로 바이트 릴레이만 한다. 하지만 Squid는 두 가지 방법으로 추가 가시성을 확보해왔다:
| 방법 | 설명 |
|---|---|
| Peek | TLS ClientHello의 SNI를 엿봐서 접속 대상 도메인 파악 |
| SslBump (MITM) | TLS를 중간에서 종단하여 복호화된 트래픽을 검사 |
TLS 1.3은 이 두 가지 모두에 심각한 영향을 미친다.
문제 1: Encrypted ClientHello (ECH)로 SNI 은닉
TLS 1.2에서
ClientHello (평문):
- SNI: www.example.com ← Squid가 읽을 수 있음
- Supported Ciphers
- ...
Squid는 peek 모드로 ClientHello의 SNI 필드를 읽어 어떤 도메인에 접속하는지 판단할 수 있었다. 이를 기반으로 URL 필터링, 도메인 기반 ACL 적용이 가능했다.
TLS 1.3 + ECH에서
ClientHello (outer, 평문):
- SNI: cloudflare-ech.com ← 실제 대상이 아닌 fronting 도메인
- ECH extension (암호화된 inner ClientHello 포함)
Inner ClientHello (암호화):
- SNI: real-target.com ← Squid가 읽을 수 없음
- TLS 1.3 자체만으로도 핸드셰이크 메시지 대부분이 암호화됨
- **ECH (Encrypted Client Hello)**가 적용되면 SNI까지 암호화
- Squid의
peek방식은 실제 접속 대상을 파악할 수 없게 됨 - 도메인 기반 ACL, URL 필터링이 무력화
문제 2: SslBump (MITM 검사)의 난이도 증가
Squid의 ssl_bump은 클라이언트-서버 사이에서 TLS를 종단하여 트래픽을 복호화·검사하는 기능이다.
TLS 1.2에서의 SslBump 동작
Client ←TLS→ Squid(가짜 인증서) ←TLS→ Server
│
복호화된 HTTP를
검사·로깅·필터링
- Squid가 서버 인증서를 먼저 peek
- 동일 CN/SAN으로 가짜 인증서 생성 (자체 CA 서명)
- 클라이언트에게 가짜 인증서 제시
- 양쪽 TLS 세션을 독립적으로 유지하며 중계
TLS 1.3에서의 문제
| 변경사항 | 영향 |
|---|---|
| 서버 인증서 암호화 | TLS 1.3에서는 Certificate 메시지가 암호화됨. Squid가 서버 인증서를 peek만으로는 볼 수 없음 → 가짜 인증서 생성 전에 full MITM이 필요 |
| PFS 필수 | RSA 키 교환 제거, (EC)DHE만 허용. 사전 공유키(pre-master secret) 기반 passive 복호화 불가능 |
| 핸드셰이크 라운드트립 감소 | 1-RTT 핸드셰이크로 서버 응답이 빨라져 프록시의 개입 타이밍이 촉박 |
| 0-RTT Early Data | 재연결 시 핸드셰이크 완료 전에 데이터 전송 가능. 프록시가 검사하기 전에 데이터가 이미 서버에 도달 |
문제 3: Peek-and-Splice의 한계
Squid의 peek-and-splice는 SslBump의 경량 버전이다:
peek: ClientHello의 SNI를 엿봄 (MITM 없이)
splice: 판단 후 해당 연결을 그대로 통과시킴 (터널링)
bump: 판단 후 해당 연결을 MITM으로 검사
TLS 1.3에서의 문제
-
서버 인증서를 peek할 수 없음
- TLS 1.2: ServerHello → Certificate (평문) → Squid가 서버 인증서 확인 가능
- TLS 1.3: ServerHello → {EncryptedExtensions, Certificate, …} (전부 암호화) → 볼 수 없음
-
splice 후 재개입 불가
- 한번 splice(통과)하면 해당 연결에 대해 더 이상 개입 불가
- TLS 1.3에서는 peek 단계에서 얻을 수 있는 정보가 적어 splice/bump 결정이 부정확
-
서버의 TLS 버전 다운그레이드 감지
- TLS 1.3은 다운그레이드 방지 메커니즘 내장
- 프록시가 중간에서 TLS 1.2로 다운그레이드하려 하면 클라이언트가 감지하고 연결 거부
문제 4: 0-RTT (Early Data) 검사 불가
[TLS 1.3 세션 재개 with 0-RTT]
Client → Server:
ClientHello + Early Data (HTTP GET /secret)
↑ 핸드셰이크 완료 전에 이미 데이터가 전송됨
- 0-RTT 데이터는 이전 세션의 PSK로 암호화됨
- Squid는 이전 세션 키를 모르므로 Early Data를 복호화할 수 없음
- 검사 없이 서버에 도달하는 데이터 경로가 생김
- 리플레이 공격 가능성도 추가 리스크
문제 5: Squid 자체의 TLS 1.3 지원 미성숙
| 이슈 | 상세 |
|---|---|
| OpenSSL 의존 | Squid의 TLS 처리는 OpenSSL에 의존. OpenSSL 버전에 따라 TLS 1.3 지원 수준이 다름 |
| ssl_bump + TLS 1.3 버그 | 다수의 알려진 버그 존재 (핸드셰이크 실패, 연결 끊김 등) |
| 설정 복잡도 | TLS 1.3 환경에서 ssl_bump을 안정적으로 동작시키려면 세밀한 설정 필요 |
| 성능 저하 | MITM 시 TLS 1.3의 (EC)DHE 연산이 RSA보다 CPU 부하가 큼 |
정리: TLS 1.3이 프록시 가시성에 미치는 영향
TLS 1.2 TLS 1.3
────────── ──────────
SNI 관찰 (peek) ✅ 가능 ⚠️ ECH 적용 시 불가
서버 인증서 peek ✅ 가능 ❌ 암호화됨
Passive 복호화 ⚠️ RSA면 가능 ❌ PFS 필수
ssl_bump (MITM) ✅ 안정적 ⚠️ 가능하나 불안정·제약 많음
0-RTT 데이터 검사 N/A ❌ 불가
다운그레이드 강제 ⚠️ 가능했음 ❌ 감지·차단됨
기업 환경에서의 대응 방안
1. 명시적 프록시 + 자체 CA 인증서 배포
- 클라이언트에 기업 CA 인증서를 설치
- ssl_bump MITM을 수행하되, TLS 1.3 관련 이슈 모니터링 필요
- ECH를 비활성화하는 정책 적용
2. DNS 기반 제어로 전환
- SNI 대신 DNS 쿼리를 관찰 (DNS-over-HTTPS 미사용 시)
- DNS 싱크홀/RPZ로 도메인 차단
- 단, DoH/DoT 사용 시 이 방법도 무력화
3. 엔드포인트 에이전트
- 프록시가 아닌 클라이언트 단에서 트래픽 검사
- TLS 종단 전의 평문 데이터에 접근 가능
- 프록시 의존도를 줄이는 방향
4. Squid 대안 검토
- TLS 1.3을 더 잘 지원하는 프록시 (예: Bumble-Bee, mitmproxy)
- 또는 클라우드 기반 SWG (Secure Web Gateway)로 전환
핵심 결론
TLS 1.3은 “프록시가 중간에서 관찰한다"는 전제 자체를 무너뜨리도록 설계되었다. HTTP CONNECT 터널 + TLS 1.3 조합은 Squid 같은 전통적 프록시의 보안 검사 모델에 근본적 도전이 된다. 기업 보안 아키텍처는 “네트워크 중간에서 본다"에서 “엔드포인트에서 본다"로 패러다임 전환이 필요하다.