Linux命令行中如何使用tcpdump

一个功能强大、灵活的命令行工具可以帮助你解决网络故障。

tcpdump是一个命令行程序,可让你捕获和分析通过系统的网络流量。 tcpdump是一个功能强大且用途广泛的工具,其中包括许多选项和过滤器,可以在多种情况下使用。 由于它是命令行工具,适合在没有GUI的远程服务器中运行,以收集可以分析的数据。

在本文中,我们将介绍tcpdump的一些最常见功能。

1. tcpdump的工作原理

tcpdump运行在用户态,底层调用的是libpcap库的各种api来实现数据包的捕获。

libpcap是一个捕获网络流量的C/C++库,通过libpcap库可以构建不同的应用程序,数据包格式为pcap

image-20210421203755994

image-20210421203834281

在上图中,我们通过ftp在本机和ftp.arpa.net之间传输数据,数据包到达网卡(Network Interface Card,简称NIC)后,经过数据包过滤器(Berkeley Packet Filter,简称BPF)筛选后,将数据包拷贝到tcpdump,然后tcpdump进行数据包的解码,可以在终端显示,也可将数据包以pcap格式保存到本地磁盘。

从上图中,我们可以看出数据到达bpf进行包过滤是在tcp协议栈之前操作的。

2. tcpdump捕获包

tcpdump包含在多个Linux发行版中,因此可能已经安装了它。 使用以下命令检查系统上是否安装了tcpdump:

$ which tcpdump
/usr/sbin/tcpdump

如果tcpdump没有安装,可以Google进行安装。

现在可以开始抓包了。

为了捕获数据包以进行故障排除或分析,tcpdump需要root权限,因此在以下示例中,大多数命令都以sudo前缀。

首先,使用命令tcpdump --list-interfaces(或简称-D)查看哪些接口可用于捕获:

$ sudo tcpdump -D
1.eth0 [Up, Running]
2.any (Pseudo-device that captures on all interfaces) [Up, Running]
3.lo [Up, Running, Loopback]
4.nflog (Linux netfilter log (NFLOG) interface)
5.nfqueue (Linux netfilter queue (NFQUEUE) interface)
6.usbmon1 (USB bus number 1)

在上面的示例中,你可以看我所有可用的接口。特殊接口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
21:34:51.424030 IP iZwz9czknxjqmstiji1vpmZ.ssh > 183.230.12.174.3821: Flags [P.], seq 2488863953:2488864085, ack 607933093, win 249, options [nop,nop,TS val 2433154148 ecr 1140831183], length 132
21:34:51.424062 IP iZwz9czknxjqmstiji1vpmZ.ssh > 183.230.12.174.3821: Flags [P.], seq 132:184, ack 1, win 249, options [nop,nop,TS val 2433154148 ecr 1140831183], length 52
21:34:51.424091 IP iZwz9czknxjqmstiji1vpmZ.ssh > 183.230.12.174.3821: Flags [P.], seq 184:316, ack 1, win 249, options 
...
^C
465 packets captured
532 packets received by filter
67 packets dropped by kernel
$

tcpdump会一直抓包,直到按下Ctrl+C中断。

我们可以通过限制抓包的数量来停止tcpdump,使用-c(count)选项。

$ sudo tcpdump -i eth0 -c 3
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
21:39:54.163860 IP iZwz9czknxjqmstiji1vpmZ.ssh > 183.230.12.174.3821: Flags [P.], seq 2488983077:2488983209, ack 607934845, win 249, options [nop,nop,TS val 2433229833 ecr 1141133924], length 132
21:39:54.163890 IP iZwz9czknxjqmstiji1vpmZ.ssh > 183.230.12.174.3821: Flags [P.], seq 132:184, ack 1, win 249, options [nop,nop,TS val 2433229833 ecr 1141133924], length 52
21:39:54.163918 IP iZwz9czknxjqmstiji1vpmZ.ssh > 183.230.12.174.3821: Flags [P.], seq 184:316, ack 1, win 249, options [nop,nop,TS val 2433229833 ecr 1141133924], length 132
3 packets captured
23 packets received by filter
14 packets dropped by kernel

这个例子中,tcpdump在抓了eth0网卡的3个包之后自动停止。

默认情况下,tcpdump将IP地址和端口解析为名称,如上例所示。 指定 -n 选项,不解析主机和端口名。这个参数很关键,会影响抓包的性能,一般抓包时都需要指定该选项:

$ sudo tcpdump -i eth0 -c 3 -n
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
21:42:18.091676 IP 172.18.158.34.22 > 183.230.12.174.3821: Flags [P.], seq 2488985253:2488985385, ack 607935361, win 249, options [nop,nop,TS val 2433265815 ecr 1141277854], length 132
21:42:18.091707 IP 172.18.158.34.22 > 183.230.12.174.3821: Flags [P.], seq 132:184, ack 1, win 249, options [nop,nop,TS val 2433265815 ecr 1141277854], length 52
21:42:18.091735 IP 172.18.158.34.22 > 183.230.12.174.3821: Flags [P.], seq 184:316, ack 1, win 249, options [nop,nop,TS val 2433265815 ecr 1141277854], length 132
3 packets captured
9 packets received by filter
0 packets dropped by kernel

