首頁 > 軟體

Linux下抓包命令tcpdump詳解

2020-06-16 16:27:57

tcpdump是一個命令列實用程式,可用於捕獲和檢查進出系統的網路流量。 它是網路管理員中用於排除網路問題和安全測試的最常用工具。

儘管名稱如此,使用tcpdump,您也可以捕獲非TCP流量,例如UDP,ARP或ICMP。 捕獲的封包可以寫入檔案或標準輸出。 tcpdump命令最強大的功能之一是它能夠使用過濾器並僅捕獲要分析的資料。

在本文中,我們將介紹如何在Linux中使用tcpdump命令的基礎知識。

安裝tcpdump

在大多數Linux發行版和macOS上預設安裝了tcpdump。 要檢查tcpdump命令在您的系統上是否可用:

[linuxidc@linux:~/www.linuxidc.com]$ tcpdump --version

輸出應如下所示:

tcpdump version 4.9.2
libpcap version 1.8.1
OpenSSL 1.1.1  11 Sep 2018

如果您的系統上沒有tcpdump,則上面的命令將顯示“ 沒有那個檔案或目錄”。 您可以使用發行版的軟體包管理器輕鬆安裝tcpdump。

[linuxidc@linux:~/www.linuxidc.com]$ tcpdump --version
bash: /usr/sbin/tcpdump: 沒有那個檔案或目錄

Ubuntu和Debian上安裝tcpdump

$sudo apt update && sudo apt install tcpdump

CentOSFedora上安裝tcpdump

$sudo yum install tcpdump

在Arch Linux上安裝tcpdump

$sudo pacman -S tcpdump

使用tcpdump捕獲封包

tcpdump命令的常規語法如下:

tcpdump [選項] [過濾器表示式]

  • 命令選項使您可以控制命令的行為。
  • 過濾器表示式定義將捕獲哪些封包。

只有root或具有sudo特權的使用者才能執行tcpdump。 如果您嘗試以非特權使用者身份執行該命令,則會收到一條錯誤訊息:“您無權在該裝置上進行捕獲”。

tcpdump: ens33: You don't have permission to capture on that device
(socket: Operation not permitted)

最簡單的用例是不帶任何選項和過濾器的情況下呼叫tcpdump:

[linuxidc@linux:~/www.linuxidc.com]$ sudo tcpdump

輸出如下:

[sudo] linuxidc 的密碼:
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ens33, link-type EN10MB (Ethernet), capture size 262144 bytes

tcpdump將繼續捕獲封包並寫入標準輸出,直到接收到中斷信號為止。 使用Ctrl + C組合鍵傳送中斷信號並停止命令。

要獲得更詳細的輸出,請傳遞-v選項,或傳遞-vv以獲得更詳細的輸出:

[linuxidc@linux:~/www.linuxidc.com]$ sudo tcpdump -vv

您可以使用-c選項指定要捕獲的封包數量。 例如,要僅捕獲5個封包,請輸入:

[linuxidc@linux:~/www.linuxidc.com]$ sudo tcpdump -c 5
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ens33, link-type EN10MB (Ethernet), capture size 262144 bytes
21:08:14.575216 IP linux.42082 > 180.101.49.12.https: Flags [.], ack 470550152, win 30016, length 0
21:08:14.577139 IP 180.101.49.12.https > linux.42082: Flags [.], ack 1, win 64240, length 0
21:08:14.578127 IP linux.37565 > _gateway.domain: 52885+ [1au] PTR? 12.49.101.180.in-addr.arpa. (55)
21:08:14.583548 IP _gateway.domain > linux.37565: 52885 NXDomain 0/1/1 (114)
21:08:14.585411 IP linux.37565 > _gateway.domain: 52885+ PTR? 12.49.101.180.in-addr.arpa. (44)
5 packets captured
14 packets received by filter
5 packets dropped by kernel

捕獲封包後,tcpdump將停止。

如果未指定任何介面,則tcpdump使用它找到的第一個介面並轉儲通過該介面的所有封包。

使用-D選項可以列印tcpdump可以從中收集封包的所有可用網路介面的列表:

[linuxidc@linux:~/www.linuxidc.com]$ sudo tcpdump -D

對於每個介面,該命令將列印介面名稱,簡短描述以及關聯的索引(數位):

輸出:
1.ens33 [Up, Running]
2.any (Pseudo-device that captures on all interfaces) [Up, Running]
3.lo [Up, Running, Loopback]
4.bluetooth0 (Bluetooth adapter number 0)
5.nflog (Linux netfilter log (NFLOG) interface)
6.nfqueue (Linux netfilter queue (NFQUEUE) interface)
7.usbmon1 (USB bus number 1)
8.usbmon2 (USB bus number 2)

