tcpdump 命令使用简介
简单介绍
tcpdump
是一款强大的网络抓包工具,运行在 Linux
平台上。熟悉 tcpdump
的使用能够帮助你分析、调试网络数据。
要想很好地掌握 tcpdump
, 必须对网络报文( TCP/IP
协议)有一定的了解。不过对于简单的使用来说,只要有网络基础概念就行了。
tcpdump
是一个很复杂的命令,想了解它的方方面面非常不易,也不值得推荐,能够使用它解决日常工作中的问题才是关键。
选项
tcpdump
的选项也很多,要想知道所有选项的话,请参考 man tcpdump
,下面只记录 tcpdump
最常用的选项。
需要注意的是,tcpdump
默认只会截取前 96 字节的内容,要想截取所有的报文内容,可以使用 -s number
, number 就是你要截取的报文字节数,如果是 0 的话,表示截取报文全部内容。
- -n 表示不要解析域名,直接显示 ip。
- -nn 不要解析域名和端口。
- -X 同时用 hex 和 ascii 显示报文的内容。
- -XX 同 -X,但同时显示以太网头部。
- -S 显示绝对的序列号(sequence number),而不是相对编号。
- -i any 监听所有的网卡。
- -v, -vv, -vvv:显示更多的详细信息。
- -c number: 截取 number 个报文,然后结束。
- -A: 只使用 ascii 打印报文的全部数据,不要和 -X 一起使用。截取 http 请求的时候可以用 sudo tcpdump -nSA port 80!
简单使用
1 | $ tcpdump -nS |
监听所有端口,直接显示 ip 地址。
1 | $ tcpdump -nnvvS |
显示更详细的数据报文,包括 tos, ttl, checksum 等。
1 | $ tcpdump -nnvvXS |
显示数据包的全部数据信息,用 hex 和 ascii 两列对比输出。
下面是抓取 ping
命令的请求和返回的两个报文,可以看到全部的数据。
1 | $ sudo tcpdump -nnvXSs 0 -c2 icmp |
过滤器
机器上的网络报文数量异常的多,很多时候我们只关系和具体问题有关的数据包(比如访问某个网站的数据,或者 icmp
超时的报文等等),而这些数据只占到很小的一部分。把所有的数据截取下来,从里面找到想要的信息无疑是一件很费时费力的工作。而 tcpdump
提供了灵活的语法可以精确地截取关心的数据包,简化分析的工作量。这些选择数据包的语句就是过滤器(filter)!
过滤器也可以简单地分为三类:type, dir 和 proto。
Type 让你区分报文的类型,主要由 host(主机), net(网络) 和 port(端口) 组成。src 和 dst 也可以用来过滤报文的源地址和目的地址。
host: 过滤某个主机的数据报文
1 | $ tcpdump host 1.2.3.4 |
src, dst: 过滤源地址和目的地址
1 | $ tcpdump src 2.3.4.5 |
net: 过滤某个网段的数据,CIDR 模式
1 | $ tcpdump net 1.2.3.0/24 |
proto: 过滤某个协议的数据,支持 tcp, udp 和 icmp。使用的时候可以省略 proto 关键字。
1 | $ tcpdump icmp |
port: 过滤通过某个端口的数据包
1 | $ tcpdump port 3389 |
src/dst, port, protocol: 结合三者
1 | $ tcpdump src port 1025 and tcp |
此外还有指定端口和数据报文范围的过滤器:
port 范围
1 | $ tcpdump portrange 21-23 |
数据包大小,单位是字节
1 | $ tcpdump less 32 |
过于过滤器的更多详细信息,请访问 tcpdump
官方 map page
的 PCAP-FILTER 部分。
输出到文件
使用 tcpdump
截取数据报文的时候,默认会打印到屏幕的默认输出,你会看到按照顺序和格式,很多的数据一行行快速闪过,根本来不及看清楚所有的内容。不过,tcpdump
提供了把截取的数据保存到文件的功能,以便后面使用其他图形工具(比如 wireshark
,Snort
)来分析。
-w
选项用来把数据报文输出到文件,比如下面的命令就是把所有 80 端口的数据导入到文件。
1 | $ sudo tcpdump -w capture_file.pcap port 80 |
-r
可以读取文件里的数据报文,显示到屏幕上。
1 | $ tcpdump -nXr capture_file.pcap host web30 |
NOTE:保存到文件的数据不是屏幕上看到的文件信息,而是包含了额外信息的固定格式
pcap
,需要特殊的软件来查看,使用vim
或者cat
命令会出现乱码。
强大的过滤器
过滤的真正强大之处在于你可以随意组合它们,而连接它们的逻辑就是常用的 与/AND/&&
、 或/OR/||
和 非/not/!
。
源地址是 10.5.2.3,目的端口是 3389 的数据包
1 | $ tcpdump -nnvS src 10.5.2.3 and dst port 3389 |
从 192.168 网段到 10 或者 172.16 网段的数据包
1 | $ tcpdump -nvX src net 192.168.0.0/16 and dat net 10.0.0.0/8 or 172.16.0.0/16 |
从 Mars 或者 Pluto 发出的数据包,并且目的端口不是 22
1 | $ tcpdump -vv src mars or pluto and not dat port 22 |
从上面的例子就可以看出,你可以随意地组合之前的过滤器来截取自己期望的数据包,最重要的就是知道自己要精确匹配的数据包怎样的!
对于比较复杂的过滤器表达式,为了逻辑的清晰,可以使用括号。不过默认情况下,tcpdump 把 () 当做特殊的字符,所以必须使用单引号 ’ 来消除歧义:
1 | $ tcpdump -nvv -c 20 'src 10.0.2.4 and (dat port 3389 or 22)' |
理解 tcpdump 的输出
截取数据只是第一步,第二步就是理解这些数据,下面就解释一下 tcpdump
命令输出各部分的意义。
1 | 21:27:06.995846 IP (tos 0x0, ttl 64, id 45646, offset 0, flags [DF], proto TCP (6), length 64) |
最基本也是最重要的信息就是数据包的源地址/端口和目的地址/端口,上面的例子第一条数据包中,源地址 ip 是 192.168.1.106,源端口是 56166,目的地址是 124.192.132.54,目的端口是 80。 > 符号代表数据的方向。
此外,上面的三条数据还是 tcp 协议的三次握手过程,第一条就是 SYN 报文,这个可以通过 Flags [S] 看出。下面是常见的 TCP 报文的 Flags:
- [S]: SYN(开始连接)
- [.]: 没有 Flag
- [F]: FIN (结束连接)
而第二条数据的 [S.] 表示 SYN-ACK,就是 SYN 报文的应答报文。
参考文档
本文主要参考了下面两篇文章,算是翻译和二次创作。
- A tcpdump Tutorial and Primer
- A Quick and Practical Reference for tcpdump