tcpdump抓包使用小結

前言

tcpdump 是一個很經常使用的網絡包分析工具,能夠用來顯示經過網絡傳輸到本系統的 TCP/IP 以及其餘網絡的數據包。tcpdump 使用 libpcap 庫來抓取網絡報,這個庫在幾乎在全部的 Linux/Unix 中都有。在 Windows 中咱們一般會使用 Wireshark 進行圖形化操做至關便捷,然而在 Linux 環境中如何巧妙應用 tcpdump 的命令來操做提高效率就顯得尤其重要。在本文中,咱們將會經過一些實例來演示如何使用 tcpdump 命令。html

tcpdump 是一款靈活、功能強大的抓包工具,能有效地幫助排查網絡故障問題。

更新歷史

2018年12月11日 - 初稿linux

閱讀原文 - https://wsgzao.github.io/post...nginx

擴展閱讀git

Wireshark - https://www.wireshark.org/#do...
tcpdump - http://www.tcpdump.org/
在 Linux 命令行中使用 tcpdump 抓包 - https://linux.cn/article-1019...github


tcpdump簡介

tcpdump, a powerful command-line packet analyzer; and libpcap, a portable C/C++ library for network traffic capture.

Tcpdump prints out a description of the contents of packets on a network interface that match the boolean expression; the description is preceded by a time stamp, printed, by default, as hours, minutes, seconds, and fractions of a second since midnight. It can also be run with the -w flag, which causes it to save the packet data to a file for later analysis, and/or with the -r flag, which causes it to read from a saved packet file rather than to read packets from a network interface. It can also be run with the -V flag, which causes it to read a list of saved packet files. In all cases, only packets that match expression will be processed by tcpdump.web

tcpdump 是一款用於截取網絡分組,並過濾輸出分組內容的工具。tcpdump 憑藉強大的功能和靈活的截取策略,使其成爲類 UNIX 系統下用於網絡分析和問題排查的首選工具。 tcpdump 提供了源代碼,公開了接口,所以具有很強的可擴展性,對於網絡維護和入侵者都是很是有用的工具。tcpdump 存在於基本的 Linux 系統中,因爲它須要將網絡界面設置爲混雜模式,普通用戶不能正常執行,但具有 root 權限的用戶能夠直接執行它來獲取網絡上的信息。所以系統中存在網絡分析工具主要不是對本機安全的威脅,而是對網絡上的其餘計算機的安全存在威脅。tcpdump 能夠將網絡中傳送的數據包的 「頭」 徹底截獲下來提供分析。它支持針對網絡層、協議、主機、網絡或端口的過濾,並提供 and、or、not 等邏輯語句來幫助咱們去掉無用的信息。正則表達式

tcpdump安裝

tcpdump 默認在幾乎全部的 Linux 發行版中均可用,但若你的 Linux 上沒有的話,使用下面方法進行安裝。

CentOS/RHEL
使用下面命令在 CentOS 和 RHEL 上安裝 tcpdump,shell

sudo yum install tcpdump*

Fedora
使用下面命令在 Fedora 上安裝 tcpdump:express

dnf install tcpdump

Ubuntu/Debian/Linux Mint
在 Ubuntu/Debain/Linux Mint 上使用下面命令安裝 tcpdump:安全

apt-get install tcpdump

tcpdump經常使用命令解釋

tcpdump [ 選項 ] [ -c 數量 ] [ -i 網絡接口 ] [ -w 文件名 ] [ 表達式 ]