上面的輸出顯示ens3是tcpdump找到的第一個介面,並且在沒有為該命令提供介面時使用。 第二個介面any是一種特殊的裝置,可讓您捕獲所有活動的介面。

要指定要在其上捕獲流量的介面,請使用-i選項呼叫命令,後跟介面名稱或關聯的索引。 例如,要捕獲來自所有介面的所有封包,可以指定any介面:

[linuxidc@linux:~/www.linuxidc.com]$ sudo tcpdump -i any

預設情況下,tcpdump對IP地址執行反向DNS解析,並將埠號轉換為名稱。 使用-n選項禁用轉換:

[linuxidc@linux:~/www.linuxidc.com]$ sudo tcpdump -n

跳過DNS查詢可以避免生成DNS流量並使輸出更具可讀性。建議在呼叫tcpdump時使用此選項。

與在螢幕上顯示輸出不同,您可以使用重定向操作符>和>>將其重定向到一個檔案:

[linuxidc@linux:~/www.linuxidc.com]$ sudo tcpdump -n -i any > linuxidc.txt
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
^C3470 packets captured
3616 packets received by filter
0 packets dropped by kernel

您還可以使用tee命令在儲存到檔案的同時檢視資料:

[linuxidc@linux:~/www.linuxidc.com]$  sudo tcpdump -n -l | tee linuxidc.txt

上面命令中的-l選項告訴tcpdump緩衝輸出行。 不使用此選項時,生成新行時,輸出不會寫在螢幕上。

了解tcpdump輸出

tcpdump在新行上輸出每個捕獲的封包的資訊。 每行包括一個時間戳和有關該封包的資訊,具體取決於協定。

TCP協定行的典型格式如下:

1592356057 [Protocol] [Src IP].[Src Port] > [Dst IP].[Dst Port]: [Flags], [Seq], [Ack], [Win Size], [Options], [Data Length]

讓我們逐個欄位進行說明,並解釋以下內容:

21:53:20.460144 IP 192.168.182.166.57494 > 35.222.85.5.80: Flags [P.], seq 1:88, ack 1, win 29200,  options [nop,nop,TS val 1067794587 ecr 2600218930], length 87

  • 21:53:20.460144 - 捕獲的封包的時間戳為本地時間,並使用以下格式:hours:minutes:seconds.frac,其中frac是自午夜以來的幾分之一秒。
  • IP - 分組協定。 在這種情況下,IP表示Internet協定版本4(IPv4)。
  • 192.168.182.166.57494 - 源IP地址和埠,以點(.)分隔。
  • 35.222.85.5.80 - 目的IP地址和埠,以點號(.)分隔。

TCP標誌欄位。 在此範例中,[P.]表示推播確認封包,用於確認前一個封包並行送資料。 其他典型標誌欄位值如下:

  • [.] - ACK (Acknowledgment)
  • [S] - SYN (Start Connection)
  • [P] - PSH (Push Data)
  • [F] - FIN (Finish Connection)
  • [R] - RST (Reset Connection)
  • [S.] - SYN-ACK (SynAcK Packet)

 

  • seq 1:88 - 序列號在first:last表示法中。 它顯示了封包中包含的資料數量。 除了資料流中的第一個封包(其中這些數位是絕對的)以外,所有後續封包均用作相對位元組位置。 在此範例中,數位為1:88,表示此封包包含資料流的位元組1至88。 使用-S選項可列印絕對序列號。
  • ack 1 - 確認號(acknowledgment number)是此連線另一端所期望的下一個資料的序列號。
  • win 29200 - 視窗號是接收緩衝區中可用位元組的數目。
  • options [nop,nop,TS val 1067794587 ecr 2600218930] - TCP選項。 使用nop或“ no operation”填充使TCP報頭為4位元組的倍數。 TS val是TCP時間戳,而ecr表示回顯應答。 請存取IANA文件以獲取有關TCP選項的更多資訊。
  • length 87 - 有效載荷資料的長度

tcpdump過濾器

在不使用過濾器的情況下呼叫tcpdump時,它將捕獲所有流量並產生大量輸出,這使得查詢和分析目標封包變得非常困難。

過濾器是tcpdump命令最強大的功能之一。 因為它們允許您僅捕獲與表示式匹配的那些封包。 例如,在對與Web伺服器有關的問題進行故障排除時,可以使用過濾器僅獲取HTTP通訊。

tcpdump使用Berkeley封包篩選器(BPF)語法使用各種加工引數(例如協定,源IP地址和目標IP地址以及埠等)過濾捕獲的封包。

在本文中,我們將介紹一些最常見的過濾器。 有關所有可用過濾器的列表,請檢視pcap-filter聯機幫助頁。

按協定過濾

