一、介绍

二、基础用法

三、进阶用法

四、总结和建议

一、介绍

在日常工作中,我们总是能遇上各种各样奇怪的网络问题,比如我这台机器怎么 ping 不通了,我的 ssh 怎么又连不上了,这个控制台怎么又访问不了了等等各种网络问题,当然有时候可以通过 ping、telnet、arp 这些命令和工具来排查和解决,但这些都比不上去抓个包来得实在,也就是下面要分享的 tcpdump 命令。

 

tcpdump 是 Linux 系统中最有效的网络工具之一,凡是有网络问题十有八九都可以用它快速定位。它运行在用户态,本质是通过调用 libpcap 库的各种 api 来实现数据包的抓取功能。tcpdump 是非常强大的,并且相较其他的 Linux 命令和工具而且要稍微复杂一些,我们没必要完全掌握它,关键是灵活运用,能解决实际问题就好了。

 

二、基础用法

1、监听网卡 eth0,这个方式最简单了,但是用处不多,因为基本上只能看到数据包的信息刷屏,压根看不清,可以使用 ctrl+c 中断退出,如果真有需求,可以将输出内容重定向到一个文件,这样也更方便查看。

 

[root@benarchen ~]# tcpdump -i eth0 #如果直接使用 tcpdump 一般是抓取除 lo 外的第一张网卡


2、监听指定的主机的流量,抓包时指定 -nn 选项,不解析主机和端口名。这个参数很关键,会影响抓包的性能,一般抓包时都需要指定该选项。

 

[root@benarchen ~]# tcpdump -i eth0 -nn 'host 192.168.1.231'

这样的话,192.168.1.231 这台主机接收到的包和发送的包都会被抓取。

[root@benarchen ~]# tcpdump -i eth0 -nn 'src host 192.168.1.231'

这样只有 192.168.1.231 这台主机发送的包才会被抓取。

[root@benarchen ~]# tcpdump -i eth0 -nn 'dst host 192.168.1.231'

这样只有 192.168.1.231 这台主机接收到的包才会被抓取。


3、监听指定端口,用来监听主机的 80 端口收到和发送的所有数据包,结合 -A (以 ascii 的方式显示数据包)参数,在 web 开发中,真是非常有用。

 

[root@benarchen ~]# tcpdump -i eth0 -nnA 'port 80'


4、监听指定主机和端口

 

[root@benarchen ~]# tcpdump -i eth0 -nnA 'port 80 and src host 192.168.1.231'

#多个条件可以用 and,or 连接。上例表示监听 192.168.1.231 主机通过 80 端口发送的数据包。


5、监听除某个端口外的其它端口

 

[root@benarchen ~]# tcpdump -i eth0 -nnA '!port 22'

#如果需要排除某个端口或者主机,可以使用 “!” 符号,上例表示监听非 22 端口的数据包。


6、抓取指定端口范围的流量

 

[root@benarchen ~]# tcpdump -ni eth0 portrange 80-9000


7、抓取指定网段的流量

 

[root@benarchen ~]# tcpdump -ni eth0 net 192.168.1.0/24


8、监听指定协议的数据,这个是用来监听 icmp 协议的数据,类似的,如果要监听 tcp或者是 udp 协议,只需要例中的 icmp 就可以了。

 

[root@benarchen ~]# tcpdump -i eth0 -nn 'icmp'


9、将数据输出到一个指定的文件

 

[root@benarchen ~]# tcpdump -i eth0 -nn port 8000 -w xxx.pcap


三、进阶用法

这里我说的进阶用法,其实也就是基础用法通过灵活组合的方式以达到解决问题的效果,这也正是 tcpdump 的强大之处。

1、抓取指定客户端访问 ssh 的数据包

 

[root@benarchen ~]# tcpdump -ni eth0 src 113.88.13.223 and dst port 22

# 也可以反过来,抓取本机 22 端口发送给指定客户端的数据包

[root@benarchen ~]# tcpdump -ni eth0 src port 22 and dst 113.88.13.223


