linux进阶25——tcpdump详解
1. 应用场景
1. 工作原理
tcpdump 是 Linux 系统中非常有用的网络工具,运行在用户态,本质上是通过调用libpcap库的各种API来实现数据包的抓取功能。
通过上图,我们可以很直观的看到,数据包到达网卡后,经过数据包过滤器(BPF)筛选后,拷贝至用户态的 tcpdump 程序,以供 tcpdump 工具进行后续的处理工作,输出或保存到 pcap 文件。
数据包过滤器(BPF)主要作用,就是根据用户输入的过滤规则,只将用户关心的数据包拷贝至 tcpdump,这样能够减少不必要的数据包拷贝,降低抓包带来的性能损耗。
思考:这里分享一个真实的面试题
面试官:如果某些数据包被 iptables 封禁,是否可以通过 tcpdump 抓到包?
通过上图,我们可以很轻易的回答此问题。
因为 Linux 系统中netfilter是工作在协议栈阶段的,tcpdump 的过滤器(BPF)工作位置在协议栈之前,所以当然是可以抓到包了!
2. 基础用法
1. 不加任何参数,默认情况下将抓取第一个非 lo 网卡上所有的数据包
[root@localhost ~]# tcpdump
2. 抓取网卡上的所有数据包(enp5s0是我的服务器的网卡名)
[root@localhost ~]# tcpdump -i enp5s0
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on enp5s0, link-type EN10MB (Ethernet), capture size 262144 bytes
3. 抓包时指定-n选项,不解析主机和端口名。这个参数很关键,会影响抓包的性能,一般抓包时都需要指定该选项。
[root@localhost ~]# tcpdump -n -i enp5s0
4. 抓取指定主机192.168.0.103的所有数据包
root@localhost ~]# tcpdump -ni enp5s0 host 192.168.0.103
5. 抓取指定主机192.168.0.103发送的数据包
[root@localhost ~]# tcpdump -ni enp5s0 src host 192.168.0.103
6. 抓取发送给192.168.0.103的所有数据包
[root@localhost ~]# tcpdump -ni enp5s0 dst host 192.168.0.103
7. 抓取enp5s0网卡上发往指定主机的数据包,抓到 10 个包就停止,这个参数也比较常用
[root@localhost ~]# tcpdump -ni enp5s0 -c 10 dst host 192.168.0.103
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on enp5s0, link-type EN10MB (Ethernet), capture size 262144 bytes
21:27:33.609483 IP 192.168.0.108.ssh > 192.168.0.103.solid-mux: Flags [P.], seq 1599630578:1599630766, ack 2937611650, win 261, length 188
21:27:33.609794 IP 192.168.0.108.ssh > 192.168.0.103.solid-mux: Flags [P.], seq 188:368, ack 1, win 261, length 180
21:27:33.609921 IP 192.168.0.108.ssh > 192.168.0.103.solid-mux: Flags [P.], seq 368:524, ack 1, win 261, length 156
21:27:33.610017 IP 192.168.0.108.ssh > 192.168.0.103.solid-mux: Flags [P.], seq 524:680, ack 1, win 261, length 156
21:27:33.610158 IP 192.168.0.108.ssh > 192.168.0.103.solid-mux: Flags [P.], seq 680:836, ack 1, win 261, length 156
21:27:33.610284 IP 192.168.0.108.ssh > 192.168.0.103.solid-mux: Flags [P.], seq 836:992, ack 1, win 261, length 156
21:27:33.610383 IP 192.168.0.108.ssh > 192.168.0.103.solid-mux: Flags [P.], seq 992:1148, ack 1, win 261, length 156
21:27:33.610478 IP 192.168.0.108.ssh > 192.168.0.103.solid-mux: Flags [P.], seq 1148:1304, ack 1, win 261, length 156
21:27:33.610613 IP 192.168.0.108.ssh > 192.168.0.103.solid-mux: Flags [P.], seq 1304:1460, ack 1, win 261, length 156
21:27:33.611230 IP 192.168.0.108.ssh > 192.168.0.103.solid-mux: Flags [P.], seq 1460:1616, ack 1, win 261, length 156
10 packets captured
11 packets received by filter
0 packets dropped by kernel
8. 抓取enp5s0网卡上所有SSH请求数据包,SSH默认端口是22
[root@localhost ~]# tcpdump -ni enp5s0 dst port 22
9. 抓取enp5s0网卡上5个ping数据包(没有收到数据包的情况下会一直监听,我是使用我本机来ping服务器,我本机ip是192.168.0.108)
[root@localhost ~]# tcpdump -ni enp5s0 -c 5 icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on enp5s0, link-type EN10MB (Ethernet), capture size 262144 bytes
21:30:36.443348 IP 192.168.0.103 > 192.168.0.108: ICMP echo request, id 1, seq 3, length 40
21:30:36.443377 IP 192.168.0.108 > 192.168.0.103: ICMP echo reply, id 1, seq 3, length 40
21:30:37.458431 IP 192.168.0.103 > 192.168.0.108: ICMP echo request, id 1, seq 4, length 40
21:30:37.458458 IP 192.168.0.108 > 192.168.0.103: ICMP echo reply, id 1, seq 4, length 40
21:30:38.476135 IP 192.168.0.103 > 192.168.0.108: ICMP echo request, id 1, seq 5, length 40
5 packets captured
6 packets received by filter
0 packets dropped by kernel
10. 抓取enp5s0网卡上所有的arp数据包
[root@localhost ~]# tcpdump -ni enp5s0 arp
11. 使用十六进制输出,当你想检查数据包内容是否有问题时,十六进制输出会很有帮助。
[root@localhost ~]# tcpdump -ni enp5s0 -c 1 arp -X
12. 只抓取enp5s0网卡上IPv6的流量
[root@localhost ~]# tcpdump -ni enp5s0 ip6
13. 抓取指定端口范围的流量
[root@localhost ~]# tcpdump -ni enp5s0 portrange 80-9000
14. 抓取指定网段的流量
[root@localhost ~]# tcpdump -ni enp5s0 net 192.168.1.0/24
3. 高级进阶
1. 抓取指定客户端访问ssh的数据包
[root@localhost ~]# tcpdump -ni enp5s0 src 192.168.0.103 and dst port 22
2. 抓取从某个网段来,到某个网段去的流量
[root@localhost ~]# tcpdump -ni enp5s0 src net 192.168.1.0/16 and dst net 10.0.0.0/8 or 172.16.0.0/16
3. 抓取来自某个主机,发往非 ssh 端口的流量
[root@localhost ~]# tcpdump -ni enp5s0 src 192.168.0.103 and not dst port 22
4. 当构建复杂查询的时候,你可能需要使用引号,单引号告诉 tcpdump 忽略特定的特殊字符,这里的()就是特殊符号,如果不用引号的话,就需要使用转义字符
[root@localhost ~]# tcpdump -ni enp5s0 'src 192.168.0.103 and (dst port 3389 or 22)'
5. 基于包大小进行筛选,如果你正在查看特定的包大小,可以使用这个参数
小于等于 64 字节:
[root@localhost ~]# tcpdump -ni enp5s0 less 64
等于 64 字节:
[root@localhost ~]# tcpdump -ni enp5s0 length == 64
大于等于 64 字节:
[root@localhost ~]# tcpdump -ni enp5s0 greater 64
6. 过滤 TCP 特殊标记的数据包
抓取某主机发送的RST数据包:
[root@localhost ~]# tcpdump -ni enp5s0 src host 192.168.0.103 and 'tcp[tcpflags] & (tcp-rst) != 0'
抓取某主机发送的SYN数据包:
[root@localhost ~]# tcpdump -ni enp5s0 src host 192.168.0.103 and 'tcp[tcpflags] & (tcp-syn) != 0'
抓取某主机发送的FIN数据包:
[root@localhost ~]# tcpdump -ni enp5s0 src host 192.168.0.103 and 'tcp[tcpflags] & (tcp-fin) != 0'
抓取 TCP 连接中的SYN或FIN包
[root@localhost ~]# tcpdump -ni enp5s0 'tcp[tcpflags] & (tcp-syn|tcp-fin) != 0'
7. 抓取所有非 ping 类型的ICMP包
[root@localhost ~]# tcpdump -i enp5s0 'icmp[icmptype] != icmp-echo and icmp[icmptype] != icmp-echoreply'
8. 抓取端口是 80,网络层协议为 IPv4, 并且含有数据,而不是 SYN、FIN 以及 ACK 等不含数据的数据包
[root@localhost ~]# tcpdump -ni enp5s0 'tcp port 80 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)'
解释一下这个复杂的表达式,具体含义就是,整个 IP 数据包长度减去 IP 头长度,再减去 TCP 头的长度,结果不为 0,就表示数据包有Data
9. 抓取 HTTP 报文,0x4757是 GET
前两字符的值,0x4854
是 HTTP
前两个字符的值
[root@localhost ~]# tcpdump -ni enp5s0 'tcp[20:2]=0x4745 or tcp[20:2]=0x4854'
4. 常用选项
(一)基础选项
-
-i
:指定接口 -
-D
:列出可用于抓包的接口 -
-s
:指定数据包抓取的长度 -
-c
:指定要抓取的数据包的数量 -
-w
:将抓包数据保存在文件中 -
-r
:从文件中读取数据 -
-C
:指定文件大小,与-w
配合使用 -
-F
:从文件中读取抓包的表达式 -
-n
:不解析主机和端口号,这个参数很重要,一般都需要加上 -
-P
:指定要抓取的包是流入还是流出的包,可以指定的值in
、out
、inout
(二)输出选项
-
-e
:输出信息中包含数据链路层头部信息 -
-t
:显示时间戳,tttt
显示更详细的时间 -
-X
:显示十六进制格式 -
-v
:显示详细的报文信息,尝试-vvv
,v
越多显示越详细
5. 过滤表达式
tcpdump 强大的功能和灵活的策略,主要体现在过滤器(BPF)强大的表达式组合能力。
(一)操作对象
表达式中可以操作的对象有如下几种:
-
type,表示对象的类型,比如:
host
、net
、port
、portrange
,如果不指定 type 的话,默认是host -
dir
:表示传输的方向,可取的方式为:src
、dst
。 -
proto
:表示协议,可选的协议有:ether
、ip
、ip6
、arp
、icmp
、tcp
、udp
。
(二)条件组合
表达对象之间还可以通过关键字 and
、or
、not
进行连接,组成功能更强大的表达式。
-
or
:表示或操作 -
and
:表示与操作 -
not
:表示非操作
部分参考微信公众号【Linux开发那些事儿】
更多推荐
所有评论(0)