TLS 1.0/1.1 레거시 지원
Cheolsu Proxy는 최신 TLS 버전뿐만 아니라 레거시 TLS 1.0/1.1 클라이언트도 지원합니다. 이를 위해 TLS 버전을 자동 감지하여 적절한 TLS 라이브러리를 선택하는 하이브리드 방식을 구현했습니다.
🎯 주요 기능
- 자동 TLS 버전 감지: ClientHello에서 TLS 버전을 자동으로 감지
- 하이브리드 TLS 처리: TLS 1.0/1.1은 native-tls, TLS 1.2+는 rustls 사용
- 크로스 플랫폼 호환성: macOS, Windows에서 모두 동작
- PKCS12 인증서 지원: native-tls용 PKCS12 인증서 자동 생성
- 터널 모드: 특정 호스트의 TLS 문제 해결을 위한 직접 터널링
🔧 구현 방식
TLS 버전별 라이브러리 선택
TLS 1.0/1.1 → native-tls (OpenSSL 기반)
TLS 1.2/1.3 → rustls (순수 Rust)
특정 호스트 → 터널 모드 (직접 연결)
터널 모드 (Tunnel Mode)
일부 호스트(특히 Apple 서비스)는 엄격한 TLS 요구사항으로 인해 프록시를 통한 TLS 핸드셰이크가 실패할 수 있습니다. 이러한 경우 터널 모드를 사용하여 프록시가 TLS 처리를 우회하고 클라이언트와 서버 간의 직접적인 TCP 터널을 생성합니다.
터널 모드 대상 호스트
gateway.icloud.com
p112-contacts.icloud.com
p112-caldav.icloud.com
wps.apple.com
- 기타 Apple 서비스 도메인
터널 모드 동작 방식
- CONNECT 요청 수신: 클라이언트가 특정 호스트로 CONNECT 요청
- 터널 모드 감지: 호스트가 터널 모드 대상인지 확인
- 200 Connection Established 응답: 즉시 터널 설정 완료 응답 전송
- 직접 TCP 연결: 클라이언트와 대상 서버 간 직접 TCP 스트림 생성
- 양방향 데이터 전송:
tokio::io::copy_bidirectional로 데이터 중계
- 이벤트 로깅: 터널 시작/완료/오류 이벤트를 Tauri UI로 전송
핵심 플로우
- CONNECT 요청 수신 → 호스트 확인
- 터널 모드 확인: 대상 호스트가 터널 모드 대상인지 확인
- 처리 방식 선택:
- 터널 모드: 직접 TCP 터널 생성
- 일반 모드: TLS 버전 감지 후 적절한 핸들러 선택
- TLS 처리 (일반 모드):
- TLS 1.0/1.1:
HybridTlsHandler::handle_with_native_tls_upgraded()
- TLS 1.2+:
HybridTlsHandler::handle_with_rustls_upgraded()
- 인증서 생성: PKCS12 형식으로 native-tls용 인증서 생성
- TLS 핸드셰이크: 선택된 라이브러리로 핸드셰이크 수행
📊 아키텍처
TLS 핸드셰이크 플로우
sequenceDiagram
participant Client as TLS Client
participant Proxy as Cheolsu Proxy
participant Detector as TLS Version Detector
participant Hybrid as HybridTlsHandler
participant Rustls as rustls
participant Native as native-tls
participant Server as Target Server
Client->>Proxy: CONNECT request
Proxy->>Proxy: Check if tunnel mode required
alt Tunnel Mode (Apple services)
Proxy->>Client: 200 Connection Established
Proxy->>Server: Direct TCP connection
Proxy->>Proxy: Spawn tunnel task
Note over Proxy: copy_bidirectional()
Note over Client,Server: Direct data flow through tunnel
else Normal TLS Mode
Proxy->>Client: 200 Connection Established
Client->>Proxy: ClientHello (TLS handshake)
Proxy->>Detector: detect_tls_version(buffer)
Detector-->>Proxy: TLS version (1.0/1.1/1.2/1.3)
alt TLS 1.0 or 1.1
Proxy->>Hybrid: handle_with_native_tls_upgraded()
Hybrid->>Native: Generate PKCS12 certificate
Native-->>Hybrid: PKCS12 identity
Hybrid->>Native: TlsAcceptor.accept()
Native-->>Hybrid: TLS stream
Hybrid-->>Proxy: NativeTls stream
else TLS 1.2 or 1.3
Proxy->>Hybrid: handle_with_rustls_upgraded()
Hybrid->>Rustls: Generate rustls certificate
Rustls-->>Hybrid: ServerConfig
Hybrid->>Rustls: TlsAcceptor.accept()
Rustls-->>Hybrid: TLS stream
Hybrid-->>Proxy: Rustls stream
end
Proxy->>Client: TLS handshake complete
Note over Client,Proxy: Secure communication established
end
PKCS12 인증서 생성 플로우
flowchart TD
A[rcgen Certificate] --> B[DER format]
B --> C[OpenSSL X509]
C --> D[OpenSSL PKey]
D --> E[PKCS12 Builder]
E --> F[PKCS12 DER]
F --> G[native-tls Identity]
G --> H[TlsAcceptor]
style A fill:#e1f5fe
style G fill:#c8e6c9
style H fill:#c8e6c9
하이브리드 TLS 핸들러 구조
graph TB
subgraph "HybridTlsHandler"
A[handle_tls_connection_upgraded]
B[TlsVersionDetector]
C{Version Check}
D[handle_with_rustls_upgraded]
E[handle_with_native_tls_upgraded]
end
subgraph "Certificate Authority"
F[RcgenAuthority]
G[OpensslAuthority]
end
subgraph "TLS Libraries"
H[rustls]
I[native-tls]
end
A --> B
B --> C
C -->|TLS 1.2/1.3| D
C -->|TLS 1.0/1.1| E
D --> F
D --> H
E --> G
E --> I
style A fill:#ffecb3
style C fill:#f3e5f5
style H fill:#e8f5e8
style I fill:#e8f5e8
📁 주요 구현 파일
1. CertificateAuthority 트레이트 확장
proxyapi_v2/src/certificate_authority/mod.rs
gen_pkcs12_identity() 메서드 추가
2. PKCS12 인증서 생성
proxyapi_v2/src/certificate_authority/rcgen_authority.rs
proxyapi_v2/src/certificate_authority/openssl_authority.rs
- rcgen/OpenSSL 인증서를 PKCS12로 변환
3. 하이브리드 TLS 핸들러
proxyapi_v2/src/hybrid_tls_handler.rs
- TLS 버전 감지 및 적절한 핸들러 선택
- Upgraded 스트림 완벽 지원
4. 프록시 통합
proxyapi_v2/src/proxy/internal.rs
- 기존 rustls 로직과 하이브리드 핸들러 통합
🚀 사용 방법
빌드
cargo build --package proxyapi_v2 \
--features "native-tls-client,rcgen-ca,openssl-ca"
테스트
cargo run --example tls_hybrid_test \
--features "native-tls-client,rcgen-ca,openssl-ca" \
--package proxyapi_v2
📊 테스트 결과
📋 TLS 버전 감지 테스트:
--------------------------
TLS 1.0 → "TLS 1.0" (native-tls) ✅
TLS 1.1 → "TLS 1.1" (native-tls) ✅
TLS 1.2 → "TLS 1.2" (rustls) ✅
TLS 1.3 → "TLS 1.3" (rustls) ✅
🔍 기술적 세부사항
PKCS12 변환 플로우
rcgen Certificate (DER)
→ openssl::x509::X509
→ openssl::pkcs12::Pkcs12
→ native_tls::Identity
TLS 버전 감지
// TLS 레코드 헤더에서 버전 추출
let version_bytes = [buffer[3], buffer[4]];
match version_bytes {
[0x03, 0x01] => Some(TlsVersion::Tls10),
[0x03, 0x02] => Some(TlsVersion::Tls11),
[0x03, 0x03] => Some(TlsVersion::Tls12),
[0x03, 0x04] => Some(TlsVersion::Tls13),
_ => None,
}
🛡️ 보안 고려사항
레거시 TLS 지원의 위험성
- TLS 1.0/1.1은 보안상 취약점이 있음
- RC4, MD5, SHA-1 등 취약한 암호화 알고리즘 사용
- BEAST, POODLE 등의 공격에 취약
권장사항
- 최신 TLS 버전 사용: 가능한 한 TLS 1.2 이상 사용
- 레거시 클라이언트 업그레이드: 오래된 클라이언트 업데이트 권장
- 보안 정책 수립: 레거시 TLS 사용에 대한 명확한 정책 수립
🔧 문제 해결
터널 모드 관련 문제
증상: Apple 서비스나 특정 호스트에 연결 실패
해결방법:
- 터널 모드 대상 호스트 목록 확인
- 터널 이벤트 로그 확인 (
🚇 [TUNNEL-EVENT] 로그)
tunnel_event_sender가 올바르게 설정되었는지 확인
- 터널 모드 타임아웃 설정 확인 (기본 5분)
TLS 핸드셰이크 실패
증상: TLS 1.0/1.1 클라이언트가 연결되지 않음
해결방법:
- native-tls 기능이 활성화되었는지 확인
- OpenSSL 라이브러리가 설치되었는지 확인
- PKCS12 인증서 생성이 성공했는지 확인
인증서 오류
증상: "certificate verify failed" 오류
해결방법:
- CA 인증서가 올바르게 설치되었는지 확인
- 인증서 체인 검증 로직 확인
- 시스템 시간이 올바른지 확인
성능 문제
증상: TLS 핸드셰이크가 느림
해결방법:
- 인증서 생성 캐싱 구현
- 연결 풀링 최적화
- 메모리 사용량 모니터링
📈 향후 개선 계획
성능 최적화
보안 강화
모니터링