Tshark: 대용량 네트워크 트래픽 분석도구

 

Wireshark는 네트워크 트래픽 분석 도구로서, 사용자가 쉽게 녹아들수 있는 UI와 풍부한 유틸리티를 갖추고 있습니다. 다만, 이러한 장점은 기껏해야 수백~수만개의 패킷 레코드를 분석하는데서 유용하지, 만약 사내, 기관 또는 학교의 전산실처럼 적게는 시간마다 수백만~수억개의 패킷이 쌓이는 환경이라면요?

 

실제로 제가 실무에서 경험해본 바로는 Wireshark에 기록되는 패킷 수가 100만개가 넘어가면서부터 프로그램이 버벅이더니 500~1000만개 정도의 패킷이 쌓일 정도면 아예 Wireshark가 멈춰버리곤 하였습니다. Wireshark에 표시해야할 패킷 정보, 메타 데이터의 양과 UI 렌더링 프로세스를 시스템 메모리가 감당 못하기 때문이었죠.

 

어찌저찌 pcap 파일이 열렸더라도, 저런 방대한 양의 레코드를 하나하나 살펴보고 GUI에서 직접 컨트롤하는 것 역시 상당히 비효율적일 것입니다. 이렇듯 GUI 상에서 사용자가 Interactive하게 처리하기 다소 불편하고 무거운 작업들이 있기 마련이고, Wireshark는 이를 대비해 좀 더 compact한 버전의 기능들을 별도의 보조 프로그램으로 제공하고 있습니다.

 

1. Wireshark의 보조 프로그램


Wireshark 설치 내역에는 대게 아래와 같은 도구들도 같이 포함됩니다.

  • tshark: 콘솔 명령어 기반의 네트워크 트래픽 분석 도구
  • capinfos: 덤프 파일의 각종 통계(ex., 패킷 수, 전체 데이터 크기, duration, bytes/sec 등)를 산출
  • mergecap: 여러 개의 pcap/pcapng 파일을 하나의 덤프 파일로 통합해주는 도구
  • dumpcap: 명령 인터페이스 기반 패킷 수집기
  • editcap: 패킷 덤프 파일의 일부 영역을 추출하는 도구
  • reordercap: pcap/pcapng 파일에 기록된 패킷을 시간(timestamp)순으로 재정렬하는 도구

 

그 중에서도 tshark에 대해 먼저 포스팅을 하고자 합니다.

 

간혹 Linux 환경에서는 tshark를 별도의 패키지로 취급하기도 하니 주의해주세요.

$ sudo apt-get install tshark

 

2. Tshark의 주요 옵션들


tshark는 터미널/콘솔을 통해 직접 패킷 수집/분석 명령어를 받습니다.

tshark 명령어의 모든 옵션은 아래 Manual에 상세하게 작성되어 있습니다. 워낙 기능들이 방대하다보니, 그 중에서 활용도가 높은 명령어들만 정리해보고자 합니다.

https://www.wireshark.org/docs/man-pages/tshark.html

 

tshark(1)