现在我们已经可以捕获网络数据包,让我们看看输出的含义。

3. 捕获包的输出格式

tcpdump能够捕获和解码许多不同的协议,例如TCP,UDP,ICMP等。这里让我们探究常见的TCP数据包。 您可以在tcpdump的手册页中找到有关不同协议格式的更多详细信息。 tcpdump捕获的典型TCP数据包如下所示:

21:48:44.091859 IP 172.18.158.34.22 > 183.230.12.174.3821: Flags [P.], seq 132:184, ack 1, win 249, options [nop,nop,TS val 2433362315 ecr 1141663861], length 52

第一个字段,21:48:44.091859代表根据本地时钟接收的数据包的时间戳。

接下来,IP代表网络层协议,在本例中为IPv4。 对于IPv6数据包,该值为IP6。

下一个字段172.18.158.34.22是源IP地址和端口。 随后是目标IP地址和端口,由183.230.12.174.3821表示。

在之后,可以找到TCP标志Flags [P.]。 该字段的典型值包括:

ValueFlag TypeDescription
SSYNConnection Start
FFINConnection Finish
PPUSHData push
RRSTConnection reset
.ACKAcknowledgment

字段也可以是这些值的组合,例如[S.]表示SYN-ACK数据包。

接下来是数据的序列号。 对于第一个捕获的数据包,这是一个绝对数。 后续数据包使用相对编号,便于跟踪。 在此示例中,序列为seq 132:184,这意味着此数据包为132至184的字节。

其后是ack 1。在这种情况下,它是1,因为这是发送数据的一方。 对于接收数据的一方,此字段表示该数据流中的下一个预期字节。 例如,该数据流下一个数据包的ack编号将为184。

下一个字段是win 249,它表示接收缓冲区中可用的字节数,其后是TCP选项,例如MSS(Maximum Segment Size)或窗口大小。有关TCP协议选项的详细信息,请查看Transmission Control Protocol (TCP) Parameters

最后,length 52表示数据包长度。

现在,让我们学习如何过滤数据包来缩小抓包范围。

4. 过滤包

tcpdump最强大的功能之一就是能使用各种参数(例如源和目标IP地址,端口,协议等)过滤数据包。让我们来看一些最常见的参数。

  • 协议

通过协议来过滤包,比如抓ICMP包:

$ sudo tcpdump -ni eth0 -c5 icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
22:10:54.475196 IP 172.18.158.34 > 54.204.39.132: ICMP echo request, id 613, seq 28, length 64
22:10:54.744406 IP 54.204.39.132 > 172.18.158.34: ICMP echo reply, id 613, seq 28, length 64
22:10:55.476358 IP 172.18.158.34 > 54.204.39.132: ICMP echo request, id 613, seq 29, length 64
22:10:55.744416 IP 54.204.39.132 > 172.18.158.34: ICMP echo reply, id 613, seq 29, length 64
22:10:56.477287 IP 172.18.158.34 > 54.204.39.132: ICMP echo request, id 613, seq 30, length 64
5 packets captured
5 packets received by filter
0 packets dropped by kernel

在另一个终端中,对另一台计算机执行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=26 time=267 ms
  • host
$ sudo tcpdump -ni eth0 -c5 host 54.204.39.132
  • port

根据端口过滤数据包。 例如,使用以下命令捕获与Web(HTTP)服务相关的数据包:

$ sudo tcpdump -ni eth0 -c5 port 80
  • 源IP、目的IP和主机名
$ sudo tcpdump -ni eth0 -c5 src 172.18.158.34
$ sudo tcpdump -ni eth0 -c5 dst 172.18.158.34
  • 复杂表达式

通过使用逻辑运算符and和or创建更复杂的表达式来组合过滤器。 例如,仅过滤来自源IP地址192.168.122.98并且是HTTP的数据包:

$ sudo tcpdump -ni eth0 -c5 src 172.18.158.34 and port 80

还可以将过滤器与括号分组来创建更复杂的表达式。在这种情况下,请用引号将整个过滤器表达式引起来,以防止shell程序将它们与shell表达式混淆:

$ sudo tcpdump -ni any -c5 "port 80 and (src 172.18.158.34 or src 54.204.39.132)"
  • 打印出数据包的内容
    • -A:以ASCII打印内容
    • -X:以十六进制打印内容
$ sudo tcpdump -ni eth0 -c5 -A
$ sudo tcpdump -ni eth0 -c5 -X
  • 将抓包内容保存到文件中,-w (write)
$ sudo tcpdump -ni any -c10 -w webserver.pcap port 80

此命令将抓到的包保存在webserver.pcap的文件中。 .pcap扩展名表示“数据包捕获”,并且是此文件格式的约定,可通过wireshark分析捕获的包。任何内容都不会显示在屏幕上,并且在捕获10个数据包之后完成。 如果需要显示捕获了数据包,请使用选项-v

要读取文件的内容,可以用-r(用于读取)选项执行tcpdump:

$ tcpdump -n -r webserver.pcap

6. 参考信息来源

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值