[카테고리:] 미분류

  • Wireshark SNI 분석

    title: "Wireshark가 SNI를 파싱하는 소스 코드 포인트(파일·흐름·찾는 법)"
    slug: wireshark-source-where-sni-is-parsed
    series: "URL·TLS·SNI·필터링·DPI 실전 가이드"
    author: EX Corp. Tech Team
    summary: "Wireshark가 ClientHello의 SNI를 어떻게 해석해 'tls.handshake.extensions_server_name'로 노출하는지, 소스 파일·심볼·읽는 흐름을 짚는다."
    tags: [Wireshark, TLS, SNI, Dissector, C, QUIC, HTTP3]
    reading_time: "8~10분"
    cover_image_suggestion: "TLS ClientHello의 Extensions 루프에서 server_name(0) 처리 흐름을 표시한 코드 스니펫 다이어그램"
    

    한눈에 핵심

    • 어디서 파싱하나? TLS 디섹터의 핵심은 epan/dissectors/packet-tls.c에 있다. ClientHello/ServerHello의 extensions 루프에서 확장 타입 server_name(0)(SNI)을 만나면 SNI 리스트를 파싱하고 디스플레이 필드를 채운다. (about.gitlab.com)
    • 필드 이름은? UI/필터에서 보이는 이름은 tls.handshake.extensions_server_name. Wireshark 공식 Display Filter Reference에 등록되어 있다. (Wireshark)
    • 왜 타입 0인가? SNI 확장은 IANA TLS ExtensionType 값 0으로 표준화되어 있으며, RFC 6066에 정의되어 있다. (IANA)
    • 최근 UX 변화? 2023년 머지리퀘스트에서 Info 컬럼에 SNI를 바로 노출하도록 개선됐다. 트리 확장을 덜 눌러도 된다. (about.gitlab.com)

    코드 리딩 로드맵

    1) 상위 레벨: TLS 디섹터 파일

    • 위치: epan/dissectors/packet-tls.c
      • TLS 레코드 → 핸드셰이크 디스섹션 → ClientHello/ServerHello 처리 → Extensions 루프 → 각 확장별 처리(여기서 server_name(0)) 흐름을 탄다. (about.gitlab.com)

    2) 확장 타입 및 규격 근거

    • SNI(server_name) 확장 타입은 0이며, 등록·유효 범위는 IANA 레지스트리에서 관리된다. (TLS 1.3의 어떤 메시지에서 허용되는지도 표기됨: CH, EE, CR 등) (IANA)
    • 프로토콜 동작·형식 정의는 RFC 6066에 있다(확장 데이터 구조, 서버의 빈 server_name 응답 등). (IETF Datatracker)

    3) 디스플레이 필드 등록과 필터 이름

    • Wireshark가 GUI/필터에서 노출하는 필드 키tls.handshake.extensions_server_name. 이 필드는 TLS 디섹터에서 등록되며, 공식 Display Filter Reference에 명시돼 있다(검색 키워드: Server Name). (Wireshark)

    4) Info 컬럼 표시에 대한 최근 변경

    • 2023-10 MR: “TLS: add SNI to Info column” — ClientHello 패킷의 Info 컬럼에 (SNI=example.com) 형태로 바로 보이도록 개선(일부 공통 확장도 상단 요약에 표시). 소스 변경 논의와 예시 출력이 MR 설명에 포함. (about.gitlab.com)

    5) QUIC/H3에서도 동일한 원리

    • QUIC는 TLS 1.3을 프레이밍으로 탑재하므로 Wireshark는 QUIC 초기 패킷에서 TLS ClientHello를 디섹트해 동일 필드(tls.handshake.extensions_server_name)로 SNI를 노출한다(발표 자료에서도 동일 필드로 매칭하도록 안내). (Lekensteyn)

    “grep으로 바로 찾기” 실전 가이드

    로컬에 Wireshark 소스 클론(또는 GitLab 웹 검색) 후, 아래 키워드로 엔트리 포인트를 찾는다:

    # 1) SNI 문자열이 등장하는 곳(확장 처리/필드 등록)
    git grep -n "server_name" epan/dissectors/packet-tls*.c epan/dissectors/packet-tls*.h
    
    # 2) 디스플레이 필드 키(필터 이름과 1:1로 맵핑)
    git grep -n "extensions_server_name" epan/dissectors
    
    # 3) 확장 루프(확장 타입 스위치/if)
    git grep -n "extension" epan/dissectors/packet-tls.c | head
    

    기대되는 독해 포인트

    • Extensions 루프에서 extension_type == 0(server_name) 조건 하에 서버 네임 리스트 길이/타입/이름을 읽어 프로토콜 트리에 추가하고, Info 컬럼 업데이트. (Info 컬럼 반영 개선은 2023년 MR 설명을 참고.) (about.gitlab.com)

    관련 공식 문서 / 좌표(북마크 추천)

    • Wireshark TLS 디스플레이 필터 레퍼런스: tls.handshake.extensions_server_name 필드 스펙 확인. (Wireshark)
    • Wireshark 개발자 가이드: 소스 빌드/디버깅/디섹터 구조 전반. (Wireshark)
    • TLS 디섹터 소스(패스): epan/dissectors/packet-tls.c (GitLab) — 확장 파싱의 중심. (about.gitlab.com)
    • packet-tls-utils.h (Doxygen): TLS 유틸·헬퍼 선언부(파싱 헬퍼/상수 등 확인 시 유용). (Wireshark)
    • IANA TLS ExtensionType 레지스트리: server_name(0) 근거. (IANA)
    • RFC 6066: SNI 구조와 동작 정의. (IETF Datatracker)
    • MR: Info 컬럼에 SNI 노출(2023-10): 동작 예시/개선 배경. (about.gitlab.com)

    디버깅 팁

    • 필드가 안 보이면: 캡처가 QUIC인데 디섹터가 구버전이거나, ECH 환경이라 평문 SNI가 없을 수 있다. 최신 Wireshark 사용 및 QUIC 디코드 설정 점검. (QUIC/TLS 분석 발표 슬라이드 참고) (Lekensteyn)
    • 필드명 혼동 방지: 과거 ssl.* 접두사에서 tls.*로 표준화됨. 최신 문서의 필터 키 사용. (Wireshark)

    TL;DR

    • 파일: epan/dissectors/packet-tls.c가 중심. Extensions 루프에서 server_name(0) 처리. (about.gitlab.com)
    • 필드: UI/필터는 tls.handshake.extensions_server_name. 공식 레퍼런스 확인. (Wireshark)
    • 스펙 근거: SNI는 RFC 6066, 타입 값은 IANA 레지스트리. (IETF Datatracker)
    • 품질 개선: 2023년부터 Info 컬럼에 SNI 바로 표시. (about.gitlab.com)