要將捕獲限制為特定協定,請將該協定指定為過濾器。 例如,要僅捕獲UDP流量,可以使用:

$sudo tcpdump -n udp

定義協定的另一種方法是使用原型限定符,後跟協定編號。 以下命令將過濾協定編號17,並產生與上述相同的結果:

$sudo tcpdump -n proto 17

有關編號的更多資訊,請檢查IP協定編號列表。

主機過濾

要僅捕獲與特定主機有關的封包,請使用主機限定符:

$sudo tcpdump -n host 192.168.1.185

主機可以是IP地址或名稱。

您還可以使用網路限定符將輸出過濾到給定的IP範圍。 例如,要僅轉儲與10.10.0.0/16相關的封包,可以使用:

$sudo tcpdump -n net 10.10

按埠過濾

若要僅將捕獲限制為來自特定埠或特定埠的封包??請使用埠限定符。 以下命令使用以下命令捕獲與SSH(埠22)服務相關的封包:

$sudo tcpdump -n port 23

portrange限定符使您能夠捕獲一系列埠中的流量:

$sudo tcpdump -n portrange 110-150

按來源和目的地過濾

您還可以使用are src,dst,src和dst以及src或dst限定符基於源或目標埠或主機篩選封包。

以下命令捕獲來自IP為192.168.1.185的主機的傳入封包:

$sudo tcpdump -n src host 192.168.1.185

要查詢從任何來源到埠80的流量,請使用:

$sudo tcpdump -n dst port 80

複合過濾器

可以使用和(&&) 或者 (||), 而不是(!)運算子組合過濾器。

例如,要捕獲來自源IP地址192.168.1.185的所有HTTP通訊,可以使用以下命令:

$sudo tcpdump -n src 192.168.1.185 and tcp port 80

您還可以使用括號來分組和建立更複雜的過濾器:

$sudo tcpdump -n 'host 192.168.1.185 and (tcp port 80 or tcp port 443)'

為避免在使用特殊字元時解析錯誤,請將過濾器括在單引號內。

這是另一個範例命令,用於從源IP地址192.168.1.185捕獲除SSH以外的所有流量:

$sudo tcpdump -n src 192.168.1.185 and not dst port 22

檢查封包

預設情況下,tcpdump僅捕獲封包頭。 但是,有時您可能需要檢查封包的內容。

tcpdump允許您以ASCII和十六進位制格式列印封包的內容。

-A選項告訴tcpdump以ASCII格式輸出每個封包,以十六進位制格式-x輸出每個封包:

$sudo tcpdump -n -A

要以十六進位制和ASCII碼顯示封包的內容,請使用-X選項:

$sudo tcpdump -n -X

讀取和寫入捕獲到檔案

tcpdump的另一個有用功能是將封包寫入檔案。 當您捕獲大量封包或要捕獲封包以供以後分析時,這非常方便。

要開始寫入檔案,請使用-w選項,後跟輸出捕獲檔案:

$sudo tcpdump -n -w data.pcap

上面的命令將捕獲的內容儲存到名為data.pcap的檔案中。 您可以根據需要命名檔案,但是使用.pcap擴充套件名(封包捕獲)是一種常見的約定。

使用-w選項時,輸出不會顯示在螢幕上。 tcpdump寫入原始封包並建立一個二進位制檔案,而常規文字編輯器無法讀取該檔案。

要檢查檔案的內容,請使用-r選項呼叫tcpdump:

$sudo tcpdump -r data.pcap

如果要在後台執行tcpdump,請在命令末尾新增與號 (&)。

也可以使用其他封包分析器工具(例如Wireshark)檢查捕獲檔案。

長時間捕獲封包時,可以啟用檔案輪換。 tcpdump允許您建立的新檔案或以指定的時間間隔或固定大小旋轉轉儲檔案。 以下命令將建立多達十個200MB檔案,分別名為file.pcap0,file.pcap1,依此類推:在覆蓋舊檔案之前。

$sudo tcpdump -n -W 5 -C 200 -w /tmp/file.pcap

生成5個檔案後,較舊的檔案將被覆蓋。

請注意,您僅應在排除故障期間執行tcpdump。

如果要在特定時間啟動tcpdump,則可以使用cronjob。 tcpdump沒有在指定時間後退出的選項。 您可以在一段時間後使用timeout命令停止tcpdump。 例如,要在1分鐘後退出,您可以使用:

$sudo timeout 60 tcpdump -n -w data.pcap

總結

tcpdump是用於分析和解決網路相關問題的命令列工具。

本文向您介紹了tcpdump用法和語法的基礎。 有關更深入的文件,請存取tcpdump網站。

如果您有任何疑問或反饋,請隨時發表評論。


IT145.com E-mail:sddin#qq.com