在网络问题的调试中,tcpdump应该说是一个必不可少的工具,和大部分linux下优秀工具一样,它的特点就是简单而强大。它是基于Unix系统的命令行式的数据包嗅探工具,可以抓取流动在网卡上的数据包。
默认情况下,tcpdump不会抓取本机内部通讯的报文。根据网络协议栈的规定,对于报文,即使是目的地是本机,也需要经过本机的网络协议层,所以本机通讯肯定是通过API进入了内核,并且完成了路由选择。【比如本机的TCP通信,也必须要socket通信的基本要素:src ip port dst ip port】
如果要使用tcpdump抓取其他主机MAC地址的数据包,必须开启网卡混杂模式,所谓混杂模式,用最简单的语言就是让网卡抓取任何经过它的数据包,不管这个数据包是不是发给它或者是它发出的。一般而言,Unix不会让普通用户设置混杂模式,因为这样可以看到别人的信息,比如telnet的用户名和密码,这样会引起一些安全上的问题,所以只有root用户可以开启混杂模式,开启混杂模式的命令是:ifconfig en0 promisc, en0是你要打开混杂模式的网卡。
Linux抓包原理:
Linux抓包是通过注册一种虚拟的底层网络协议来完成对网络报文(准确的说是网络设备)消息的处理权。当网卡接收到一个网络报文之后,它会遍历系统中所有已经注册的网络协议,例如以太网协议、x25协议处理模块来尝试进行报文的解析处理,这一点和一些文件系统的挂载相似,就是让系统中所有的已经注册的文件系统来进行尝试挂载,如果哪一个认为自己可以处理,那么就完成挂载。
当抓包模块把自己伪装成一个网络协议的时候,系统在收到报文的时候就会给这个伪协议一次机会,让它来对网卡收到的报文进行一次处理,此时该模块就会趁机对报文进行窥探,也就是把这个报文完完整整的复制一份,假装是自己接收到的报文,汇报给抓包模块。
host(缺省类型): 指明一台主机,如:host 210.27.48.2
net: 指明一个网络地址,如:net 202.0.0.0
port: 指明端口号,如:port 23
确定方向的关键字
src: src 210.27.48.2, IP包源地址是210.27.48.2
dst: dst net 202.0.0.0, 目标网络地址是202.0.0.0
dst or src(缺省值)
dst and src
协议的关键字:缺省值是监听所有协议的信息包
fddi
ip
arp
rarp
tcp
udp
其他关键字
gateway
broadcast
less
greater
常用表达式:多条件时可以用括号,但是要用\转义
非 : ! or "not" (去掉双引号)
且 : && or "and"
或 : || or "or"
tcpdump: WARNING: eth0: no IPv4 address assigned
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
15:36:18.806314 IP bogon.26 > bogon.61681: Flags [P.], seq 1872349141:1872349385, ack 1531137621, win 252, length 244
15:36:18.806566 IP bogon.43893 > jtbjdc001.home.******.com.domain: 46527+ PTR? 37.36.200.10.in-addr.arpa. (43)
15:36:18.806893 IP jtbjdc001.home.******.com.domain > bogon.43893: 46527 1/0/0 PTR bogon. (62)
15:36:18.806968 IP bogon.40634 > jtbjdc001.home.******.com.domain: 52587+ PTR? 91.12.151.10.in-addr.arpa. (43)
15:36:18.807270 IP jtbjdc001.home.******.com.domain > bogon.40634: 52587 1/0/0 PTR bogon. (62)
15:36:18.807345 IP bogon.58342 > jtbjdc001.home.******.com.domain: 49094+ PTR? 11.1.150.10.in-addr.arpa. (42)
15:36:18.807374 IP bogon.26 > bogon.61681: Flags [P.], seq 244:408, ack 1, win 252, length 164
15:36:18.807641 IP jtbjdc001.home.******.com.domain > bogon.58342: 49094* 1/0/0 PTR jtbjdc001.home.******.com. (83)
15:36:18.807692 IP bogon.46970 > jtbjdc001.home.******.com.domain: 17599+ PTR? 90.12.151.10.in-addr.arpa. (43)
15:36:18.807994 IP jtbjdc001.home.******.com.domain > bogon.46970: 17599 1/0/0 PTR bogon. (62)
15:36:18.808099 IP bogon.26 > bogon.61681: Flags [P.], seq 408:1420, ack 1, win 252, length 1012
15:36:18.808131 IP bogon.26 > bogon.61681: Flags [P.], seq 1420:1568, ack 1, win 252, length 148
15:36:18.808200 IP bogon.26 > bogon.61681: Flags [P.], seq 1568:1716, ack 1, win 252, length 148
15:36:18.808241 IP bogon.26 > bogon.61681: Flags [P.], seq 1716:1864, ack 1, win 252, length 148
15:36:18.808347 IP bogon.26 > bogon.61681: Flags [P.], seq 1864:2012, ack 1, win 252, length 148
抓取所有经过指定网络接口上的数据包
tcpdump -i eth0
如果不指定网卡,默认tcpdump只会监视第一个网络接口,一般是eth0,下面的例子都没有指定网络接口。
控制台输出:
tcpdump: WARNING: eth0: no IPv4 address assigned
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
15:41:30.230320 IP bogon.26 > bogon.61681: Flags [P.], seq 1874716549:1874716793, ack 1531139153, win 252, length 244
15:41:30.230570 IP bogon.51968 > jtbjdc001.home.******.com.domain: 24716+ PTR? 37.36.200.10.in-addr.arpa. (43)
15:41:30.230905 IP jtbjdc001.home.******.com.domain > bogon.51968: 24716 1/0/0 PTR bogon. (62)
15:41:30.230982 IP bogon.47049 > jtbjdc001.home.******.com.domain: 21078+ PTR? 91.12.151.10.in-addr.arpa. (43)
15:41:30.231304 IP jtbjdc001.home.******.com.domain > bogon.47049: 21078 1/0/0 PTR bogon. (62)
15:41:30.231379 IP bogon.48906 > jtbjdc001.home.******.com.domain: 53621+ PTR? 11.1.150.10.in-addr.arpa. (42)
15:41:30.231408 IP bogon.26 > bogon.61681: Flags [P.], seq 244:408, ack 1, win 252, length 164
15:41:30.231673 IP jtbjdc001.home.******.com.domain > bogon.48906: 53621* 1/0/0 PTR jtbjdc001.home.******.com. (83)
15:41:30.231723 IP bogon.53129 > jtbjdc001.home.******.com.domain: 28967+ PTR? 90.12.151.10.in-addr.arpa. (43)
15:41:30.231996 IP jtbjdc001.home.******.com.domain > bogon.53129: 28967 1/0/0 PTR bogon. (62)
15:41:30.232101 IP bogon.26 > bogon.61681: Flags [P.], seq 408:1420, ack 1, win 252, length 1012
15:41:30.232133 IP bogon.26 > bogon.61681: Flags [P.], seq 1420:1568, ack 1, win 252, length 148
15:41:30.232202 IP bogon.26 > bogon.61681: Flags [P.], seq 1568:1716, ack 1, win 252, length 148
15:41:30.232243 IP bogon.26 > bogon.61681: Flags [P.], seq 1716:1864, ack 1, win 252, length 148
15:41:30.232351 IP bogon.26 > bogon.61681: Flags [P.], seq 1864:2012, ack 1, win 252, length 148
15:41:30.232399 IP bogon.26 > bogon.61681: Flags [P.], seq 2012:2160, ack 1, win 252, length 148
抓取所有经过 eth0,目的或源地址是 10.151.12.90 的网络数据:
tcpdump -i eth0 host 10.151.12.90
抓取主机10.37.63.255和主机10.37.63.61或10.37.63.95的通信:
tcpdump host 10.37.63.255 and \(10.37.63.61 or 10.37.63.95 \)
抓取主机192.168.13.210除了和主机10.37.63.61之外所有主机通信的数据包:
tcpdump -n host 10.37.63.255 and ! 10.37.63.61
抓取主机10.37.63.255除了和主机10.37.63.61之外所有主机通信的ip包
tcpdump ip -n host 10.37.63.255 and ! 10.37.63.61
抓取主机10.37.63.3发送的所有数据:
tcpdump -i en0 src host 10.37.63.3 (注意数据流向)
抓取主机10.37.63.3接收的所有数据:
tcpdump -i en0 dst host 10.37.63.3 (注意数据流向)
抓取主机10.37.63.3所有在TCP 80端口的数据包:
tcpdump -i en0 host 10.37.63.3 and tcp port 80
第一列是时间戳:时、分、秒、微秒
第二列是网际网路协议的名称
第三列是报文发送方的十进制的网际网路协议地址,以及紧跟其后的端口号(偶尔会是某个协议名如 http ,如果在此处仍然显示端口号加上 -n 选项)
第四列是大于号
第五列是报文接收方的十进制的网际网路协议地址,以及紧跟其后的端口号(偶尔会是某个协议名如 http ,如果在此处仍然显示端口号加上 -n 选项)
第六列是冒号
第七列是 Flags 标识,可能的取值是 [S.] [.] [P.] [F.]
第八、九、十……列 是tcp协议报文头的一些变量值:
seq 是 请求同步的 序列号
ack 是 已经同步的 序列号
win 是 当前可用窗口大小
length 是 tcp协议报文体的长度
如果加入了-S选项,会看到的 seq, ack 是 两个冒号分割的值,分别表示变更前、后的值。