2、抓取从某个网段来,到某个网段去的流量

 

[root@benarchen ~]# tcpdump -nn src net 113.88.13.223/32 and dst net 10.0.0.0/24 or 172.17.0.0/16  


3、抓取来自某个主机,发往非 ssh 端口的流量

 

[root@benarchen ~]# tcpdump -nni eth0 src 113.88.13.223 and not dst port 22


4、在某些复杂查询的时候需要使用引号、单引号告诉 tcpdump 忽略特定的特殊字符,这里的 () 就是特殊符号,如果不用引号的话,就需要使用转义字符

 

[root@benarchen ~]# tcpdump -ni eth0 'src 113.88.13.223 and (dst port 3389 or 22)'

# 或者也可以使用转义

[root@benarchen ~]# tcpdump -ni eth0 src 113.88.13.223 and \(dst port 3389 or 22\)


5、还可以基于包大小进行筛选,如果你正在查看特定的包大小,可以使用这个参数

 

# 小于等于 48 字节

[root@benarchen ~]# tcpdump -ni less 48

# 等于 48 字节

[root@benarchen ~]# tcpdump -ni eth0 length == 48

# 大于等于 48 字节

[root@benarchen ~]# tcpdump -ni eth0 greater 48


6、过滤 TCP 特殊标记的数据包,可以帮助快速定位到网络问题

 

# 抓取某主机发送的 RST 数据包

[root@benarchen ~]# tcpdump -ni eth0 src host 113.88.13.223 and 'tcp[tcpflags] & (tcp-rst) != 0'

# 抓取某主机发送的 SYN 数据包

[root@benarchen ~]# tcpdump -ni eth0 src host 113.88.13.223 and 'tcp[tcpflags] & (tcp-syn) != 0'

# 抓取某主机发送的 FIN 数据包

[root@benarchen ~]# tcpdump -ni eth0 src host 113.88.13.223 and 'tcp[tcpflags] & (tcp-fin) != 0'

# 抓取 TCP 连接中的 SYN 或 FIN 包

[root@benarchen ~]# tcpdump 'tcp[tcpflags] & (tcp-syn|tcp-fin) != 0'


7、抓取端口是 80,网络层协议为 IPv4, 并且含有数据,而不是 SYN、FIN 以及 ACK 等不含数据的数据包

 

[root@benarchen ~]# tcpdump 'tcp port 80 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)'

# 整个 IP 数据包长度减去 IP 头长度,再减去 TCP 头的长度,结果不为 0,就表示数据包有 data


四、总结和建议

1、常规参数

 

# 基础参数

-i:指定网络接口

-D:列出可用于抓包的接口

-s:指定数据包抓取的长度

-c:指定要抓取的数据包的数量

-w:将抓包数据保存在文件中

-r:从文件中读取数据

-C:指定文件大小,与 -w 配合使用

-F:从文件中读取抓包的表达式

-n:不解析主机和端口号,这个参数很重要,一般都需要加上

-P:指定要抓取的包是流入还是流出的包,可以指定的值in、out、inout

# 输出参数

-e:输出信息中包含数据链路层头部信息

-t:显示时间戳,tttt 显示更详细的时间

-X:显示十六进制格式

-v:显示详细的报文信息,尝试 -vvv,v 越多显示越详细


2、组合表达式参数

 

# 操作对象

type,表示对象的类型,比如:host、net、port、portrange,如果不指定 type 的话,默认是 host

dir:表示传输的方向,可取的方式为:src、dst。

proto:表示协议,可选的协议有:ether、ip、ip6、arp、icmp、tcp、udp。

# 组合连接词

or:表示或操作

and:表示与操作

not:表示非操作


3、建议

 

tcpdump 也不是万能的,还是要讲究灵活应用,配合其他的工具(ping、telnet、curl、arp 等)来解决实际问题

tcpdump 抓包是对系统性能有不小损耗的,生产环境慎用,并且应该尽量带上 -nn 选择,以降低性能损耗

抓包时尽可能要有针对性的指定过滤规则,减少无效数据包的干扰