Linux中的Tcpdump命令
“ tcpdump”是一个命令行实用程序,可用于捕获和检查进出系统的网络流量。
它是网络管理员中用于排除网络问题和安全测试的最常用工具。
尽管名称为'tcpdump',我们也可以捕获非TCP流量,例如UDP,ARP或者ICMP。
捕获的数据包可以写入文件或者标准输出。
“ tcpdump”命令最强大的功能之一是它能够使用过滤器并仅捕获要分析的数据。
在本文中,我们将介绍如何在Linux中使用'tcpdump'命令的基础知识。
安装'tcpdump'
大多数Linux发行版和macOS上默认安装了“ tcpdump”。
要检查“ tcpdump”命令在系统上是否可用:
tcpdump --version
输出应如下所示:
tcpdump version 4.9.2 libpcap version 1.8.1 OpenSSL 1.1.1b 26 Nov 2019
如果系统上不存在“ tcpdump”,则上面的命令将显示“ tcpdump:找不到命令”。
我们可以使用发行版的软件包管理器轻松安装“ 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 [options] [expression]
- 命令“选项”使我们可以控制命令的行为。
- 过滤器“表达式”定义将捕获哪些数据包。
只有root或者具有'sudo'特权的用户才能运行'tcpdump'。
如果我们尝试以非特权用户身份运行该命令,则会收到一条错误消息:“我们无权在该设备上进行捕获”。
最简单的用例是不带任何选项和过滤器的情况下调用“ 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 theitroad-host.ssh > desktop-machine.39196: Flags [P.], seq 201647193:201647301, ack 1226568763, win 402, options [nop,nop,TS val 1051794587 ecr 2679218230], length 108 15:47:24.248785 IP theitroad-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 theitroad-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
捕获数据包后,“ tcpdump”将停止。
如果未指定任何接口,则“ tcpdump”将使用它找到并转储通过该接口的所有数据包的第一个接口。
使用“ -D”选项可打印tcpdump可以从中收集数据包的所有可用网络接口的列表:
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'找到的第一个接口,并且在没有为该命令提供接口时使用。
第二个接口“ any”是一种特殊的设备,可让我们捕获所有活动的接口。
要指定要在其上捕获流量的接口,请使用“ -i”选项调用该命令,后跟接口名称或者关联的索引。
例如,要捕获来自所有接口的所有数据包,我们可以指定“ any”接口:
sudo tcpdump -i any
默认情况下,“ tcpdump”对IP地址执行反向DNS解析,并将端口号转换为名称。
使用'-n'选项禁用翻译:
sudo tcpdump -n
跳过DNS查找可避免生成DNS流量,并使输出更具可读性。
建议我们在每次调用'tcpdump'时使用此选项。
我们可以使用重定向操作符'>'和'>>'将其重定向到文件中,而不是在屏幕上显示输出:
sudo tcpdump -n -i any > file.out
我们还可以使用“ tee”命令在保存到文件的同时查看数据:
sudo tcpdump -n -l | tee file.out
上面命令中的'-l'选项告诉'tcpdump'使输出行缓冲。
如果不使用此选项,则在生成新行时,输出不会写在屏幕上。
了解“ 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 201647193:201647301, 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地址和端口,由点('。')分隔。
- '192.168.1.150.37445'-目标IP地址和端口,以点号(..)分隔。
- '标志[P.]'-TCP标志字段。在此示例中,“ [P。]”表示推送确认数据包,用于确认前一个数据包并发送数据。其他典型标志字段值如下:
- [。]-ACK(确认)
- [S]-SYN(开始连接)
- [P]-PSH(推送数据)
- [F]-FIN(完成连接)
- [R]-RST(重置连接)
- [S.]-SYN-ACK(SynAcK数据包)
- 'seq 201647193:201647301'-序列号以'first:last'表示法表示。它显示了数据包中包含的数据数量。除了数据流中的第一个数据包(其中这些数字是绝对的)以外,所有后续数据包均用作相对字节位置。在此示例中,数字为'201647193:201647301',表示此数据包包含数据流的字节201647193至201647301. 使用“ -S”选项打印绝对序列号。
- “ ack 1226568763”确认号是此连接另一端预期的下一个数据的序列号。
- 'win 402'-窗口号是接收缓冲区中可用字节的数目。
- 'options [nop,nop,TS val 1051794587 ecr 2679218230]'-TCP选项。使用'nop'或者“ no operation”填充使TCP报头为4字节的倍数。 “ TS val”是TCP时间戳,“ ecr”表示回显应答。请访问IANA文档以获取有关TCP选项的更多信息。
- 'length 108'-有效载荷数据的长度
'tcpdump'过滤器
当不带过滤器的情况下调用“ tcpdump”时,它将捕获所有流量并产生大量输出,这使得查找和分析目标数据包变得非常困难。
过滤器是“ tcpdump”命令最强大的功能之一。
因为它们允许我们仅捕获与表达式匹配的那些数据包。
例如,在对与Web服务器有关的问题进行故障排除时,可以使用过滤器仅获取HTTP通信。
'tcpdump'使用伯克利数据包过滤器(BPF)语法通过各种加工参数(例如协议,源和目标IP地址和端口等)过滤捕获的数据包。
在本文中,我们将介绍一些最常见的过滤器。
有关所有可用过滤器的列表,请查看pcap-filter联机帮助页。
按协议过滤
要将捕获限制为特定协议,请将该协议指定为过滤器。
例如,要仅捕获UDP流量,可以使用:
sudo tcpdump -n udp
定义协议的另一种方法是使用“ proto”限定符,后跟协议编号。
以下命令将过滤协议编号17,并产生与上述相同的结果:
sudo tcpdump -n proto 17
有关编号的更多信息,请检查IP协议编号列表。
按主机过滤
要仅捕获与特定主机有关的数据包,请使用“主机”限定符:
sudo tcpdump -n host 192.168.1.185
主机可以是IP地址或者名称。
我们还可以使用“ net”限定符将输出过滤到给定的IP范围。
例如,要仅转储与“ 10.10.0.0/16”相关的数据包,可以使用:
sudo tcpdump -n net 10.10
按端口过滤
要仅将捕获限制为来自特定端口或者特定端口的数据包,请使用“端口”限定符。
下面的命令使用以下命令捕获与SSH(端口22)服务相关的数据包:
sudo tcpdump -n port 23
使用“端口范围”限定符可以捕获一系列端口中的流量:
sudo tcpdump -n portrange 110-150
按来源和目的地过滤
我们还可以使用'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
复杂过滤器
可以使用'and'('&&'),'or'('||')和'not'('!')运算符来组合过滤器。
例如,要捕获来自源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 10 -C 200 -w /tmp/file.pcap
生成十个文件后,较旧的文件将被覆盖。
请注意,我们仅应在排除故障期间运行“ tcpdump”。
如果要在特定时间启动“ tcpdump”,则可以使用cronjob。
“ tcpdump”没有在指定时间后退出的选项。
我们可以在一段时间后使用“超时”命令停止“ tcpdump”。
例如,要在5分钟后退出,我们可以使用:
sudo timeout 300 tcpdump -n -w data.pcap