tcpdump是一个命令行程序,可用于捕获和检查进出系统的网络流量。它是网络管理员中用于排除网络问题和安全测试的最常用工具。
尽管名称为tcpdump,但您也可以捕获非TCP流量,例如UDP,ARP或ICMP。捕获的数据包可以写入文件或标准输出。
tcpdump命令最强大的功能之一是它能够使用过滤器并仅捕获您要分析的数据。在本教程中,我们将介绍如何在Linux使用tcpdump命令的基础知识。
在大多数Linux发行版和macOS默认安装tcpdump。要检查tcpdump命令在您的系统是否可用,请运行命令tcpdump --version
,命令将会打印tcpdump的版本号。
tcpdump --version
tcpdump version 4.9.2
libpcap version 1.8.1
OpenSSL 1.1.1b 26 Feb 2019
如果你的系统未安装tcpdump,命令将显示tcpdump: command not found,tcpdump命令未找到。您可以使用发行版的软件包管理器轻松安装tcpdump。
如果你的计算机运行的是基于Debian的Linux发行版,例如Ubuntu,Linux mint。请运行命令sudo apt update && sudo apt install tcpdump
安装tcpdump。
如果你的计算机运行的是基于RedHat的Linux发行版,例如CentOS,Fedora。请运行命令sudo yum install tcpdump
安装tcpdump。
如果你的计算机运行的是Arch发行版,请运行命令sudo pacman -S tcpdump
安装tcpdump。
sudo apt update && sudo apt install tcpdump
sudo yum install tcpdump
sudo pacman -S tcpdump
tcpdump选项
tcpdump
命令的语法是tcpdump [options] [expression]
。其中options
允许您控制命令的行为。expression
过滤器定义要捕获的数据包。
只有root用户或具有sudo权限的用户才能运行tcpdump
。 如果您尝试以非root用户身份运行tcpdump命令。
则会收到一条错误消息,You don’t have permission to capture on that device,也就是你没有权限捕获在这个设备。
最简单的用例是不使用没有任何选项和过滤器运行tcpdump
命令。
sudo tcpdump
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ens3, link-type EN10MB (Ethernet), capture size 262144 bytes
15:47:24.248737 IP myfreax-host.ssh > desktop-machine.39196: Flags [P.], seq 201747193:201747301, ack 1226568763, win 402, options [nop,nop,TS val 1051794587 ecr 2679218230], length 108
15:47:24.248785 IP myfreax-host.ssh > desktop-machine.39196: Flags [P.], seq 108:144, ack 1, win 402, options [nop,nop,TS val 1051794587 ecr 2679218230], length 36
15:47:24.248828 IP myfreax-host.ssh > desktop-machine.39196: Flags [P.], seq 144:252, ack 1, win 402, options [nop,nop,TS val 1051794587 ecr 2679218230], length 108
... Long output suppressed
23116 packets captured
23300 packets received by filter
184 packets dropped by kernel
tcpdump将继续捕获数据包并写入标准输出,直到接收到中断信号为止。可使用Ctrl+C
组合键发送中断信号并停止命令。
要获得更详细的输出,请传递-v
选项,或者传递-vv
以获得更详细的输出,运行命令sudo tcpdump -vv
。
您可以使用-c
选项指定要捕获的数据包数量。例如要仅捕获十个数据包,可以运行命令sudo tcpdump -c 10
。
sudo tcpdump -vv
sudo tcpdump -c 10
捕获数据包后,tcpdump将停止。未指定接口时,tcpdump使用第一个接口查找并保存通过该接口的所有数据包。
如果你需要找到第一接口的名称或者所有接口的名称,请使用tcpdump的-D
选项,例如命令sudo tcpdump -D
将打印所有可用网络接口的列表。
sudo tcpdump -D
命令将打印接口名称,简短描述以及关联的索引编号。
sudo tcpdump -D
1.ens3 [Up, Running]
2.any (Pseudo-device that captures on all interfaces) [Up, Running]
3.lo [Up, Running, Loopback]
上面的输出显示ens3
是tcpdump找到的第一个接口,并且在tcpdump命令没有指定接口时使用第一个接口。
第二个接口any
是一种特殊的设备,可让您捕获所有活动的接口。
要在指定的接口捕获数据包,请使用-i
选项运行tcpdump命令,后跟接口名称或关联的索引编号。
例如命令sudo tcpdump -i any
将会在any
接口捕获来自所有接口的所有数据包。
sudo tcpdump -i any
默认情况下,tcpdump对IP地址执行反向DNS解析,并将端口号转换为常用服务的名称,例如端口将会转换为SSH。
如果你需要禁用反向DNS解析,端口映射服务名称,可以使用-n
选项禁用这些功能,例如命令sudo tcpdump -n
。
跳过DNS查找可避免生成DNS流量,并使输出更具可读性。建议您每次调tcpdump
时都使用此选项。
sudo tcpdump -n
您可以使用重定向操作符>
和>>
将其重定向到文件中,而不是在终端显示输出。您还可以使用tee
命令保存到文件的同时监控数据。
在使用组合tee命令和tcpdump时,请使用tcpdump的-l
选项缓冲输出。不使用此选项时,生成新行时,输出不会写在屏幕。
sudo tcpdump -n -i any > file.out
sudo tcpdump -n -l | tee file.out
了解tcpdump输出
tcpdump在每行输出捕获的信息。每行包含时间戳和数据包的信息,具体取决于协议。
TCP协议行的典型格式,和示例数据如下:
[Timestamp] [Protocol] [Src IP].[Src Port] > [Dst IP].[Dst Port]: [Flags], [Seq], [Ack], [Win Size], [Options], [Data Length]
15:47:24.248737 IP 192.168.1.185.22 > 192.168.1.150.37445: Flags [P.], seq 201747193:201747301, ack 1226568763, win 402, options [nop,nop,TS val 1051794587 ecr 2679218230], length 108
15:47:24.248737
捕获的数据包的时间戳记为本地时间,并使用格式hours:minutes:seconds.frac
显示,其中frac
是自午夜以来的几分之一秒。
IP
版本。在这种情况下,IP表示Internet协议版本4,也就是IPv4。
192.168.1.185.22
源IP地址和端口,以点.
分隔,这里22
是端口。
192.168.1.150.37445
目标IP地址和端口,以点.
分隔,37445
是端口。
Flags [P.]
TCP标识字段。在此示例中,[P.]
表示推送确认数据包,用于确认先前的数据包并发送数据。其他典型标识字段包括。
[.]
ACK确认,[S]
SYN开始连接,[P]
PSH推送数据,[F]
FIN完成连接,[R]
-RST重置连接,[S.]
SYN-ACK SynAcK数据包。
seq 201747193:201747301
序列号为first:last
表示法。它显示了数据包中包含的数据数量。
除了数据流中的第一个数据包以外,所有后续数据包均用作相对字节位置。
在此示例中,数字为201747193:201747301
,表示此数据包包含数据流的字节201747193至201747301。可使用-S
选项打印绝对序列号。
ack 1226568763
确认号是此连接另一端预期的下一个数据的序列号。win 402
窗口号是接收缓冲区中的可用字节数。
options [nop,nop,TS val 1051794587 ecr 2679218230]
TCP选项。 nop
或no operation
用于使TCP报头4字节的倍数的填充。
TS val
是TCP时间戳,ecr
表示回显应答。要获取TCP选项的更多信息,请访问IANA文档。length 108
有效载荷数据的长度。
tcpdump 过滤
如果在没有过滤器的情况下运行tcpdump命令,它将捕获所有流量并产生大量输出,这使得查找和分析目标数据包非常困难。
过滤器是tcpdump
命令最强大的功能之一。 因为它们允许您仅捕获与表达式匹配的那些数据包。
例如,在对与Web服务器的问题进行故障排除时,可以使用过滤器仅获取HTTP流量。
tcpdump使用Berkeley数据包过滤器 BPF语法,使用各种参数,例如协议,源IP地址和目标IP地址和端口等,过滤捕获的数据包。
在本教程中,我们将介绍一些最常见的过滤器。要找到所有可用过滤器的列表,请查看pcap-filter联机帮助页。
协议过滤
要将捕获限制为指定协议,请将该协议指定为过滤器。例如要仅捕获UDP流量,可以运行命令sudo tcpdump -n udp
。
定义协议的另一种方法是使用限定符proto
,后跟协议编号。如需要知道更多协议对应编码的信息,请查看IP协议号码列表。
命令sudo tcpdump -n proto 17
将过滤编号是17的协议,并产生与过滤UDP协议相同的结果。
sudo tcpdump -n udp
sudo tcpdump -n proto 17
host 过滤
要仅捕获与指定主机相关的数据包,请使用限定符host
,host
可以是IP地址或名称。
您还可以使用限定符net
将输出过滤到指定的IP范围,这相当与使用子网掩码指定网段。
例如要仅转储与10.10.0.0/16
相关的数据包,可以运行命令sudo tcpdump -n net 10.10
。
sudo tcpdump -n host 192.168.1.185
sudo tcpdump -n net 10.10
端口过滤
要仅将捕获来自指定端口的数据包,请使用限定符port
。命令sudo tcpdump -n port 23
捕获SSH服务相关的数据包,也就是端口22。
除了指定端口之外,还可以指定端口的范围, portrange
限定符使您可以捕获指定端口范围的流量。
sudo tcpdump -n port 23
sudo tcpdump -n portrange 110-150
过滤来源与目标
您还可以使用限定符src
,dst
,src and dst
和src or dst
基于源,目标端口或者主机过滤数据包。过滤器可以使用&&
,||
和!
运算符进行组合。
您也可以使用括号创建判断的先后的条件,来构建更复杂的过滤。为避免使用特殊字符时解析错误,请将过滤条件括在单引号内。
sudo tcpdump -n src host 192.168.1.185
命令捕获源自IP为192.168.1.185的主机发送的数据包。
sudo tcpdump -n dst port 80
命令过滤目标端口是80的数据包。
sudo tcpdump -n src 192.168.1.185 and tcp port 80
命令捕获源IP地址192.168.1.185并且协议是TCP,端口的数据包,通常是捕获HTTP协议的数据包。
sudo tcpdump -n 'host 192.168.1.185 and (tcp port 80 or tcp port 443)'
命令捕获IP地址是192.168.1.185
并且协议是TCP,端口可以是80或者443的数据包。
sudo tcpdump -n src 192.168.1.185 and not dst port 22命令捕获IP地址是192.168.1.185
并且目标端口不是端口22。
sudo tcpdump -n src host 192.168.1.185
sudo tcpdump -n dst port 80
sudo tcpdump -n src 192.168.1.185 and tcp port 80
sudo tcpdump -n src 192.168.1.185 and not dst port 22
查看数据
tcpdump默认仅捕获数据包头部。但是,有时您可能需要检查数据包的内容。tcpdump允许您以ASCII和十六进制格式打印数据包的内容。
-A
选项可以使用ASCII打印每个数据包的数据,-x
选项将使用十六进制打印每个数据包的数据。
sudo tcpdump -n -A
命令要以ASCII码显示数据包的内容,sudo tcpdump -n -X
命令要以十六进制显示数据包的内容。
sudo tcpdump -n -A
sudo tcpdump -n -X
读取与写入文件
tcpdump的另一个有用的功能是数据包写入文件。 当您捕获大量数据包或捕获数据包以供以后分析时,这非常方便。
要写入文件,请使用-w
选项,然后是指定要写入的文件名称。 您可以根据需要命名文件名称,但是捕获数据包使用.pcap
扩展名是一种常见的约定。
使用-w
选项时,输出不显示在屏幕上。tcpdump写入的数据包是二进制格式的文件,常见的文本编辑器无法读取该文件。
sudo tcpdump -n -w data.pcap
命令会将捕获数据包内容并保存到文件data.pcap。要检查文件的内容,请使用-r
选项运行tcpdump命令。
sudo tcpdump -n -w data.pcap
sudo tcpdump -r data.pcap
如果要在后台中运行tcpdump
,请在命令末尾添加符号&
。数据包捕获文件也可以使用其它数据包分析器工具例如Wireshark进行查看。
长时间捕获数据包时,可以启用文件轮换的功能。 tcpdump允许您创建新文件并以指定的时间间隔或固定大小滚动存储文件。
sudo tcpdump -n -W 10 -C 200 -w /tmp/file.pcap
命令将创建十个200MB文件,分别命名为file.pcap0
,file.pcap1
等。一旦生成十个文件,较旧的文件将被覆盖。
sudo tcpdump -n -W 10 -C 200 -w /tmp/file.pcap
如果要在指定时间启动tcpdump,则可以使用Crontab定时任务。如果仅需要运行一段时间并退出,您可以使用timeout命令停止tcpdump。
例如命令sudo timeout 300 tcpdump -n -w data.pcap
将在5分钟后退出。
sudo timeout 300 tcpdump -n -w data.pcap
结论
tcpdump
是用于分析和排除网络相关问题的命令行工具。如果您有任何问题或反馈,请随时发表评论。
本教程向您展示tcpdump用法和语法的基础。如需要更深入的了解,请访问Tcpdump 文档。