# 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를 검사·로깅·필터링 ``` 1. Squid가 서버 인증서를 먼저 peek 2. 동일 CN/SAN으로 가짜 인증서 생성 (자체 CA 서명) 3. 클라이언트에게 가짜 인증서 제시 4. 양쪽 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에서의 문제 1. **서버 인증서를 peek할 수 없음** - TLS 1.2: ServerHello → Certificate (평문) → Squid가 서버 인증서 확인 가능 - TLS 1.3: ServerHello → {EncryptedExtensions, Certificate, ...} (전부 암호화) → 볼 수 없음 2. **splice 후 재개입 불가** - 한번 splice(통과)하면 해당 연결에 대해 더 이상 개입 불가 - TLS 1.3에서는 peek 단계에서 얻을 수 있는 정보가 적어 splice/bump 결정이 부정확 3. **서버의 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 같은 전통적 프록시의 보안 검사 모델에 근본적 도전이 된다. > 기업 보안 아키텍처는 "네트워크 중간에서 본다"에서 "엔드포인트에서 본다"로 패러다임 전환이 필요하다.