man tcpdump
...
tcpdump [ -AbdDefhHIJKlLnNOpqStuUvxX# ] [ -B buffer_size ]
        [ -c count ]
        [ -C file_size ] [ -G rotate_seconds ] [ -F file ]
        [ -i interface ] [ -j tstamp_type ] [ -m module ] [ -M secret ]
        [ --number ] [ -Q in|out|inout ]
        [ -r file ] [ -V file ] [ -s snaplen ] [ -T type ] [ -w file ]
        [ -W filecount ]
        [ -E spi@ipaddr algo:secret,...  ]
        [ -y datalinktype ] [ -z postrotate-command ] [ -Z user ]
        [ --time-stamp-precision=tstamp_precision ]
        [ --immediate-mode ] [ --version ]
        [ expression ]
...

選項翻譯以下: 

-l:使標準輸出變爲緩衝行形式;
-c:抓包次數;
-nn:直接以 IP 及 Port Number 顯示,而非主機名與服務名稱;
-s :<數據包大小> 設置每一個數據包的大小;
-i:指定監聽的網絡接口;
-r:從指定的文件中讀取包;
-w:輸出信息保存到指定文件;
-a:將網絡地址和廣播地址轉變成名字;
-d:將匹配信息包的代碼以人們可以理解的彙編格式給出;
-e:在輸出行打印出數據鏈路層的頭部信息;
-f:將外部的Internet地址以數字的形式打印出來;
-t:在輸出的每一行不打印時間戳;
-v :輸出稍微詳細的報文信息;--vv則輸出更詳細信息。

表達式指正則表達式,tcpdump 利用它做爲過濾報文的條件,若是一個報文知足表達式的條件,則會捕獲該報文。若是沒有給出任何條件,則會截獲網絡上全部的信息包。
在表達式中通常有以下幾種類型的關鍵字:

  1. 關於類型的關鍵字:

主要包括 host,net,port,例如 host 210.27.48.2, 指明 210.27.48.2 是一臺主機,net 202.0.0.0 指明 202.0.0.0 是一個網絡地址,port 23 指明端口號是 23。若是沒有指定類型,缺省的類型是 host。

  1. 肯定傳輸方向的關鍵字:

主要包括 src,dst,dst or src,dst and src, 這些關鍵字指明瞭傳輸的方向。舉例說明,src 210.27.48.2 ,指明 ip 包中源地址是 210.27.48.2 , dst net 202.0.0.0 指明目的網絡地址是 202.0.0.0。若是沒有指明 方向關鍵字,則缺省是 src or dst 關鍵字。

  1. 協議的關鍵字:

主要包括 fddi,ip,arp,rarp,tcp,udp 等類型。Fddi 指明是在 FDDI (分佈式光纖數據接口網絡) 上的特定的網絡協議,實際上它是」ether」 的別名,fddi 和 ether 具備相似的源地址和目的地址,因此能夠將 fddi 協議包看成 ether 的包進行處理和分析。 其餘的幾個關鍵字就是指明瞭監聽的包的協議內容。若是沒有指定任何協議,則 tcpdump 將會 監聽全部協議的信息包。

  1. 三種邏輯運算:

與運算是'and','&&'; 或運算是'or' ,'||'; 非運算是'not' '!'

  1. 其餘重要的關鍵字:

gateway, broadcast, less(小於), greater(大於)

tcpdump命令演示

從全部網卡中捕獲數據包
運行下面命令來從全部網卡中捕獲數據包:

tcpdump -i any

從指定網卡中捕獲數據包
要從指定網卡中捕獲數據包,運行:

tcpdump -i eth0

將捕獲的包寫入文件
使用 -w 選項將全部捕獲的包寫入文件:

tcpdump -i eth1 -w packets_file

讀取以前產生的 tcpdump 文件
使用下面命令從以前建立的 tcpdump 文件中讀取內容:

tcpdump -r packets_file

獲取更多的包信息,而且以可讀的形式顯示時間戳
要獲取更多的包信息同時以可讀的形式顯示時間戳,使用:

tcpdump -ttttnnvvS

查看整個網絡的數據包
要獲取整個網絡的數據包,在終端執行下面命令:

tcpdump net 192.168.1.0/24

根據 IP 地址查看報文
要獲取指定 IP 的數據包,不論是做爲源地址仍是目的地址,使用下面命令:

tcpdump host 192.168.1.100

要指定 IP 地址是源地址或是目的地址則使用:

tcpdump src 192.168.1.100
tcpdump dst 192.168.1.100

查看某個協議或端口號的數據包
要查看某個協議的數據包,運行下面命令:

tcpdump ssh

要捕獲某個端口或一個範圍的數據包,使用:

tcpdump port 22
tcpdump portrange 22-125

咱們也能夠與 src 和 dst 選項連用來捕獲指定源端口或指定目的端口的報文。

咱們還可使用 「與」 (and,&&)、「或」 (or,|| ) 和 「非」(not,!) 來將兩個條件組合起來。當咱們須要基於某些條件來分析網絡報文是很是有用。

使用 「與」
可使用 and 或者符號 && 來將兩個或多個條件組合起來。好比:

tcpdump src 192.168.1.100 && port 22 -w ssh_packets

使用 「或」
「或」 會檢查是否匹配命令所列條件中的其中一條,像這樣:

tcpdump src 192.168.1.100 or dst 192.168.1.50 && port 22 -w ssh_packets
tcpdump port 443 or 80 -w http_packets

使用 「非」
當咱們想表達不匹配某項條件時可使用 「非」,像這樣:

tcpdump -i eth0 src port not 22

這會捕獲 eth0 上除了 22 號端口的全部通信。

tcpdump抓包實踐

使用 tcpdump 抓包,須要管理員權限,所以下面的示例中絕大多數命令都是以 sudo 開頭。

首先,先用 tcpdump -D 命令列出能夠抓包的網絡接口:

$ sudo tcpdump -D
1.eth0
2.virbr0
3.eth1
4.any (Pseudo-device that captures on all interfaces)
5.lo [Loopback]

如上所示,能夠看到個人機器中全部能夠抓包的網絡接口。其中特殊接口 any 可用於抓取全部活動的網絡接口的數據包。

咱們就用以下命令先對 any 接口進行抓包:

$ sudo tcpdump -i any
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
09:56:18.293641 IP rhel75.localdomain.ssh > 192.168.64.1.56322: Flags [P.], seq 3770820720:3770820916, ack 3503648727, win 309, options [nop,nop,TS val 76577898 ecr 510770929], length 196
09:56:18.293794 IP 192.168.64.1.56322 > rhel75.localdomain.ssh: Flags [.], ack 196, win 391, options [nop,nop,TS val 510771017 ecr 76577898], length 0
09:56:18.295058 IP rhel75.59883 > gateway.domain: 2486+ PTR? 1.64.168.192.in-addr.arpa. (43)
09:56:18.310225 IP gateway.domain > rhel75.59883: 2486 NXDomain* 0/1/0 (102)
09:56:18.312482 IP rhel75.49685 > gateway.domain: 34242+ PTR? 28.64.168.192.in-addr.arpa. (44)
09:56:18.322425 IP gateway.domain > rhel75.49685: 34242 NXDomain* 0/1/0 (103)
09:56:18.323164 IP rhel75.56631 > gateway.domain: 29904+ PTR? 1.122.168.192.in-addr.arpa. (44)
09:56:18.323342 IP rhel75.localdomain.ssh > 192.168.64.1.56322: Flags [P.], seq 196:584, ack 1, win 309, options [nop,nop,TS val 76577928 ecr 510771017], length 388
09:56:18.323563 IP 192.168.64.1.56322 > rhel75.localdomain.ssh: Flags [.], ack 584, win 411, options [nop,nop,TS val 510771047 ecr 76577928], length 0
09:56:18.335569 IP gateway.domain > rhel75.56631: 29904 NXDomain* 0/1/0 (103)
09:56:18.336429 IP rhel75.44007 > gateway.domain: 61677+ PTR? 98.122.168.192.in-addr.arpa. (45)
09:56:18.336655 IP gateway.domain > rhel75.44007: 61677* 1/0/0 PTR rhel75. (65)
09:56:18.337177 IP rhel75.localdomain.ssh > 192.168.64.1.56322: Flags [P.], seq 584:1644, ack 1, win 309, options [nop,nop,TS val 76577942 ecr 510771047], length 1060
---- SKIPPING LONG OUTPUT -----
09:56:19.342939 IP 192.168.64.1.56322 > rhel75.localdomain.ssh: Flags [.], ack 1752016, win 1444, options [nop,nop,TS val 510772067 ecr 76578948], length 0
^C
9003 packets captured
9010 packets received by filter
7 packets dropped by kernel
$

tcpdump 會持續抓包直到收到中斷信號。你能夠按 Ctrl+C 來中止抓包。正如上面示例所示,tcpdump 抓取了超過 9000 個數據包。在這個示例中,因爲我是經過 ssh 鏈接到服務器,因此 tcpdump 也捕獲了全部這類數據包。-c 選項能夠用於限制 tcpdump 抓包的數量:

$ sudo tcpdump -i any -c 5
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
11:21:30.242740 IP rhel75.localdomain.ssh > 192.168.64.1.56322: Flags [P.], seq 3772575680:3772575876, ack 3503651743, win 309, options [nop,nop,TS val 81689848 ecr 515883153], length 196
11:21:30.242906 IP 192.168.64.1.56322 > rhel75.localdomain.ssh: Flags [.], ack 196, win 1443, options [nop,nop,TS val 515883235 ecr 81689848], length 0
11:21:30.244442 IP rhel75.43634 > gateway.domain: 57680+ PTR? 1.64.168.192.in-addr.arpa. (43)
11:21:30.244829 IP gateway.domain > rhel75.43634: 57680 NXDomain 0/0/0 (43)
11:21:30.247048 IP rhel75.33696 > gateway.domain: 37429+ PTR? 28.64.168.192.in-addr.arpa. (44)
5 packets captured
12 packets received by filter
0 packets dropped by kernel
$

如上所示,tcpdump 在抓取 5 個數據包後自動中止了抓包。這在有些場景中十分有用 —— 好比你只須要抓取少許的數據包用於分析。當咱們須要使用過濾規則抓取特定的數據包(以下所示)時,-c 的做用就十分突出了。

在上面示例中,tcpdump 默認是將 IP 地址和端口號解析爲對應的接口名以及服務協議名稱。而一般在網絡故障排查中,使用 IP 地址和端口號更便於分析問題;用 -n 選項顯示 IP 地址,-nn 選項顯示端口號:

$ sudo tcpdump -i any -c5 -nn
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
23:56:24.292206 IP 192.168.64.28.22 > 192.168.64.1.35110: Flags [P.], seq 166198580:166198776, ack 2414541257, win 309, options [nop,nop,TS val 615664 ecr 540031155], length 196
23:56:24.292357 IP 192.168.64.1.35110 > 192.168.64.28.22: Flags [.], ack 196, win 1377, options [nop,nop,TS val 540031229 ecr 615664], length 0
23:56:24.292570 IP 192.168.64.28.22 > 192.168.64.1.35110: Flags [P.], seq 196:568, ack 1, win 309, options [nop,nop,TS val 615664 ecr 540031229], length 372
23:56:24.292655 IP 192.168.64.1.35110 > 192.168.64.28.22: Flags [.], ack 568, win 1400, options [nop,nop,TS val 540031229 ecr 615664], length 0
23:56:24.292752 IP 192.168.64.28.22 > 192.168.64.1.35110: Flags [P.], seq 568:908, ack 1, win 309, options [nop,nop,TS val 615664 ecr 540031229], length 340
5 packets captured
6 packets received by filter
0 packets dropped by kernel

如上所示,抓取的數據包中顯示 IP 地址和端口號。這樣還能夠阻止 tcpdump 發出 DNS 查找,有助於在網絡故障排查中減小數據流量。

如今你已經會抓包了,讓咱們來分析一下這些抓包輸出的含義吧。

理解抓取的報文

tcpdump 可以抓取並解碼多種協議類型的數據報文,如 TCP、UDP、ICMP 等等。雖然這裏咱們不可能介紹全部的數據報文類型,但能夠分析下 TCP 類型的數據報文,來幫助你入門。更多有關 tcpdump 的詳細介紹能夠參考其 幫助手冊。tcpdump 抓取的 TCP 報文看起來以下:

08:41:13.729687 IP 192.168.64.28.22 > 192.168.64.1.41916: Flags [P.], seq 196:568, ack 1, win 309, options [nop,nop,TS val 117964079 ecr 816509256], length 372

具體的字段根據不一樣的報文類型會有不一樣,但上面這個例子是通常的格式形式。

第一個字段 08:41:13.729687 是該數據報文被抓取的系統本地時間戳。

而後,IP 是網絡層協議類型,這裏是 IPv4,若是是 IPv6 協議,該字段值是 IP6。

192.168.64.28.22 是源 ip 地址和端口號,緊跟其後的是目的 ip 地址和其端口號,這裏是 192.168.64.1.41916。

在源 IP 和目的 IP 以後,能夠看到是 TCP 報文標記段 Flags [P.]。該字段一般取值以下:

標誌類型 描述
S SYN Connection Start
F FIN Connection Finish
P PUSH Data push
R RST Connection reset
. ACK Acknowledgment

該字段也能夠是這些值的組合,例如 [S.] 表明 SYN-ACK 數據包。

接下來是該數據包中數據的序列號。對於抓取的第一個數據包,該字段值是一個絕對數字,後續包使用相對數值,以便更容易查詢跟蹤。例如此處 seq 196:568 表明該數據包包含該數據流的第 196 到 568 字節。

接下來是 ack 值:ack 1。該數據包是數據發送方,ack 值爲 1。在數據接收方,該字段表明數據流上的下一個預期字節數據,例如,該數據流中下一個數據包的 ack 值應該是 568。

接下來字段是接收窗口大小 win 309,它表示接收緩衝區中可用的字節數,後跟 TCP 選項如 MSS(最大段大小)或者窗口比例值。更詳盡的 TCP 協議內容請參考 Transmission Control Protocol(TCP) Parameters。

最後,length 372 表明數據包有效載荷字節長度。這個長度和 seq 序列號中字節數值長度是不同的。

如今讓咱們學習如何過濾數據報文以便更容易的分析定位問題。

過濾數據包

正如上面所提,tcpdump 能夠抓取不少種類型的數據報文,其中不少可能和咱們須要查找的問題並無關係。舉個例子,假設你正在定位一個與 web 服務器鏈接的網絡問題,就沒必要關係 SSH 數據報文,所以在抓包結果中過濾掉 SSH 報文可能更便於你分析問題。

tcpdump 有不少參數選項能夠設置數據包過濾規則,例如根據源 IP 以及目的 IP 地址,端口號,協議等等規則來過濾數據包。下面就介紹一些最經常使用的過濾方法。

協議
在命令中指定協議即可以按照協議類型來篩選數據包。比方說用以下命令只要抓取 ICMP 報文:

$ sudo tcpdump -i any -c5 icmp
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
而後再打開一個終端,去 ping 另外一臺機器:

$ ping opensource.com
PING opensource.com (54.204.39.132) 56(84) bytes of data.
64 bytes from ec2-54-204-39-132.compute-1.amazonaws.com (54.204.39.132): icmp_seq=1 ttl=47 time=39.6 ms
回到運行 tcpdump 命令的終端中,能夠看到它篩選出了 ICMP 報文。這裏 tcpdump 並無顯示有關 opensource.com 的域名解析數據包:

09:34:20.136766 IP rhel75 > ec2-54-204-39-132.compute-1.amazonaws.com: ICMP echo request, id 20361, seq 1, length 64
09:34:20.176402 IP ec2-54-204-39-132.compute-1.amazonaws.com > rhel75: ICMP echo reply, id 20361, seq 1, length 64
09:34:21.140230 IP rhel75 > ec2-54-204-39-132.compute-1.amazonaws.com: ICMP echo request, id 20361, seq 2, length 64
09:34:21.180020 IP ec2-54-204-39-132.compute-1.amazonaws.com > rhel75: ICMP echo reply, id 20361, seq 2, length 64
09:34:22.141777 IP rhel75 > ec2-54-204-39-132.compute-1.amazonaws.com: ICMP echo request, id 20361, seq 3, length 64
5 packets captured
5 packets received by filter
0 packets dropped by kernel

主機
用 host 參數只抓取和特定主機相關的數據包:

$ sudo tcpdump -i any -c5 -nn host 54.204.39.132
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
09:54:20.042023 IP 192.168.122.98.39326 > 54.204.39.132.80: Flags [S], seq 1375157070, win 29200, options [mss 1460,sackOK,TS val 122350391 ecr 0,nop,wscale 7], length 0
09:54:20.088127 IP 54.204.39.132.80 > 192.168.122.98.39326: Flags [S.], seq 1935542841, ack 1375157071, win 28960, options [mss 1460,sackOK,TS val 522713542 ecr 122350391,nop,wscale 9], length 0
09:54:20.088204 IP 192.168.122.98.39326 > 54.204.39.132.80: Flags [.], ack 1, win 229, options [nop,nop,TS val 122350437 ecr 522713542], length 0
09:54:20.088734 IP 192.168.122.98.39326 > 54.204.39.132.80: Flags [P.], seq 1:113, ack 1, win 229, options [nop,nop,TS val 122350438 ecr 522713542], length 112: HTTP: GET / HTTP/1.1
09:54:20.129733 IP 54.204.39.132.80 > 192.168.122.98.39326: Flags [.], ack 113, win 57, options [nop,nop,TS val 522713552 ecr 122350438], length 0
5 packets captured
5 packets received by filter
0 packets dropped by kernel
如上所示,只抓取和顯示與 54.204.39.132 有關的數據包。

端口號
tcpdump 能夠根據服務類型或者端口號來篩選數據包。例如,抓取和 HTTP 服務相關的數據包:

$ sudo tcpdump -i any -c5 -nn port 80
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
09:58:28.790548 IP 192.168.122.98.39330 > 54.204.39.132.80: Flags [S], seq 1745665159, win 29200, options [mss 1460,sackOK,TS val 122599140 ecr 0,nop,wscale 7], length 0
09:58:28.834026 IP 54.204.39.132.80 > 192.168.122.98.39330: Flags [S.], seq 4063583040, ack 1745665160, win 28960, options [mss 1460,sackOK,TS val 522775728 ecr 122599140,nop,wscale 9], length 0
09:58:28.834093 IP 192.168.122.98.39330 > 54.204.39.132.80: Flags [.], ack 1, win 229, options [nop,nop,TS val 122599183 ecr 522775728], length 0
09:58:28.834588 IP 192.168.122.98.39330 > 54.204.39.132.80: Flags [P.], seq 1:113, ack 1, win 229, options [nop,nop,TS val 122599184 ecr 522775728], length 112: HTTP: GET / HTTP/1.1
09:58:28.878445 IP 54.204.39.132.80 > 192.168.122.98.39330: Flags [.], ack 113, win 57, options [nop,nop,TS val 522775739 ecr 122599184], length 0
5 packets captured
5 packets received by filter
0 packets dropped by kernel

IP 地址 / 主機名
一樣,你也能夠根據源 IP 地址或者目的 IP 地址或者主機名來篩選數據包。例如抓取源 IP 地址爲 192.168.122.98 的數據包:

$ sudo tcpdump -i any -c5 -nn src 192.168.122.98
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
10:02:15.220824 IP 192.168.122.98.39436 > 192.168.122.1.53: 59332+ A? opensource.com. (32)
10:02:15.220862 IP 192.168.122.98.39436 > 192.168.122.1.53: 20749+ AAAA? opensource.com. (32)
10:02:15.364062 IP 192.168.122.98.39334 > 54.204.39.132.80: Flags [S], seq 1108640533, win 29200, options [mss 1460,sackOK,TS val 122825713 ecr 0,nop,wscale 7], length 0
10:02:15.409229 IP 192.168.122.98.39334 > 54.204.39.132.80: Flags [.], ack 669337581, win 229, options [nop,nop,TS val 122825758 ecr 522832372], length 0
10:02:15.409667 IP 192.168.122.98.39334 > 54.204.39.132.80: Flags [P.], seq 0:112, ack 1, win 229, options [nop,nop,TS val 122825759 ecr 522832372], length 112: HTTP: GET / HTTP/1.1
5 packets captured
5 packets received by filter
0 packets dropped by kernel
注意此處示例中抓取了來自源 IP 地址 192.168.122.98 的 53 端口以及 80 端口的數據包,它們的應答包沒有顯示出來由於那些包的源 IP 地址已經變了。

相對的,使用 dst 就是按目的 IP / 主機名來篩選數據包。

$ sudo tcpdump -i any -c5 -nn dst 192.168.122.98
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
10:05:03.572931 IP 192.168.122.1.53 > 192.168.122.98.47049: 2248 1/0/0 A 54.204.39.132 (48)
10:05:03.572944 IP 192.168.122.1.53 > 192.168.122.98.47049: 33770 0/0/0 (32)
10:05:03.621833 IP 54.204.39.132.80 > 192.168.122.98.39338: Flags [S.], seq 3474204576, ack 3256851264, win 28960, options [mss 1460,sackOK,TS val 522874425 ecr 122993922,nop,wscale 9], length 0
10:05:03.667767 IP 54.204.39.132.80 > 192.168.122.98.39338: Flags [.], ack 113, win 57, options [nop,nop,TS val 522874436 ecr 122993972], length 0
10:05:03.672221 IP 54.204.39.132.80 > 192.168.122.98.39338: Flags [P.], seq 1:643, ack 113, win 57, options [nop,nop,TS val 522874437 ecr 122993972], length 642: HTTP: HTTP/1.1 302 Found
5 packets captured
5 packets received by filter
0 packets dropped by kernel

多條件篩選
固然,可使用多條件組合來篩選數據包,使用 and 以及 or 邏輯操做符來建立過濾規則。例如,篩選來自源 IP 地址 192.168.122.98 的 HTTP 數據包:

$ sudo tcpdump -i any -c5 -nn src 192.168.122.98 and port 80
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
10:08:00.472696 IP 192.168.122.98.39342 > 54.204.39.132.80: Flags [S], seq 2712685325, win 29200, options [mss 1460,sackOK,TS val 123170822 ecr 0,nop,wscale 7], length 0
10:08:00.516118 IP 192.168.122.98.39342 > 54.204.39.132.80: Flags [.], ack 268723504, win 229, options [nop,nop,TS val 123170865 ecr 522918648], length 0
10:08:00.516583 IP 192.168.122.98.39342 > 54.204.39.132.80: Flags [P.], seq 0:112, ack 1, win 229, options [nop,nop,TS val 123170866 ecr 522918648], length 112: HTTP: GET / HTTP/1.1
10:08:00.567044 IP 192.168.122.98.39342 > 54.204.39.132.80: Flags [.], ack 643, win 239, options [nop,nop,TS val 123170916 ecr 522918661], length 0
10:08:00.788153 IP 192.168.122.98.39342 > 54.204.39.132.80: Flags [F.], seq 112, ack 643, win 239, options [nop,nop,TS val 123171137 ecr 522918661], length 0
5 packets captured
5 packets received by filter
0 packets dropped by kernel
你也可使用括號來建立更爲複雜的過濾規則,但在 shell 中請用引號包含你的過濾規則以防止被識別爲 shell 表達式:

$ sudo tcpdump -i any -c5 -nn "port 80 and (src 192.168.122.98 or src 54.204.39.132)"
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
10:10:37.602214 IP 192.168.122.98.39346 > 54.204.39.132.80: Flags [S], seq 871108679, win 29200, options [mss 1460,sackOK,TS val 123327951 ecr 0,nop,wscale 7], length 0
10:10:37.650651 IP 54.204.39.132.80 > 192.168.122.98.39346: Flags [S.], seq 854753193, ack 871108680, win 28960, options [mss 1460,sackOK,TS val 522957932 ecr 123327951,nop,wscale 9], length 0
10:10:37.650708 IP 192.168.122.98.39346 > 54.204.39.132.80: Flags [.], ack 1, win 229, options [nop,nop,TS val 123328000 ecr 522957932], length 0
10:10:37.651097 IP 192.168.122.98.39346 > 54.204.39.132.80: Flags [P.], seq 1:113, ack 1, win 229, options [nop,nop,TS val 123328000 ecr 522957932], length 112: HTTP: GET / HTTP/1.1
10:10:37.692900 IP 54.204.39.132.80 > 192.168.122.98.39346: Flags [.], ack 113, win 57, options [nop,nop,TS val 522957942 ecr 123328000], length 0
5 packets captured
5 packets received by filter
0 packets dropped by kernel
該例子中咱們只抓取了來自源 IP 爲 192.168.122.98 或者 54.204.39.132 的 HTTP (端口號 80)的數據包。使用該方法就很容易抓取到數據流中交互雙方的數據包了。

檢查數據包內容

在以上的示例中,咱們只按數據包頭部的信息來創建規則篩選數據包,例如源地址、目的地址、端口號等等。有時咱們須要分析網絡鏈接問題,可能須要分析數據包中的內容來判斷什麼內容須要被髮送、什麼內容須要被接收等。tcpdump 提供了兩個選項能夠查看數據包內容,-X 以十六進制打印出數據報文內容,-A 打印數據報文的 ASCII 值。

例如,HTTP 請求報文內容以下:

$ sudo tcpdump -i any -c10 -nn -A port 80
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
13:02:14.871803 IP 192.168.122.98.39366 > 54.204.39.132.80: Flags [S], seq 2546602048, win 29200, options [mss 1460,sackOK,TS val 133625221 ecr 0,nop,wscale 7], length 0
E..<..@.@.....zb6.'....P...@......r............
............................
13:02:14.910734 IP 54.204.39.132.80 > 192.168.122.98.39366: Flags [S.], seq 1877348646, ack 2546602049, win 28960, options [mss 1460,sackOK,TS val 525532247 ecr 133625221,nop,wscale 9], length 0
E..<..@./..a6.'...zb.P..o..&...A..q a..........
.R.W.......     ................
13:02:14.910832 IP 192.168.122.98.39366 > 54.204.39.132.80: Flags [.], ack 1, win 229, options [nop,nop,TS val 133625260 ecr 525532247], length 0
E..4..@.@.....zb6.'....P...Ao..'...........
.....R.W................
13:02:14.911808 IP 192.168.122.98.39366 > 54.204.39.132.80: Flags [P.], seq 1:113, ack 1, win 229, options [nop,nop,TS val 133625261 ecr 525532247], length 112: HTTP: GET / HTTP/1.1
E.....@.@..1..zb6.'....P...Ao..'...........
.....R.WGET / HTTP/1.1
User-Agent: Wget/1.14 (linux-gnu)
Accept: */*
Host: opensource.com
Connection: Keep-Alive
................
13:02:14.951199 IP 54.204.39.132.80 > 192.168.122.98.39366: Flags [.], ack 113, win 57, options [nop,nop,TS val 525532257 ecr 133625261], length 0
E..4.F@./.."6.'...zb.P..o..'.......9.2.....
.R.a....................
13:02:14.955030 IP 54.204.39.132.80 > 192.168.122.98.39366: Flags [P.], seq 1:643, ack 113, win 57, options [nop,nop,TS val 525532258 ecr 133625261], length 642: HTTP: HTTP/1.1 302 Found
E....G@./...6.'...zb.P..o..'.......9.......
.R.b....HTTP/1.1 302 Found
Server: nginx
Date: Sun, 23 Sep 2018 17:02:14 GMT
Content-Type: text/html; charset=iso-8859-1
Content-Length: 207
X-Content-Type-Options: nosniff
Location: https://opensource.com/
Cache-Control: max-age=1209600
Expires: Sun, 07 Oct 2018 17:02:14 GMT
X-Request-ID: v-6baa3acc-bf52-11e8-9195-22000ab8cf2d
X-Varnish: 632951979
Age: 0
Via: 1.1 varnish (Varnish/5.2)
X-Cache: MISS
Connection: keep-alive
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>302 Found</title>
</head><body>
<h1>Found</h1>
<p>The document has moved <a href="https://opensource.com/">here</a>.</p>
</body></html>
................
13:02:14.955083 IP 192.168.122.98.39366 > 54.204.39.132.80: Flags [.], ack 643, win 239, options [nop,nop,TS val 133625304 ecr 525532258], length 0
E..4..@.@.....zb6.'....P....o..............
.....R.b................
13:02:15.195524 IP 192.168.122.98.39366 > 54.204.39.132.80: Flags [F.], seq 113, ack 643, win 239, options [nop,nop,TS val 133625545 ecr 525532258], length 0
E..4..@.@.....zb6.'....P....o..............
.....R.b................
13:02:15.236592 IP 54.204.39.132.80 > 192.168.122.98.39366: Flags [F.], seq 643, ack 114, win 57, options [nop,nop,TS val 525532329 ecr 133625545], length 0
E..4.H@./.. 6.'...zb.P..o..........9.I.....
.R......................
13:02:15.236656 IP 192.168.122.98.39366 > 54.204.39.132.80: Flags [.], ack 644, win 239, options [nop,nop,TS val 133625586 ecr 525532329], length 0
E..4..@.@.....zb6.'....P....o..............
.....R..................
10 packets captured
10 packets received by filter
0 packets dropped by kernel

這對定位一些普通 HTTP 調用 API 接口的問題頗有用。固然若是是加密報文,這個輸出也就沒多大用了。

保存抓包數據

tcpdump 提供了保存抓包數據的功能以便後續分析數據包。例如,你能夠夜裏讓它在那裏抓包,而後早上起來再去分析它。一樣當有不少數據包時,顯示過快也不利於分析,將數據包保存下來,更有利於分析問題。

使用 -w 選項來保存數據包而不是在屏幕上顯示出抓取的數據包:

$ sudo tcpdump -i any -c10 -nn -w webserver.pcap port 80
[sudo] password for ricardo:
tcpdump: listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
10 packets captured
10 packets received by filter
0 packets dropped by kernel

該命令將抓取的數據包保存到文件 webserver.pcap。後綴名 pcap 表示文件是抓取的數據包格式。

正如示例中所示,保存數據包到文件中時屏幕上就沒有任何有關數據報文的輸出,其中 -c10 表示抓取到 10 個數據包後就中止抓包。若是想有一些反饋來提示確實抓取到了數據包,可使用 -v 選項。

tcpdump 將數據包保存在二進制文件中,因此不能簡單的用文本編輯器去打開它。使用 -r 選項參數來閱讀該文件中的報文內容:

$ tcpdump -nn -r webserver.pcap
reading from file webserver.pcap, link-type LINUX_SLL (Linux cooked)
13:36:57.679494 IP 192.168.122.98.39378 > 54.204.39.132.80: Flags [S], seq 3709732619, win 29200, options [mss 1460,sackOK,TS val 135708029 ecr 0,nop,wscale 7], length 0
13:36:57.718932 IP 54.204.39.132.80 > 192.168.122.98.39378: Flags [S.], seq 1999298316, ack 3709732620, win 28960, options [mss 1460,sackOK,TS val 526052949 ecr 135708029,nop,wscale 9], length 0
13:36:57.719005 IP 192.168.122.98.39378 > 54.204.39.132.80: Flags [.], ack 1, win 229, options [nop,nop,TS val 135708068 ecr 526052949], length 0
13:36:57.719186 IP 192.168.122.98.39378 > 54.204.39.132.80: Flags [P.], seq 1:113, ack 1, win 229, options [nop,nop,TS val 135708068 ecr 526052949], length 112: HTTP: GET / HTTP/1.1
13:36:57.756979 IP 54.204.39.132.80 > 192.168.122.98.39378: Flags [.], ack 113, win 57, options [nop,nop,TS val 526052959 ecr 135708068], length 0
13:36:57.760122 IP 54.204.39.132.80 > 192.168.122.98.39378: Flags [P.], seq 1:643, ack 113, win 57, options [nop,nop,TS val 526052959 ecr 135708068], length 642: HTTP: HTTP/1.1 302 Found
13:36:57.760182 IP 192.168.122.98.39378 > 54.204.39.132.80: Flags [.], ack 643, win 239, options [nop,nop,TS val 135708109 ecr 526052959], length 0
13:36:57.977602 IP 192.168.122.98.39378 > 54.204.39.132.80: Flags [F.], seq 113, ack 643, win 239, options [nop,nop,TS val 135708327 ecr 526052959], length 0
13:36:58.022089 IP 54.204.39.132.80 > 192.168.122.98.39378: Flags [F.], seq 643, ack 114, win 57, options [nop,nop,TS val 526053025 ecr 135708327], length 0
13:36:58.022132 IP 192.168.122.98.39378 > 54.204.39.132.80: Flags [.], ack 644, win 239, options [nop,nop,TS val 135708371 ecr 526053025], length 0
$

這裏不須要管理員權限 sudo 了,由於此刻並非在網絡接口處抓包。

你還可使用咱們討論過的任何過濾規則來過濾文件中的內容,就像使用實時數據同樣。 例如,經過執行如下命令從源 IP 地址 54.204.39.132 檢查文件中的數據包:

$ tcpdump -nn -r webserver.pcap src 54.204.39.132
reading from file webserver.pcap, link-type LINUX_SLL (Linux cooked)
13:36:57.718932 IP 54.204.39.132.80 > 192.168.122.98.39378: Flags [S.], seq 1999298316, ack 3709732620, win 28960, options [mss 1460,sackOK,TS val 526052949 ecr 135708029,nop,wscale 9], length 0
13:36:57.756979 IP 54.204.39.132.80 > 192.168.122.98.39378: Flags [.], ack 113, win 57, options [nop,nop,TS val 526052959 ecr 135708068], length 0
13:36:57.760122 IP 54.204.39.132.80 > 192.168.122.98.39378: Flags [P.], seq 1:643, ack 113, win 57, options [nop,nop,TS val 526052959 ecr 135708068], length 642: HTTP: HTTP/1.1 302 Found
13:36:58.022089 IP 54.204.39.132.80 > 192.168.122.98.39378: Flags [F.], seq 643, ack 114, win 57, options [nop,nop,TS val 526053025 ecr 135708327], length 0

下一步作什麼?

以上的基本功能已經能夠幫助你使用強大的 tcpdump 抓包工具了。更多的內容請參考 tcpdump 網站以及它的幫助文件。

tcpdump 命令行工具爲分析網絡流量數據包提供了強大的靈活性。若是須要使用圖形工具來抓包請參考 Wireshark。

Wireshark 還能夠用來讀取 tcpdump 保存的 pcap 文件。你可使用 tcpdump 命令行在沒有 GUI 界面的遠程機器上抓包而後在 Wireshark 中分析數據包。

一站式學習 Wireshark
https://community.emc.com/thr...
https://www.w3cschool.cn/wire...

相關文章
相關標籤/搜索