一份快速实用的 tcpdump 命令参考手册
对于 tcpdump 的使用,大部分管理员会分成两类。有一类管理员,他们熟知 tcpdump 和其中的所有标记;另一类管理员,他们仅了解基本的使用方法,剩下事情都要借助参考手册才能完成。出现这种情况的原因在于, tcpdump 是一个相当高级的命令,使用的时候需要对网络的工作机制有相当深入的了解。
在今天的文章中,我想提供一个快速但相当实用的 tcpdump 参考。我会谈到基本的和一些高级的使用方法。我敢肯定我会忽略一些相当酷的命令,欢迎你补充在评论部分。
在我们深入了解以前,最重要的是了解 tcpdump 是用来做什么的。 tcpdump 命令用来保存和记录网络流量。你可以用它来观察网络上发生了什么,并可用来解决各种各样的问题,包括和网络通信无关的问题。除了网络问题,我经常用 tcpdump 解决应用程序的问题。如果你发现两个应用程序之间无法很好工作,可以用 tcpdump 观察出了什么问题。 tcpdump 可以用来抓取和读取数据包,特别是当通信没有被加密的时候。
基础知识
了解 tcpdump ,首先要知道 tcpdump中使用的标记(flag)。在这个章节中,我会涵盖到很多基本的标记,这些标记在很多场合下会被用到。
1.不转换主机名、端口号等
通常情况下, tcpdump 会尝试查找和转换主机名和端口号。
# tcpdumptcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
16:15:05.051896 IP blog.ssh > 10.0.3.1.32855: Flags [P.], seq 2546456553:2546456749, ack 1824683693, win 355, options [nop,nop,TS val 620879437 ecr 620879348], length 196
你可以通过 -n 标记关闭这个功能。我个人总是使用这个标记,因为我喜欢使用 IP 地址而不是主机名,主机名和端口号的转换经常会带来困扰。
但是,知道利用 tcpdump 转换或者不转换的功能还是相当有用的,特别是有些时候,知道源流量(source traffic)来自哪个服务器是相当重要的。
2.增加详细信息
增加一个简单 -v 标记,输出会包含更多信息,例如一个 IP 包的生存时间(ttl, time to live)、长度和其他的选项。
tcpdump 的详细信息有三个等级,你可以通过在命令行增加 v 标记的个数来获取更多的信息。通常我在使用 tcpmdump 的时候,
总是使用最高等级的详细信息,因为我希望看到所有信息,以免后面会用到。
3.指定网络接口
tcpdump -i eth0通常情况下,如果不指定网络接口, tcpdump 在运行时会选择编号最低的网络接口,一般情况下是 eth0,不过因系统不同可能会有所差异。
你可以用 -i 标记来指定网络接口。在大多数 Linux 系统上,any 这一特定的网络接口名用来让 tcpdump 监听所有的接口。
我发现这在排查服务器(拥有多个网络接口)的问题特别有用,尤其是牵扯到路由的时候。
4.写入文件
tcpdump -w /path/to/filetcpdump 运行结果会输出在屏幕上。
但很多时候,你希望把 tcpdump 的输出结果保存在文件中,最简单的方法就是利用 -w 标记。如果你后续还会检查这些网络数据,这样做就特别有用。将这些数据存成一个文件的好处,就是你可以多次读取这个保存下来的文件,并且可以在这个网络流量的快照上使用其它标记或者过滤器(我们后面会讨论到)。
通常这些数据被缓存而不会被写入文件,直到你用 CTRL+C 结束 tcpdump 命令的时候。
5.读取文件
6.指定抓包大小
较新版本的 tcpdump 通常可以截获 65535 字节,但某些情况下你不需要截获默认大小的数据包。运行 tcpdump 时,
你可以通过 -s 标记来指定快照长度。
7.指定抓包数量
你也可以通过 -c 标记后面加上抓包的数量,让 tcpdump 在抓到一定数量的数据包后停止操作。当你不希望看到 tcpdump 的输出大量出现在屏幕上,以至于你无法阅读的时候,就会希望使用这个标记。当然,通常更好的方法是借助过滤器来截获特定的流量。
8.基础知识汇总
你可以将以上这些基础的标记组合起来使用,来让 tcpdump 提供你所需要的信息。
=======================================================================================
过滤器
介绍完基础的标记后,我们该介绍过滤器了。 tcpdump 可以通过各式各样的表达式,来过滤所截取或者输出的数据。我在这篇文章里会给出一些简单的例子,以便让你们了解语法规则。你们可以查询 tcpdump 帮助中的 pcap-filter 章节,了解更为详细的信息。
9.查找特定主机的流量
10.只显示源地址为特定主机的流量
前面的例子显示了源和目的地址是 10.0.3.1 的流量,而上面的命令只显示数据包源地址是 10.0.3.1 的流量。这是通过在 host 前面增加 src 参数来实现的。这个额外的过滤器告诉 tcpdump 查找特定的源地址。 反过来通过 dst 过滤器,可以指定目的地址。
11.过滤源和目的端口
tcpdump -nvvv -i any -c 3 port 22 and port 60738
通过类似 and 操作符,你可以在 tcpdump 上使用更为复杂的过滤器描述。这个就类似 if 语句,你就这么想吧。这个例子中,我们使用 and 操作符告诉 tcpdump 只输出端口号是 22 和 60738 的数据包。这点在分析网络问题的时候很有用,因为可以通过这个方法来关注某一个特定会话(session)的数据包。你可以用两种方式来表示 and 操作符,and 或者 && 都可以。我个人倾向于两个都使用,特别要记住在使用 && 的时候,要用单引号或者双引号包住表达式。在 BASH 中,你可以使用 && 运行一个命令,该命令成功后再执行后面的命令。通常,最好将表达式用引号包起来,这样会避免不预期的结果,特别当过滤器中有一些特殊字符的时候。
12.查找两个端口号的流量
13.查找两个特定端口和来自特定主机的数据流
在一个过滤器中,你可以多次使用括号。在下面的例子中,下面命令可以限定截获满足如下条件的数据包:发送或接收端口号为 80 或 443,主机来源于 10.0.3.169 或者 10.0.3.1,且目的地址是 10.0.3.246。
================================================================================================
理解输出结果
打开tcpdump的所有选项去截获网络流量是相当困难的,但一旦你拿到这些数据你就要对它进行解读。在这个章节,我们将涉及如何判断源/目的 IP 地址,源/目的端口号,以及 TCP 协议类型的数据包。当然这些是相当基础的,你从 tcpdump 里面获取的信息也远不止这些。不过这篇文章主要是粗略的介绍,我们会关注在这些基础知识上。我建议你们可以通过帮助页获取更为详细的信息。
14.判断源和目的地址
判断源和目的地址和端口号相当简单。
从上面的输出,我们可以看到源 IP 地址是 10.0.3.246,源端口号是 56894, 目的 IP 地址是 192.168.0.92,端口号是 22。一旦你理解 tcpdump 格式后,这些信息很容易判断。如果你还没有猜到格式,你可以按照 src-ip.src-port > dest-ip.dest-port: Flags[S] 格式来分析。源地址位于 > 前面,后面则是目的地址。你可以把 > 想象成一个指向目的地址的箭头符号。
15.判断数据包类型
|
10.0.3.246.56894 > 192.168.0.92.22: Flags [S], cksum 0xcf28 (incorrect -> 0x0388), seq 682725222, win 29200, options [mss 1460,sackOK,TS val 619989005 ecr 0,nop,wscale 7], length 0
|
从上面的例子,我们可以判断这个数据包是一个 SYN 数据包。我们是通过 tcpdump 输出中的 [S] 标记字段得出这个结论,不同类型的数据包有不同类型的标记。不需要深入了解 TCP 协议中的数据包类型,你就可以通过下面的速查表来加以判断。
- [S] – SYN (开始连接)
- [.] – 没有标记
- [P] – PSH (数据推送)
- [F] – FIN (结束连接)
- [R] – RST (重启连接)
在这个版本的 tcpdump 输出中,[S.] 标记代表这个数据包是 SYN-ACK 数据包。
16.不好的例子
上面显示了一个不好的通信例子,在这个例子中“不好”,代表通信没有建立起来。我们可以看到 10.0.3.246 发出一个 SYN 数据包给 主机 192.168.0.92,但是主机并没有应答。
17.好的例子
好的例子应该向上面这样,我们看到典型的 TCP 3次握手。第一数据包是 SYN 包,从主机 10.0.3.246 发送给 主机192.168.0.110,第二个包是 SYN-ACK 包,主机192.168.0.110 回应 SYN 包。最后一个包是一个 ACK 或者 SYN – ACK – ACK 包,是主机 10.0.3.246 回应收到了 SYN – ACK 包。从上面看到一个 TCP/IP 连接成功建立。
=======================================================================
数据包检查
18.用十六进制和 ASCII 码打印数据包
19.只打印 ASCII 码格式的数据包
从上面的输出,你可以看到我们成功获取了一个 http 的 GET 请求包。如果网络通信没有被加密,用人类可阅读的格式打出包中数据,对于解决应用程序的问题是很有帮助。如果你排查一个网络通信被加密的问题,打印包中数据就不是很有用。不过如果你有证书的话,你还是可以使用 ssldump 或者 wireshark。
===================================================================
非 TCP 数据流
虽然这篇文章主要采用 TCP 传输来讲解 tcpdump ,但是 tcpdump 绝对不是只能抓 TCP 数据包。它还可以用来获取其他类型的数据包,例如 ICMP、 UDP 和 ARP 包。下面是一些简单的例子,说明 tcpdump 可以截获非 TCP 数据包。
20.ICMP 数据包
21.UDP 数据包
tcpdump -nvvv -i any -c 2 udp