📚 네트워크 · 패킷 분석 › 02. 포트 · 프로토콜 분석 — 62편
이전 글: 61. HTTP 요청·응답 구조 · 다음 글: 63. FTP Active·Passive 모드와 보안
참고(01. TCP/IP 구조 이해): 41. TCP 3-Way Handshake — 연결이 성립했다는 증거 — TLS Handshake는 TCP 연결 성립 뒤에 시작됨
오늘날 웹 트래픽의 대부분은 HTTPS입니다. 앞의 두 글에서 본 메서드·경로·상태코드는 HTTPS에서는 네트워크 구간에서 보이지 않습니다. 그렇다고 관제가 아무것도 볼 수 없는 것은 아닙니다.
이 경계를 정확히 알아야 "HTTPS라서 확인 불가"라고 성급하게 결론 내리거나, 반대로 "SNI가 있으니 목적지는 확실하다"고 과신하는 실수를 피할 수 있습니다. 이번 글은 TLS Handshake를 개념 수준에서 정리하고, 필드 단위 패킷 해석은 03. Wireshark 패킷 분석 시리즈로 넘깁니다.
HTTPS는 HTTP 메시지를 TLS(Transport Layer Security) 로 암호화해 전송하는 방식이며 기본 포트는 443/TCP입니다. TLS가 제공하는 것은 세 가지입니다.
| 기능 | 의미 | 담당 요소 |
|---|---|---|
| 기밀성 | 제3자가 내용을 읽지 못함 | 대칭키 암호화 (세션 키) |
| 무결성 | 전송 중 변조 탐지 | 메시지 인증 (AEAD 등) |
| 서버 인증 | 접속한 서버가 그 도메인의 주인인지 확인 | 인증서와 인증기관(CA) 서명 |
| 요소 | 설명 |
|---|---|
| ClientHello | 클라이언트가 지원하는 TLS 버전, 암호 스위트 목록, 난수, 확장(Extension)을 제시 |
| SNI (Server Name Indication) | ClientHello의 확장. 접속하려는 도메인 이름을 서버에 알림 (한 IP에 여러 사이트가 있어서 필요) |
| ServerHello | 서버가 버전·암호 스위트를 선택해 응답 |
| Certificate | 서버 인증서 (주체 도메인, 발급자, 유효기간, 공개키) |
| 키 교환 | 양쪽이 세션 키를 만들기 위한 값 교환 (현재는 주로 ECDHE) |
| Finished | Handshake 내용이 변조되지 않았음을 서로 확인 |
| 항목 | TLS 1.2 | TLS 1.3 |
|---|---|---|
| 완전한 Handshake 왕복 | 2-RTT | 1-RTT |
| 서버 인증서 전송 | 평문 (네트워크에서 보임) | 암호화 (네트워크에서 보이지 않음) |
| 키 교환 | RSA 키 전송 방식 또는 (EC)DHE | (EC)DHE만 사용 → 전방 비밀성 기본 |
| 암호 스위트 | 선택지 많음, 구형 조합 존재 | 소수의 AEAD 스위트로 정리 |
| 버전 표시 | Handshake의 버전 필드 | 호환성 때문에 기존 버전 필드는 1.2로 두고, supported_versions 확장으로 1.3 협상 |
| SNI | 평문 | 평문 (ECH 적용 시 예외, 아래 참고) |
| 정보 | 네트워크에서 보이는가 | 비고 |
|---|---|---|
| 출발지·목적지 IP, 포트 | 보임 | IP·TCP 헤더 |
| 통신량·시간·연결 빈도 | 보임 | 흐름 통계 |
| TLS 버전, 암호 스위트 | 보임 | Hello 메시지 |
| SNI (도메인) | 대부분 보임 | ECH 적용 시 실제 도메인이 숨겨질 수 있음 |
| 서버 인증서 | TLS 1.2 보임 / TLS 1.3 안 보임 | |
| URL 경로·쿼리, 메서드 | 안 보임 | HTTP 메시지 전체가 암호화 |
| 요청·응답 헤더, 쿠키, 본문 | 안 보임 | |
| 상태코드 | 안 보임 | 웹 서버 로그에서 확인 |
ECH(Encrypted Client Hello) 는 SNI를 포함한 ClientHello의 민감한 부분을 암호화하는 확장입니다. 적용되면 네트워크에 보이는 바깥쪽 ClientHello의 SNI에는 실제 목적지가 아니라 서비스 제공자(예: CDN)의 공용 이름이 보일 수 있습니다. 일부 브라우저와 CDN에서 적용이 진행 중인 단계로, 환경과 시점에 따라 적용 여부가 다릅니다. 따라서 "SNI는 항상 실제 도메인을 보여준다"고 단정하지 않습니다.
TCP 3-Way Handshake가 끝난 뒤 TLS Handshake가 이어집니다.

