전화 음성에서 웹 자막까지 3 — Wireshark로 SIP 등록과 통화 읽기
VM 캡처와 Mac 분석의 역할, capture filter와 display filter를 익힙니다. REGISTER·인증·INVITE·SDP·ACK·BYE를 예정 실습과 설명용 예시로 읽습니다.
목차(21개 항목)
SIP 로그는 길고, 패킷 목록은 더 길어 보입니다. 처음부터 모든 필드를 읽으려 하면 금방 길을 잃습니다. 이 글에서는 한 통화의 제어 흐름을 시간순으로 찾는다는 한 가지 목표만 잡습니다.
실습 상태: 아래 캡처·등록·통화 분석은 아직 실행하지 않은 후속 실습입니다. 과거에 VM에서 UDP 5060만 대상으로 180초
tcpdump를 시작한 기록은 있지만, 그 캡처에서 REGISTER나 통화 패킷을 실제로 관찰·판독한 결과는 아직 없습니다. 아래 출력과 패킷 번호는 모두 설명용 예상 예시입니다.
시리즈 목차 #58 · 이전: Asterisk SIP 계정 #59 · 다음: RTP 패킷 분석 #61
이번 글의 한 가지 개념: 캡처와 표시는 서로 다른 필터다
Wireshark에는 이름이 비슷한 필터가 두 개 있습니다.
| 구분 | 적용 시점 | 역할 | 이 글의 예 |
|---|---|---|---|
| capture filter | 패킷을 저장하기 전 | 저장할 패킷 자체를 제한 | udp port 5060 |
| display filter | 저장한 뒤 화면에 표시할 때 | 캡처 안에서 관심 패킷만 숨기거나 표시 | sip |
Wireshark 공식 사용자 가이드는 capture filter가 libpcap 문법으로 캡처 대상을 제한하고, display filter가 이미 캡처된 패킷의 프로토콜과 필드 값을 기준으로 화면 표시를 제한한다고 설명합니다. 두 문법은 같지 않습니다. 자세한 내용은 Filtering while capturing과 Filtering Packets While Viewing에서 확인할 수 있습니다.
capture filter를 너무 좁게 잡으면 나중에 되돌릴 수 없습니다. display filter는 원본 캡처를 지우지 않으므로 언제든 바꿀 수 있습니다. 그래서 입문 실습에서는 캡처 범위를 명확히 정하되, 분석은 display filter로 반복하는 방식이 안전합니다.
왜 VM에서 캡처하고 Mac에서 분석하는가
이 프로젝트에서 Asterisk는 Ubuntu VM 안에 있고 Linphone과 Wireshark GUI는 Mac에 있습니다.
패킷은 실제로 지나가는 위치에서 잡아야 합니다. Mac의 임의 인터페이스만 선택하면 VM 내부 loopback의 127.0.0.1:60000 트래픽은 보이지 않습니다. 반면 VM의 tcpdump -i any는 VM이 보는 여러 인터페이스를 한 번에 관찰할 수 있습니다. 그 파일을 공유 디렉터리에 저장하면 Mac Wireshark로 열어 큰 화면에서 분석할 수 있습니다.
tradeoff는 있습니다. any는 편하지만 특정 인터페이스의 Ethernet 헤더와 정확한 방향을 공부하기에는 덜 명확할 수 있습니다. 인터페이스가 확인된 뒤에는 lima0, lo 등 실제 이름으로 범위를 좁히는 편이 좋습니다.
SIP 통화에서 찾을 시간순서
RFC 3261의 기본 흐름을 이 실습에 맞추면 두 단계입니다.
1. 등록
첫 401 Unauthorized는 비밀번호가 틀렸다는 최종 판정이 아니라 Digest 인증 challenge일 수 있습니다. 단말은 challenge의 nonce 등을 사용해 Authorization 값을 계산한 뒤 REGISTER를 다시 보냅니다. 실제 성공 여부는 뒤따르는 200 OK까지 봐야 판단합니다.
2. 7000으로 발신하고 종료
100 Trying, 180 Ringing, 183 Session Progress 같은 provisional response는 구성과 상태에 따라 일부만 나타날 수 있으며 고정 순서로 모두 온다고 가정하지 않습니다. 이 dialplan은 곧바로 Answer()하므로 180 Ringing도 필수가 아닙니다. RFC 3261은 ACK가 INVITE의 최종 응답을 확인하고, BYE가 이미 만들어진 세션을 종료한다고 정의합니다. 상대가 받기 전에 발신 시도를 취소할 때는 CANCEL, 성립한 세션을 끊을 때는 BYE를 사용합니다. BYE의 200 OK에 다시 ACK를 보내는 흐름은 아닙니다.
SDP에서는 무엇을 찾나
SIP 메시지 본문에 SDP(Session Description Protocol)가 있으면 미디어 조건을 찾을 수 있습니다.
| 줄 | 뜻 |
|---|---|
c=IN IP4 ... | 이 SDP가 제시하는 미디어 연결 주소 |
m=audio ... RTP/AVP 8 | 오디오를 받을 포트와 payload type 목록 |
a=rtpmap:8 PCMA/8000 | PT 8을 PCMA, 8 kHz clock으로 해석 |
SIP 5060과 RTP 포트는 다릅니다. 5060은 이 구성의 SIP 제어 포트이고, 실제 음성은 SDP로 합의된 별도 UDP 포트로 흐릅니다. 이 프로젝트의 Asterisk RTP 범위는 10000–10020이지만 상대 단말이 제시하는 포트는 별개일 수 있습니다.
실습 하나: SIP 캡처를 만들고 한 통화 흐름 찾기
이 절은 앞으로 사용자가 직접 수행할 실습입니다. 블로그 작성 과정에서는 실행하지 않았습니다. 실제 통화나 현재 캡처 세션을 임의로 시작하지 않습니다.
1단계 — 현재 VM 주소 확인
실행 위치: Mac 터미널
과거의 192.168.64.2는 당시 값입니다. 재시작 뒤 달라질 수 있으므로 현재 vzNAT 쪽 주소를 확인합니다. 127.0.0.1과 Mac의 Wi-Fi 주소를 VM 주소로 착각하지 않습니다.
2단계 — SIP만 파일로 캡처
실행 위치: Ubuntu VM의 새 터미널
| 옵션 | 의미 |
|---|---|
-n | 주소를 이름으로 바꾸지 않아 불필요한 DNS 조회를 피함 |
-i any | VM이 보는 모든 인터페이스에서 캡처 |
-s 0 | 패킷을 가능한 전체 길이로 저장 |
-w ...pcap | 화면 출력 대신 파일에 기록 |
'udp port 5060' | SIP UDP 5060만 저장하는 capture filter |
캡처가 시작된 뒤 사용자가 Linphone 등록을 갱신하고 7000으로 한 번 전화했다가 끊습니다. 그 다음 캡처 터미널에서 Ctrl+C로 종료합니다. Ctrl+C는 저장된 파일을 지우지 않고 캡처 프로세스를 정상 종료합니다.
3단계 — Mac Wireshark에서 파일 열기
Lima 공유 디렉터리를 통해 Mac 저장소의 다음 상대 경로에서 파일을 찾습니다.
Wireshark에서 파일을 연 뒤 display filter 입력창에 차례로 적용합니다.
Wireshark의 공식 SIP display filter reference에서 사용 가능한 SIP 필드를 확인할 수 있습니다. 설치 버전에 따라 필드 표기나 지원 범위가 다를 수 있으므로 필터 입력창의 자동완성도 함께 확인합니다.
4단계 — Flow Sequence로 시간순서 확인
Telephony → VoIP Calls에서 감지된 SIP 통화를 선택하고 Flow Sequence를 엽니다. Wireshark 공식 VoIP Calls Window는 이 창이 신호 메시지와 관련 RTP stream을 묶어 표시한다고 설명합니다.
설명용 예상 흐름:
실제 결과가 이 예시와 다르면 결과를 예시에 맞춰 해석하지 않습니다. 재전송, 인증 상태, dialplan, 단말 동작에 따라 메시지가 더 있거나 순서가 달라질 수 있습니다.
결과를 해석하는 질문 다섯 개
- REGISTER의 요청 URI와 Contact는 각각 무엇인가?
- 첫 401 뒤에 Authorization이 붙은 두 번째 REGISTER가 있는가?
- 최종 REGISTER 응답이 200인가?
- INVITE의 목적지가
7000인가? - INVITE/200 OK의 SDP에서 제시한 코덱과 미디어 주소·포트는 무엇인가?
이 다섯 질문에 답하면 “등록이 됐다”와 “전화가 연결됐다”를 분리할 수 있습니다. RTP 실제 품질은 아직 답하지 못합니다. 그것은 다음 글 #61의 미디어 패킷 분석 범위입니다.
흔한 오류
캡처 파일에 아무 패킷도 없다
캡처 위치와 인터페이스가 잘못됐거나, Linphone이 다른 transport를 사용할 수 있습니다. 현재 구성은 UDP 5060을 전제로 하지만 실제 단말 설정을 확인해야 합니다. sudo tcpdump -D로 VM의 인터페이스 목록을 읽고 캡처 위치를 다시 점검합니다.
capture filter 칸에 sip을 넣었다
sip은 대표적인 display filter입니다. libpcap 기반 capture filter에는 udp port 5060 같은 표현을 씁니다. Wireshark 창에서 두 입력 위치를 혼동하지 않습니다.
401을 보고 인증 실패라고 결론냈다
Digest challenge의 정상 중간 단계일 수 있습니다. 같은 Call-ID·사용자의 뒤이은 REGISTER와 최종 상태 코드를 함께 봅니다. 401이 반복되고 200이 오지 않을 때 인증 정보나 realm 문제를 의심합니다.
SIP는 성공인데 소리가 없다
INVITE → 200 → ACK는 제어 경로의 성공 증거입니다. RTP가 실제로 도착하고 코덱이 맞는지는 별도 확인이 필요합니다. SDP의 IP·포트가 도달 가능한지와 RTP stream을 봅니다.
캡처를 그대로 공유했다
SIP 캡처에는 사용자 ID, 사설 IP, Contact, Call-ID, Digest challenge·response, SDP가 포함될 수 있습니다. 비밀번호 평문이 보이지 않더라도 인증·네트워크 메타데이터가 민감합니다. 원본 pcap을 공개 저장소나 블로그 자산에 올리지 말고, 필요하면 식별자를 가린 최소 화면만 별도로 만듭니다.
단계별 과제
- capture filter와 display filter를 각각 한 문장으로 정의합니다.
- REGISTER 네 단계에서 challenge와 최종 성공 응답을 찾습니다.
- INVITE의 Request-URI에서
7000을 찾습니다. - SDP에서 IP, RTP 포트, payload type을 표에 적습니다.
- 관찰하지 못한 메시지는 “없다”고 단정하지 말고 캡처 범위와 필터부터 확인합니다.
확인 문제
udp port 5060과sip중 어느 것이 capture filter인가요?- 첫 REGISTER에 대한 401은 언제 정상 흐름일 수 있나요?
- INVITE와 200 OK만 보고 실제 음성이 정상이라고 말할 수 있나요?
- SDP의
m=audio줄에서 어떤 정보를 얻나요?
정답은 각각 “udp port 5060”, “Digest 인증 challenge일 때”, “아니다”, “미디어 종류·포트·transport profile·payload type 목록”입니다.