Heesung Yang

[명령어] tcpdump

tcpdump는 네트워크 패킷을 캡쳐할 수 있는 명령어로 여러가지 상황에서 활용할 수 있다.

  • HTTP API 통신하는 app이 실제로 어떤 내용을 주고 받는지 확인하고 싶을 때(API document가 없다거나, 디버깅 등을 하기 위해)
  • A -> B 로 메시지를 전송했는데 B 의 app 로그에는 아무것도 안남았을 때
    • 만약 A와 B가 서로 다른 회사면 서로 상대방 탓이라며 책임 떠넘기기 하는 경우가 있음
    • A는 우리는 분명 보냈다. B의 문제다. 라고 말하고 B는 우린 못받았다. A의 문제다 라면서 이야기가 끝나지 않는 상황
    • 이런 상황에서 tcpdump를 활용하면 메시지가 어디까지 전송되었는지 확인할 수 있음
~$ sudo tcpdump -nn -i eth0 net 10.20.30.0/24 and port 80

위와 같은 형태로 명령어를 사용할 수 있는데 그 의미를 해석하자면 다음과 같다.

eth0 네트워크 인터페이스를 통해 10.20.30.0/24 네트워크와 주고 받는 패킷 중 포트 넘버가 80 인 패킷을 캡쳐해라.

더 다양한 옵션은 아래에서 살펴보자.

항상 사용하는 옵션

  • -i <network interface> : 네트워크 패킷을 캡쳐할 네트워크 인터페이스 지정

    # eth0 네트워크 인터페이스의 패킷 캡쳐
    ~$ sudo tcpdump -i eth0
    
    # 모든 네트워크 인터페이스의 패킷 캡쳐
    ~$ sudo tcpdump -i any
    
  • -nn : IP, Port를 이름으로 변환하지 않고 그대로 출력한다. 변환 과정이 없으므로 패킷 덤프 시 딜레이가 없다. 항상 사용하자.

    tcpdump -nn option

    • IP -> hostname 변환하지 않는다.
    • Port -> well-known protocol 변환하지 않는다.

자주 사용하는 옵션

  • -w <file name> : 패킷 캡쳐 내용을 파일로 저장한다. 보통 wireshark GUI에서 분석을 위해 서버에서 일단 파일로 저장 후 로컬 컴퓨터로 다운로드한다. 파일 확장자는 pcap을 사용하지만 아무거나 상관없다.

    ~$ sudo tcpdump -i any port 80 -w dump.pcap
    
  • -A : packet 내용을 ASCII 로 출력한다. HTTP Header 정보 등을 터미널에서 실시간으로 확인할 때 유용하다.

    ~$ sudo tcpdump -i any port 80 -A -nn
    
    21:01:13.268676 IP 10.120.0.31.9000 > 10.120.1.111.33200: Flags [P.], seq 1:320, ack 81, win 227, options [nop,nop,TS val 554863434 ecr 553599198], length 319
    E..s%9@.?...
    x..
    x.o#(...6.p4........S.....
    !..J .@.HTTP/1.1 200 OK
    Server: nginx
    Date: Mon, 23 Aug 2021 12:00:53 GMT
    Content-Type: application/json
    Content-Length: 29
    Connection: keep-alive
    Allow: GET, HEAD, OPTIONS
    Vary: Accept-Language, Cookie
    Content-Language: en
    X-Content-Type-Options: nosniff
    Referrer-Policy: same-origin
    

가끔 사용하면 유용한 옵션

패킷 캡쳐 내용을 파일로 저장 시 Rotation 하는 방법

종종 어떤 문제의 원인 파악을 위해 패킷 캡쳐가 필요할 때가 있다. 근데 해당 문제가 잘 재현이 되지 않아 재현될 때까지 패킷 캡쳐를 해야할 때가 있다. 이런 경우, 패킷 캡쳐를 위해 tcpdump 명령어를 계속 실행해두면 디스크 용량이 꽉 찰 수도 있기 때문에 조심해야 하는데 이럴 때 활용하면 좋은 옵션이 있다.

  • -G <seconds> : 지정한 시간마다 파일을 rotation한다. -w 옵션의 파일명을 strftime 형식으로 써야하며, -w 설정을 안할경우 동일한 파일명에 덮어쓰기가 된다.
    • strftime 형식
      • %Y : 년
      • %m : 월
      • %d : 일
      • %H : 시
      • %M : 분
      • %S : 초
  • -C <file size> : 지정한 파일 사이즈마다 rotation 한다. (unit : 1,000,000 bytes)
  • -W <total number of files> : 몇 개의 pcap 파일을 생성할 지 설정. -G, -C 옵션과 함께 사용 가능하다.
  • -z <command> : 파일 Rotation 직 후 실행할 명령어 지정이 가능하다. gzip 을 이용하여 압축도 가능하다.

    -z 옵션 사용 시 gzip: trace.pcap.gz: Permission denied 라는 에러가 발생하는 경우가 있다. sudo 명령어로 tcpdump를 실행하면 tcpdump 유저/그룹으로 파일이 생성되는데, 이 파일을 압축할 권한이 현재 계정에 없기 때문이다.

    -rw-r--r-- 1 tcpdump tcpdump 10005643  8월 23 21:51 trace
    

    이 때 -Z <user account> 옵션을 이용하여 생성되는 파일의 유저/그룹을 설정할 수 있다.

    ~$ sudo tcpdump -i eth0 port 80 -nn -Z hsyang -z gzip -C 10 -w trace -W 2
    