그림 1. 관제에서 볼 수 있는 메타데이터(SNI·버전)와 볼 수 없는 내용(URL·본문)의 경계
TLS 1.2 (ECDHE 기준, 개념도)
[클라이언트] [서버 :443]
ClientHello (버전·스위트 목록·SNI) ─────────────────────→
←─── ServerHello, Certificate(평문), ServerKeyExchange, ServerHelloDone
ClientKeyExchange, ChangeCipherSpec, Finished ─────────→
←──────────────────────────── ChangeCipherSpec, Finished
↓ (2-RTT 후)
════════════ 암호화된 HTTP 요청·응답 ════════════
TLS 1.3 (개념도)
[클라이언트] [서버 :443]
ClientHello (key_share·supported_versions·SNI) ──────→
←─── ServerHello (key_share)
[이후 암호화] EncryptedExtensions, Certificate, CertificateVerify, Finished
[암호화] Finished ───────────────────────────────────→
↓ (1-RTT 후)
════════════ 암호화된 HTTP 요청·응답 ════════════
TLS 1.3에서는 ServerHello 직후부터 암호화되므로 인증서가 네트워크에 평문으로 나타나지 않습니다. 네트워크 장비가 인증서 정보를 기록하던 방식이 TLS 1.3 환경에서는 제한되는 이유입니다. 또한 TLS 1.3 패킷에도 중간 장비 호환성을 위해 ChangeCipherSpec 메시지가 보일 수 있으나, 1.2에서와 같은 의미는 아닙니다.
실습 환경: 본인 소유 Linux VM (Rocky Linux 또는 Ubuntu). 인터페이스 이름은 ens33을 예시로 사용합니다. 실습용 TLS 서버는 VM 내부에서만 실행합니다.
도구 설치:
# Rocky Linux
sudo dnf install -y openssl tcpdump wireshark-cli
# Ubuntu
sudo apt install -y openssl tcpdump tshark
mkdir -p ~/tlslab && cd ~/tlslab
openssl req -x509 -newkey rsa:2048 -nodes -keyout key.pem -out cert.pem -days 30 -subj "/CN=lab.local"
openssl s_server -accept 8443 -cert cert.pem -key key.pem -www
openssl s_client -connect 127.0.0.1:8443 -servername lab.local -brief </dev/null
openssl s_client -connect 127.0.0.1:8443 -servername lab.local -tls1_2 -brief </dev/null
openssl s_client -connect 127.0.0.1:8443 -servername lab.local </dev/null 2>/dev/null \
| openssl x509 -noout -subject -issuer -dates
공개 웹사이트의 인증서도 같은 방법으로 확인할 수 있습니다(예: -connect example.com:443 -servername example.com).
📷 [실습 화면 삽입]
-brief출력에서 TLS 1.3과 1.2의 프로토콜·암호 스위트가 다르게 보이는 화면
VM에서 외부 HTTPS 사이트에 접속하며 캡처한 뒤, ClientHello의 SNI만 추출합니다.
sudo tcpdump -ni ens33 -c 30 -w /tmp/tls.pcap 'tcp port 443' &
curl -s -o /dev/null https://example.com
sleep 2; sudo pkill tcpdump
# (tcpdump가 권한을 낮춰 파일을 쓰는 배포판이 있어 홈 디렉터리 대신 /tmp에 저장)
tshark -r /tmp/tls.pcap -Y 'tls.handshake.type == 1' \
-T fields -e ip.src -e ip.dst -e tls.handshake.extensions_server_name
ClientHello 필드 하나하나의 해석은 03. Wireshark 패킷 분석 시리즈에서 다룹니다.
형식 예시(값은 환경마다 다름):
$ openssl s_client -connect 127.0.0.1:8443 -servername lab.local -brief </dev/null
Protocol version: TLSv1.3
Ciphersuite: TLS_AES_256_GCM_SHA384
Peer certificate: CN = lab.local
Verification error: self-signed certificate
$ ... | openssl x509 -noout -subject -issuer -dates
subject=CN = lab.local
issuer=CN = lab.local
notBefore=Sep 26 05:10:00 2026 GMT
notAfter=Oct 26 05:10:00 2026 GMT
$ tshark ... -e tls.handshake.extensions_server_name
192.168.10.20 203.0.113.10 example.com
| 확인 항목 | 읽는 법 |
|---|---|
| Protocol / Ciphersuite | 협상된 TLS 버전과 암호 스위트 |
| subject = issuer | 자체 서명 인증서 (공인 CA 발급이 아님) |
| Verification error | 클라이언트가 신뢰할 수 없는 인증서 → 운영 서비스라면 확인 대상 |
| SNI 값 | 네트워크 캡처에서 확인되는 접속 도메인 |
📷 [실습 화면 삽입] tshark로 ClientHello의 SNI가 추출된 화면
Zeek의 ssl.log, Suricata의 tls 이벤트처럼 TLS 메타데이터를 기록하는 도구는 대체로 버전·암호 스위트·SNI·인증서 정보를 남깁니다. 필드 구성 형식 예시(도구·버전에 따라 필드명이 다름):
ts=2026-09-26T14:20:31 src=192.168.10.30:51044 dst=203.0.113.10:443
version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 server_name=www.example.com
| 관찰 | 정상일 수 있는 경우 | 의심해야 하는 경우 |
|---|---|---|
| 자체 서명·만료 인증서 | 내부 관리 장비, 개발 서버 | 외부 목적지인데 자체 서명, 인증서 CN과 SNI 불일치 |
| SNI 없이 IP로 직접 TLS 연결 | 일부 애플리케이션·장비 통신 | 사용자 PC가 평판 정보 없는 외부 IP와 SNI 없이 반복 통신 |
| SSLv3·TLS 1.0/1.1 사용 | 교체되지 않은 구형 장비 | 외부 공개 서버가 구형 버전 허용 (취약 설정 점검 대상) |
| 일정 간격의 짧은 TLS 연결 반복 | 업데이트 확인, 동기화 서비스 | 정해진 주기로 같은 목적지에 소량 통신 반복 (비코닝 가능성) |
| 드문 도메인·신규 도메인 SNI | 새로 쓰기 시작한 SaaS | 조직 내 한두 단말만 접속하는 무작위 형태 도메인 |
| 443 포트인데 TLS Handshake가 없음 | — | 443을 다른 프로토콜 통로로 사용 (21편에서 다룸) |
TLS ClientHello의 구성(버전·스위트·확장 순서)을 해시로 만든 JA3·JA4 같은 클라이언트 지문도 탐지에 활용됩니다. 다만 브라우저가 확장 순서를 무작위화하는 등의 변화로 지문 방식마다 한계가 있어, 단독 근거보다는 보조 지표로 씁니다.
| 위치 | 확인 가능한 것 | 한계 |
|---|---|---|
| 방화벽·NetFlow | IP·포트·통신량·시간 | 도메인·내용 불가 |
| IDS / 네트워크 메타데이터(Zeek 등) | SNI, 버전, 스위트, (1.2) 인증서 | 내용 불가, 1.3 인증서 불가 |
| TLS 복호화 프록시 | URL·헤더·본문 | 개인정보·법적 검토 필요, 인증서 고정 앱 예외 (04. 네트워크 장비 실습 시리즈에서 다룸) |
| 웹 서버 로그 | 복호화 후의 요청줄·상태코드 | 자기 서버로 들어오는 요청만 |
| DNS 로그 | TLS 이전의 도메인 질의 | DoH 등 암호화 DNS 사용 시 누락 가능 (08편에서 다룸) |
한계와 오탐 주의
다음 글: 07. DNS 레코드와 질의 유형