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
在CentOS和Fedora上安裝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協議行的典型格式如下:
[Timestamp] [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網站。
如果您有任何疑問或反饋,請隨時發表評論。
更多Linux命令相關信息見Linux命令大全 專題頁面 http://www.hospitaldelafe.com/topicnews.aspx?tid=16