지정한 시간마다 Rotation

# 10초마다 Rotate. 파일이 계속 생성되므로 주의!!!
~$ sudo tcpdump -nn -i eth0 -G 10 -w 'trace_%Y-%m-%d_%H:%M:%S.pcap'
trace_2021-08-23_21:30:34.pcap
trace_2021-08-23_21:30:44.pcap
trace_2021-08-23_21:30:56.pcap
trace_2021-08-23_21:31:08.pcap
...
# 10초마다 Rotate. 총 2개의 파일 생성 후 종료된다. 종료 시 아래와 같은 메시지가 출력된다.
# Maximum file limit reached: 2
~$ sudo tcpdump -nn -i eth0 -G 10 -W 2 -w 'trace_%Y-%m-%d_%H:%M:%S.pcap'

# 만약 하루에 한번 발생하는 에러를 추적하고 싶은 경우, 아래와 같이 24시간 동안의 패킷만 캡쳐하는 방법을 사용할 수 있다.
~$ sudo tcpdump -nn -i eth0 -G 3600 -W 24 -w 'trace_%Y-%m-%d_%H:%M:%S.pcap'
trace_2021-08-23_21:36:16.pcap
trace_2021-08-23_21:36:27.pcap

지정한 파일 크기마다 Rotation

# 10 MB 마다 Rotate
# -w 로 지정한 파일명 끝에 숫자가 자동으로 붙는다.
~$ sudo tcpdump -nn -i eth0 -C 10 -w trace
-rw-r--r-- 1 tcpdump tcpdump 10005643  8월 23 21:51 trace
-rw-r--r-- 1 tcpdump tcpdump 10000174  8월 23 21:51 trace1
-rw-r--r-- 1 tcpdump tcpdump 10001430  8월 23 21:51 trace2
-rw-r--r-- 1 tcpdump tcpdump 10000294  8월 23 21:51 trace3
-rw-r--r-- 1 tcpdump tcpdump 10001716  8월 23 21:51 trace4
# 10 MB 마다 Rotate
# -w 로 지정한 파일명 끝에 숫자가 자동으로 붙는다.
# 파일을 5개로 유지하며 계속 Rotate 한다.
~$ sudo tcpdump -nn -i eth0 -C 10 -W 5 -w trace

-W 옵션이 없을때와 다르게 0번부터 번호가 붙는다. 그리고 -W 옵션을 -G 옵션과 사용 할 때와는 다르게 -C 옵션과 사용 할 때는 해당 갯수만큼 파일이 생성되면 종료하지 않고 이전 파일을 덮어쓰며 계속 Rotate 한다. 아래 예를 보면 trace0~2 파일의 생성시각이 trace3,4 보다 이후인 것을 확인할 수 있는데 생성된 파일 수가 5개가 넘어가면서 이전 파일을 덮어쓴 결과다.

-rw-r--r-- 1 tcpdump tcpdump 10001994  8월 23 22:01 trace0
-rw-r--r-- 1 tcpdump tcpdump 10001920  8월 23 22:01 trace1
-rw-r--r-- 1 tcpdump tcpdump  7557120  8월 23 22:01 trace2
-rw-r--r-- 1 tcpdump tcpdump 10001492  8월 23 22:00 trace3
-rw-r--r-- 1 tcpdump tcpdump 10005576  8월 23 22:00 trace4

즉,

  • -G 10 -W 5 : 10초 간격으로 파일 생성. 파일 5개 생성 시 tcpdump 종료됨
  • -C 10 -W 5 : 10MB 마다 파일 생성. 파일 5개가 계속 Rotation -> Overwrite 되며 계속 캡쳐됨