Activate a counter for SCTP chunks. In addition to the total number of SCTP packets, for each source and destination address and port combination the number of chunks of the most common types (DATA, SACK, HEARTBEAT, HEARTBEAT ACK, INIT, INIT ACK, COOKIE EC

www.wireshark.org

 

2-1. 패킷 데이터 소스(Source) 설정

tshark가 분석할 input에 해당하는 대상은 크게 로컬에 저장된 pcap/pcapng 파일 또는 특정 네트워크 인터페이스가 될 수 있습니다.

 

pcap/pcapng 파일을 파라미터로 주는 경우

$ tshark -r [input 파일명]

 

네트워크 인터페이스를 파라미터로 주는 경우

특정 네트워크 인터페이스를 통해 출입하는 패킷 데이터를 분석합니다. 정적인 패킷 데이터를 분석하던 위의 또다른 방법과는 달리, 실시간으로 전송되는 데이터를 확인할 수 있습니다.

$ tshark -i [네트워크 인터페이스명]

 

호스트에서 분석 가능한 인터페이스를 조회하려면 ifconfig, 또는 tshark -D 명령어를 이용합니다.

$ ifconfig # 또는
$ tshark -D

 

▨ 주의 ▧ : Couldn't run /usr/bin/dumpcap in child process: Permission denied

 

만약 tshark 명령어를 수행하자마자 위의 에러 메시지가 발생한다면 다음과 같이 조치합니다.

$ sudo dpkg-reconfigure wireshark-common # <Yes> 선택
$ sudo chmod +x /usr/bin/dumpcap

 

2-2. 데이터 저장

 

수집한 packet 레코드 저장

# tshark ... -w [저장할 pcap 파일명]
$ tshark -i eth0 -c 10 -w out.pcap

 

n초마다 분할 저장

가령 n=60 으로 설정하면, 수집된 패킷들이 60초 간격마다 저장됩니다.

# tshark ... -b duration:[시간 간격(초)] -w [저장할 pcap 파일명]
$ tshark -i eth0 -b duration:60 -w out.pcap

 

패킷 n개마다 분할 저장

(Windows, Mac에서만 동작합니다. Linux 패키지 버전은 아직 해당 옵션에 대한 버그가 안고쳐진 것 같네요.)

$ tshark -i eth0 -b packets:10000 -w out.pcap 

 

2-3. 패킷 분석 시간/개수 설정

 

일정 시간동안만 수집

# tshark ... -a duration:[시간(초)]
$ tshark -i eth0 -a duration:30

 

특정 개수만큼 수집

# tshark ... -c [수집할 패킷 개수]
$ tshark -r test.pcap -c 5

 

3. 패킷 세부 항목/통계 분석


앞서 살펴본 기능들은 'tcpdump같은 패킷 수집기의 기능들과 크게 다를게 없습니다. 이번에는 tshark가 제공하는 좀 더 정밀한 분석 옵션을 정리하였습니다.

 

3-1 특정 필드 정보 추출

Wireshark에서 패킷 내부 프로토콜 스택별로 필드(field) 정보를 추출하듯이, tshark로도 비슷한 작업을 수행할 수 있습니다.

 

사용자가 원하는 필드 영역만 골라 분석하고자 한다면, ‘-T fields ’와 ‘-e’ 옵션을 사용해야합니다.

  • 예시1: 두 호스트의 IP 주소 추출
# tshark ... -T fields -e [필드 식별자1] -e [필드 식별자2] ...
$ tshark -r test.pcap -T fields -e ip.src -e ip.dst

 

  • 예시2: 패킷 발생시간, 크기, 프로토콜 정보
tshark -r test.pcap -T fields -e frame.time -e frame.len -e frame.protocols

 

  • 예시3: TCP Flow 번호 및 seq/ack 추출

해당 필드가 존재하지 않는 패킷은 공백이 출력됩니다. 본 예시에서 분석하고자 하는 필드는 TCP 패킷에만 속하므로, -Y 옵션(아래 3-2에서 자세하게 설명)을 이용하여 TCP 패킷을 필터링해줍니다.

$ tshark -r test.pcap -Y "tcp" -T fields -e tcp.stream -e tcp.seq -e tcp.ack

 

그 이외에 추출하고자 하는 필드 식별자 코드를 찾고자 한다면 아래 링크를 참고해주세요.

https://www.wireshark.org/docs/dfref/

 

Wireshark · Display Filter Reference: Index

Wireshark: The world's most popular network protocol analyzer

www.wireshark.org

 

3-2 패킷 필터링

패킷 필터링 옵션에는 ‘수집용 필터’와 ‘분석용 필터’ 2가지가 존재합니다. 이 둘은 사용처와 문법이 완전히 다르니 잘 구분해야 합니다.

 

수집용 필터 옵션: -f

특정 기준을 통과하는 패킷만 수집하고자 할 때 사용하는 옵션입니다. 필터링 문법은 Tcpdump와 거의 유사합니다(Wireshark의 필터링 문법과는 많이 다릅니다!). 또한, 실시간 패킷 수집 모드(네트워크 인터페이스를 파라미터로 준 경우)에서만 사용 가능하며, Input pcap 파일을 파라미터로 주었을때는 작동하지 않습니다.

 

  • 예시1: IP 주소가 일치하는 패킷만 수집
$ tshark -i eth0 -f "host 34.158.253.218"

 

  • 예시2: TCP 패킷만 수집
$ tshark -i eth0 -f 'tcp'

 

  • 예시3: TCP port 80번을 사용하는 패킷만 수집
$ tshark -i eth0 -f "tcp port 80"

 

분석 필터: -Y

분석하고자 하는 필터 옵션을 설정하기 위해 대문자 -Y를 사용합니다. 분석 필터의 문법은 Wireshark의 필터링 문법과 동일하며, 실시간 패킷 수집 모드와 pcap 파일 읽기 모드 어디서나 사용가능합니다.

 

  • 예시1: 수신자 IP가 일치하는 패킷
$ tshark -r test.pcap -Y "ip.addr == 192.168.137.17"

 

  • 예시2: TCP 수신자 포트번호가 443인 패킷
$ tshark -r test.pcap -Y "tcp.srcport eq 443"

 

  • 예시3: HTTP request Message
$ tshark -r test.pcap -Y "http.request and !ssdp"

 

3-3 기타 통계 분석

Wireshark에서와 마찬가지로, tshark는 여러가지 통계 지표들도 산출하여 나타내주기도 합니다. 패킷 수집과정에서 발생하는 로그 출력을 비활성화하기 위해 ‘-Q’ 옵션을 사용하였습니다.

 

  • 예시1: 패킷 길이 통계
# tshark ... -z plen,tree
$ tshark -r test.pcap -Q -z plen,tree

 

  • 예시2:  Flow 리스트 조회

tcp’ 자리에 udpip 등의 프로토콜을 파라미터로 대신 넣을수 있습니다. (ex., -z conv,udp)

# tshark ... -z conv,tcp
$ tshark -r test.pcap -Q -z conv,tcp

 

  • 예시3: HTTP 트래픽 통계
# tshark ... -z http,stat
$ tshark -r test.pcap -Q -z http,stat

 

  • 예시4: Host 통계
# tshark ... -z hosts,ip
$ tshark -r test.pcap -Q -z hosts,ip

 

  • 예시5: MAC 주소별 통계
# tshark ... -z endpoints,eth
$ tshark -r test.pcap -Q -z endpoints,eth

 

4. 분석 데이터 Export


tshark의 강점은 데이터 엔지니어링에 용이하다는 점입니다. 패킷으로부터 추출한 여러 분석 데이터가 기반이 되는 데이터 파이프라인을 손쉽게 구축할 수 있습니다. tshark의 결과물을 csv, xml 등의 포맷으로 저장하기도 하며, 나아가 다른 응용 프로그램 또는 Elasticsearch와 같은 DB에 실시간으로 streaming 하는 프로세스도 구현 가능합니다.

 

CSV 파일로 내보내기

-E header=y’ 옵션은 csv 파일 최상단에 필드 헤더명을 추가하고, ‘-E separator=,’ 옵션을 통해 각 필드를 콤마(,)로 구분할 수 있게 합니다.

# tshark ... -T fields -e [필드 식별자1] -e [필드 식별자2] ... -E header=y -E separator=, > [csv 파일명]
$ tshark -r test.pcap -Y "http.request && not ssdp" -T fields -e ip.dst -e tcp.dstport -e http.host -E header=y -E separator=, > out.csv

 

다른 애플리케이션으로 내보내기

tshark의 출력을 pythonsys 라이브러리로 읽어들여 처리하는 프로세스를 만드는 것도 가능합니다.

# network_capture.py

import sys

for row in sys.stdin:
    if "Capturing on" not in row and "packets" not in row:
        entry = row.replace("\n","").split(",")
        print('Got an entry: ', entry)
$ tshark -i eth0 -Q -T fields -e _ws.col.Protocol -e frame.time_epoch -E separator=, | python network_capture.py

 

ElasticSearch로 내보내기 (7.x 버전부터는 불가능)

저는 localhost에 elasticsearch(6.8.23 버전)이 설치된 상태에서 진행하였습니다.

$ elasticsearch -d # ElasticSearch 활성화

# tshark -T ek ... > [json 파일명]
$ tshark -T ek -r test.pcap -c 100 > test.json

# curl ... -XPOST [Elastic 서버 주소]/_bulk --data-binary "@[json 파일명]"
$ curl -H "Content-Type: application/x-ndjson" -XPOST http://localhost:9200/_bulk --data-binary "@test.json"

 

Elasticsearch에 저장된 데이터를 조회해봅니다. 아래는 패킷 중 src IP가 192.168.137.17인 레코드를 추려낸 결과물을 서버로부터 응답받는 예시입니다.

$ curl -XGET 'http://localhost:9200/packets-2022-11-03/_search?q=source:"192.168.137.17"&pretty'

반응형