tcpdump
是一个很经常使用的网络包分析工具,能够用来显示经过网络传输到本系统的 TCP/IP 以及其余网络的数据包。tcpdump
使用 libpcap 库来抓取网络报,这个库在几乎在全部的 Linux/Unix 中都有。mysql
tcpdump
能够从网卡或以前建立的数据包文件中读取内容,也能够将包写入文件中以供后续使用。必须是 root 用户或者使用 sudo 特权来运行 tcpdump
。linux
参数 : ios
-A 以ASCII格式打印出全部分组,并将链路层的头最小化。 sql
-c 在收到指定的数量的分组后,tcpdump就会中止。 shell
-C 在将一个原始分组写入文件以前,检查文件当前的大小是否超过了参数file_size 中指定的大小。若是超过了指定大小,则关闭当前文件,而后在打开一个新的文件。参数 file_size 的单位是兆字节(是1,000,000字节,而不是1,048,576字节)。 centos
-d 将匹配信息包的代码以人们可以理解的汇编格式给出。 缓存
-dd 将匹配信息包的代码以C语言程序段的格式给出。 安全
-ddd 将匹配信息包的代码以十进制的形式给出。 bash
-D 打印出系统中全部能够用tcpdump截包的网络接口。 服务器
-e 在输出行打印出数据链路层的头部信息。
-E 用spi@ipaddr algo:secret解密那些以addr做为地址,而且包含了安全参数索引值spi的IPsec ESP分组。
-f 将外部的Internet地址以数字的形式打印出来。
-F 从指定的文件中读取表达式,忽略命令行中给出的表达式。
-i 指定监听的网络接口。
-l 使标准输出变为缓冲行形式,能够把数据导出到文件。
-L 列出网络接口的已知数据链路。
-m 从文件module中导入SMI MIB模块定义。该参数能够被使用屡次,以导入多个MIB模块。
-M 若是tcp报文中存在TCP-MD5选项,则须要用secret做为共享的验证码用于验证TCP-MD5选选项摘要(详情可参考RFC 2385)。
-b 在数据-链路层上选择协议,包括ip、arp、rarp、ipx都是这一层的。
-n 不把网络地址转换成名字。
-nn 不进行端口名称的转换。
-N 不输出主机名中的域名部分。例如,‘nic.ddn.mil‘只输出’nic‘。
-t 在输出的每一行不打印时间戳。
-O 不运行分组分组匹配(packet-matching)代码优化程序。
-P 不将网络接口设置成混杂模式。
-q 快速输出。只输出较少的协议信息。
-r 从指定的文件中读取包(这些包通常经过-w选项产生)。
-S 将tcp的序列号以绝对值形式输出,而不是相对值。
-s 从每一个分组中读取最开始的snaplen个字节,而不是默认的68个字节。
-T 将监听到的包直接解释为指定的类型的报文,常见的类型有rpc远程过程调用)和snmp(简单网络管理协议;)。
-t 不在每一行中输出时间戳。
-tt 在每一行中输出非格式化的时间戳。
-ttt 输出本行和前面一行之间的时间差。
-tttt 在每一行中输出由date处理的默认格式的时间戳。
-u 输出未解码的NFS句柄。
-v 输出一个稍微详细的信息,例如在ip包中能够包括ttl和服务类型的信息。
-vv 输出详细的报文信息。
-w 直接将分组写入文件中,而不是不分析并打印出来。
注意 :
一、若是使用tcpdump -n, 能够清晰看到以太网以及ip地址而不是名字标识
二、若是咱们使用tcpdump -e, 则能够清晰的看到第一个数据包是全网广播的, 而第二个数据包是点对点的
各比特的含义以下:
使用下面命令在 CentOS 和 RHEL 上安装 tcpdump
,
$ yum install tcpdump*
不带任何选项的tcpdump,默认会抓取第一个网络接口,且只有将tcpdump进程终止才会中止抓包。
例如:
shell> tcpdump -nn -i eth0 icmp
抓包选项:
-c:指定要抓取的包数量。注意,是最终要获取这么多个包。例如,指定"-c 10"将获取10个包,但可能已经处理了100个包,只不过只有10个包是知足条件的包。
-i interface:指定tcpdump须要监听的接口。若未指定该选项,将从系统接口列表中搜寻编号最小的已配置好的接口(不包括loopback接口,要抓取loopback接口使用tcpdump -i lo),
:一旦找到第一个符合条件的接口,搜寻立刻开始。可使用'any'关键字表示全部网络接口。
-n:对地址以数字方式显式,不然显式为主机名,也就是说-n选项不作主机名解析。
-nn:除了-n的做用外,还把端口显示为数值,不然显示端口服务名。
-N:不打印出host的域名部分。例如tcpdump将会打印'nic'而不是'nic.ddn.mil'。
-P:指定要抓取的包是流入仍是流出的包。能够给定的值为"in"、"out"和"inout",默认为"inout"。
-s len:设置tcpdump的数据包抓取长度为len,若是不设置默认将会是65535字节。对于要抓取的数据包较大时,长度设置不够可能会产生包截断,若出现包截断,
:输出行中会出现"[|proto]"的标志(proto实际会显示为协议名)。可是抓取len越长,包的处理时间越长,而且会减小tcpdump可缓存的数据包的数量,
:从而会致使数据包的丢失,因此在能抓取咱们想要的包的前提下,抓取长度越小越好。
因此经常使用的选项也就这几个:
tcpdump -D #命令列出能够抓包的网络接口
tcpdump -c num -i int -nn -XX -vvv
tcpdump的表达式由一个或多个"单元"组成,每一个单元通常包含ID的修饰符和一个ID(数字或名称)。有三种修饰符:
(1).type:指定ID的类型。
能够给定的值有host/net/port/portrange。例如"host foo","net 128.3","port 20","portrange 6000-6008"。默认的type为host。
(2).dir:指定ID的方向。
能够给定的值包括src/dst/src or dst/src and dst,默认为src or dst。例如,"src foo"表示源主机为foo的数据包,"dst net 128.3"表示目标网络为128.3的数据包,"src or dst port 22"表示源或目的端口为22的数据包。
(3).proto:经过给定协议限定匹配的数据包类型。
经常使用的协议有tcp/udp/arp/ip/ether/icmp等,若未给定协议类型,则匹配全部可能的类型。例如"tcp port 21","udp portrange 7000-7009"。
因此,一个基本的表达式单元格式为"proto dir type ID"
除了使用修饰符和ID组成的表达式单元,还有关键字表达式单元:gateway,broadcast,less,greater以及算术表达式。
表达式单元之间可使用操做符" and / && / or / || / not / ! "进行链接,从而组成复杂的条件表达式。如"host foo and not port ftp and not port ftp-data",这表示筛选的数据包要知足"主机为foo且端口不是ftp(端口21)和ftp-data(端口20)的包",经常使用端口和名字的对应关系可在linux系统中的/etc/service文件中找到。
另外,一样的修饰符可省略,如"tcp dst port ftp or ftp-data or domain"与"tcp dst port ftp or tcp dst port ftp-data or tcp dst port domain"意义相同,都表示包的协议为tcp且目的端口为ftp或ftp-data或domain(端口53)。
使用括号"()"能够改变表达式的优先级,但须要注意的是括号会被shell解释,因此应该使用反斜线"\"转义为"\(\)",在须要的时候,还须要包围在引号中。
默认状况下,直接启动tcpdump将监视第一个网络接口(非lo口)上全部流通的数据包。这样抓取的结果会很是多,滚动很是快。
tcpdump
1 2 3 |
|
抓取全部通过eth1,目的或源地址是192.168.1.1的网络数据
指定源地址,192.168.1.1
指定目的地址,192.168.1.1
1 2 3 |
|
抓取全部通过eth1,目的或源端口是25的网络数据
指定源端口
指定目的端口
1 2 3 |
|
1 2 3 4 5 |
|
1 2 3 |
|
Tcpdump + Wireshark 的完美组合实现:在 Linux 里抓包,而后在Windows 里分析包。
|
tcp: ip icmp arp rarp 和 tcp、udp、icmp这些选项等都要放到第一个参数的位置,用来过滤数据报的类型
-i eth1 : 只抓通过接口eth1的包
-t : 不显示时间戳
-s 0 : 抓取数据包时默认抓取长度为68字节。加上-S 0 后能够抓到完整的数据包
-c 100 : 只抓取100个数据包
dst port ! 22 : 不抓取目标端口是22的数据包
src net 192.168.1.0/24 : 数据包的源网络地址为192.168.1.0/24
-w ./target.cap : 保存成cap文件,方便用ethereal(即wireshark)分析
抓取全部通过eth1,目的地址是192.168.1.254或192.168.1.200端口是80的TCP数
1 |
|
抓取全部通过eth1,目标MAC地址是00:01:02:03:04:05的ICMP数据
1 |
|
抓取全部通过eth1,目的网络是192.168,但目的主机不是192.168.1.200的TCP数据
1 |
|
首先了解如何从包头过滤信息
1 2 3 4 5 |
|
1 |
|
1 |
|
1 |
|
1 |
|
1 |
|
1 |
|
1 |
|
1 |
|
1 |
|
1 |
|
1 |
|
1 |
|
1 |
|
1 |
|
-c
参数对于运维人员来讲也比较经常使用,由于流量比较大的服务器,靠人工CTRL+C仍是抓的太多,甚至致使服务器宕机,因而能够用-c
参数指定抓多少个包。
1 |
|
上面的命令计算抓10000个SYN包花费多少时间,能够判断访问量大概是多少。
抓取主机10.37.63.255和主机10.37.63.61或10.37.63.9
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 (注意数据流向)
监视主机master一、与master二、master3之间通讯的数据包
tcpdump host master1 and \( master2 or master3 \)
抓取主机10.37.63.3全部在TCP 80端口的数据包:
tcpdump -i en0 host 10.37.63.3 and tcpp port 80
抓取HTTP主机10.37.63.3在80端口接收到的数据包:
tcpdump -i en0 host 10.37.63.3 and dst port 80
打印master4与任何其余主机之间通讯的IP 数据包, 但不包括与master5之间的数据包.
tcpdump ip host master4 and not master5
抓取全部通过 en0,目的或源端口是 25 的网络数据
tcpdump -i en0 port 25 #源端口 tcpdump -i en0 src port 25 #目的端口 tcpdump -i en0 dst port 25 网络过滤
抓取全部通过 en0,网络是 192.168上的数据包
tcpdump -i en0 net 192.168 tcpdump -i en0 src net 192.168 tcpdump -i en0 dst 192.168 tcpdump -i en0 net 192.168 tcpdump -i en0 net 192.168../24
协议过滤
tcpdump -i en0 arp tcpdump -i en0 ip tcpdump -i en0 tcp tcpdump -i en0 udp tcpdump -i en0 icmp
抓取全部通过 en0,目的地址是 192.168.1.254 或 192.168.1.200 端口是 80 的 TCP 数据
抓取全部通过 en0,目标 MAC 地址是 00:01:02:03:04:05 的 ICMP 数据
抓取全部通过 en0,目的网络是 192.168,但目的主机不是 192.168.1.200 的 TCP 数据
只抓 SYN 包
抓 SYN, ACK
高级包头过滤如前两个的包头过滤,首先了解如何从包头过滤信息:
1 |
|
1 |
|
1 |
|
1 |
|
1 |
|
1 |
|
获取10.1.85.21
和10.1.85.19
之间的通讯,使用命令注意转义符号。
[root@centos daocoder]# tcpdump host 10.1.85.21 and \( 10.1.85.19\) -i ens5f0 -nn -c 10
抓 DNS 请求数据
其余-c 参数对于运维人员来讲也比较经常使用,由于流量比较大的服务器,靠人工 CTRL+C 仍是抓的太多,因而能够用-c 参数指定抓多少个包。
经过tcpdump截获主机www.baidu.com发送与接收全部的数据包
获取从10.1.85.21
发来的10个数据包。
[root@localhost ~]# tcpdump src host 10.1.85.21 -c 10 -i ens5f1
监听tcp(udp)端口。
[root@centos daocoder]# tcpdump tcp port 22 -c 10
获取主机10.1.85.21
和除10.1.85.19
以外全部主机的通讯。
[root@centos daocoder]# tcpdump ip host 10.1.85.21 and ! 10.1.85.19 -c 10 -i any
若是想要获取主机210.27.48.1除了和主机210.27.48.2以外全部主机通讯的ip包,使用命令:
#tcpdump ip host 210.27.48.1 and ! 210.27.48.2
获取从10.1.85.19
且端口主机到10.1.85.21
主机的通讯。
[root@centos daocoder]# tcpdump src host 10.1.85.19 and src port 48565 and dst host 10.1.85.
抓取包含10.10.10.122的数据包
tcpdump -i ens33 -vnn host 10.10.10.122
抓取包含10.10.10.0/24网段的数据包
tcpdump -i ens33 -vnn net 10.10.10.0/24
tcpdump -i ens33 -vnn net 10.10.10.0 mask 255.255.255.0
抓取包含端口22的数据包
tcpdump -i ens33 -vnn port 22
抓取udp协议的数据包
tcpdump -i ens33 -vnn udp
抓取icmp协议的数据包
tcpdump -i ens33 -vnn icmp
抓取arp协议的数据包
tcpdump -i ens33 -vnn arp
抓取ip协议的数据包
tcpdump -i ens33 -vnn ip proto ip
tcpdump -i ens33 -vnn ip
抓取源ip是10.10.10.122的数据包
tcpdump -i ens33 -vnn src host 10.10.10.122
抓取目标ip是10.10.10.122的数据包
tcpdump -i ens33 -vnn dst host 10.10.10.122
抓取源端口是22的数据包
tcpdump -i ens33 -vnn src port 22
抓取源ip是10.10.10.253且目的端口是22的数据包
tcpdump -i ens33 -vnn src host 10.10.10.122 and dst port 22
抓取源ip是10.10.10.122或者端口是22的数据包
tcpdump -i ens33 -vnn src host 10.10.10.122 or port 22
抓取源ip是10.10.10.122且端口不是22的数据包
tcpdump -i ens33 -vnn src host 10.10.10.122 and not port 22
想要截获主机210.27.48.1 和主机210.27.48.2或210.27.48.3的通讯,使用命令(注意:括号前的反斜杠是必须的):
#tcpdump host 210.27.48.1 and \(210.27.48.2 or 210.27.48.3 \)
抓取源ip是10.10.10.2且端口是22,或源ip是10.10.10.65且目的端口是80的数据包。
tcpdump -i ens33 -vnn \(src host 10.10.10.2 and port 22 \) or \(src ip host 10.10.10.65 and prot 80\)
抓取源ip是10.10.10.59且目的端口是22,或者源ip是10.10.10.68且目的端口是80的数据包
tcpdump -i ens33 -vnn '\(src host 10.10.10.59 and dst port 22\) 'or '\(src host 10.10.10.68 and dst prot 80\)'
把抓取的数据包记录存到/tmp/fill文件中,当抓取100个数据包后就退出程序
tcpdump -i ens33 -c 100 -w /tmp/fill
从/tmp/fill记录中读取tcp协议的数据包。
tcpdump -i ens33 -r /tmp/fill tcp
从/tmp/fill记录中读取包含10.10.10.58的数据包。
tcpdump -i ens33 -r /tmp/fill host 10.10.10.58
过滤数据包类型是多播而且端口不是2二、不是icmp协议的数据包。
tcpdump -i ens33 ether multicast and not port 22 and 'not icmp'
过滤协议类型是ip而且目标端口是22的数据包
tcpdump -i ens33 -n ip and dst prot 22
过滤抓取mac地址是某个具体的mac地址、协议类型是arp的数据包
tcpdump -i ens33 ether src host 00:0c:29:2f:a7:50 and arp
过滤抓取协议类型是ospf的数据包
tcpdump -i ens33 ip proto ospf
proto
或者ip proto
加上在/etc/protocols
中可以找到的协议或者相应的协议编号进行过滤。
过滤长度大于200字节的报文
tcpdump -i ens33 greater 200
过滤协议类型为tcp的数据包
tcpdump tcp
过滤出广播包和多播包
tcpdump -i ens33 -c 1 ip multicast and ip broadcast tcpdump -i ens33 -c 1 -vnn 'ether[0] & 1 != 0'
保证目标地址最后一位不为0,只有目标地址最后一位为0,与运算以后才会为0,不然目标地址是低位为0高位不为0的状况,也就是广播包或者多播包。
[root@localhost ~]# tcpdump -i ens33 -c 1 -vnn 'ether[0] & 1 != 0'
查找端口号大于23的全部tcp数据流
tcpdump -i ens33 -c 1 -vnn 'tcp[0:2] & 0xffff > 0x0017 '
监视指定网络接口的数据包
tcpdump -i eth1
若是不指定网卡,默认tcpdump只会监视第一个网络接口,如eth0。
监视指定主机的数据包,例如全部进入或离开longshuai的数据包
tcpdump host longshuai
想要截获全部210.27.48.1 的主机收到的和发出的全部的分组:
#tcpdump host 210.27.48.1
打印helios<-->hot或helios<-->ace之间通讯的数据包
tcpdump host helios and \( hot or ace \)
打印ace与任何其余主机之间通讯的IP数据包,但不包括与helios之间的数据包
tcpdump ip host ace and not helios
截获主机hostname发送的全部数据
tcpdump src host hostname
监视全部发送到主机hostname的数据包
tcpdump dst host hostname
监视指定主机和端口的数据包
tcpdump tcp port 22 and host hostname
对本机的udp 123端口进行监视(123为ntp的服务端口)
tcpdump udp port 123
监视指定网络的数据包,如本机与192.168网段通讯的数据包,"-c 10"表示只抓取10个包
tcpdump -c 10 net 192.168
打印全部经过网关snup的ftp数据包(注意,表达式被单引号括起来了,这能够防止shell对其中的括号进行错误解析)
shell> tcpdump 'gateway snup and (port ftp or ftp-data)'
抓取ping包
[root@server2 ~]# tcpdump -c 5 -nn -i eth0 icmp
抓取到本机22端口包
[root@server2 ~]# tcpdump -c 10 -nn -i eth0 tcp dst port 22 tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
运行下面命令来从全部网卡中捕获数据包:
$ tcpdump -i any
要从指定网卡中捕获数据包,运行:
$ tcpdump -i eth0
使用 -w
选项将全部捕获的包写入文件:
$ tcpdump -i eth1 -w packets_file
使用下面命令从以前建立的 tcpdump 文件中读取内容:
$ tcpdump -r packets_file
要获取更多的包信息同时以可读的形式显示时间戳,使用:
$ tcpdump -ttttnnvvS
要获取整个网络的数据包,在终端执行下面命令:
$ tcpdump net 192.168.1.0/24
要获取指定 IP 的数据包,无论是做为源地址仍是目的地址,使用下面命令:
$ tcpdump host 192.168.1.100
要指定 IP 地址是源地址或是目的地址则使用:
$ tcpdump src 192.168.1.100
$ tcpdump dst 192.168.1.100
要查看某个协议的数据包,运行下面命令:
$ tcpdump ssh
要捕获某个端口或一个范围的数据包,使用:
$ tcpdump port 22
$ tcpdump portrange 22-125
咱们也能够与 src
和 dst
选项连用来捕获指定源端口或指定目的端口的报文。
咱们还可使用“与” (and
,&&
)、“或” (or
,||
) 和“非”(not
,!
) 来将两个条件组合起来。当咱们须要基于某些条件来分析网络报文是很是有用。
可使用 and
或者符号 &&
来将两个或多个条件组合起来。好比:
$ tcpdump src 192.168.1.100 && port 22 -w ssh_packets
“或”会检查是否匹配命令所列条件中的其中一条,像这样:
$ tcpdump src 192.168.1.100 or dst 192.168.1.50 && port 22 -w ssh_packets
$ tcpdump port 443 or 80 -w http_packets
当咱们想表达不匹配某项条件时可使用“非”,像这样:
$ tcpdump -i eth0 src port not 22
这会捕获 eth0 上除了 22 号端口的全部通信。
一、截获全部210.27.48.1 的主机收到的和发出的全部的分组:
#tcpdump host 210.27.48.1
二、截获主机210.27.48.1 和主机210.27.48.2或210.27.48.3的通讯,使用命令(注意:括号前的反斜杠是必须的):
#tcpdump host 210.27.48.1 and \(210.27.48.2 or 210.27.48.3 \)
三、获取主机210.27.48.1除了和主机210.27.48.2以外全部主机通讯的ip包,使用命令:
#tcpdump ip host 210.27.48.1 and ! 210.27.48.2
四、获取主机192.168.228.246接收或发出的ssh包,而且不转换主机名使用以下命令:
#tcpdump -nn -n src host 192.168.228.246 and port 22 and tcp
五、获取主机192.168.228.246接收或发出的ssh包,并把mac地址也一同显示:
# tcpdump -e src host 192.168.228.246 and port 22 and tcp -n -nn
六、过滤的是源主机为192.168.0.1与目的网络为192.168.0.0的报头:
tcpdump src host 192.168.0.1 and dst net 192.168.0.0/24
七、过滤源主机物理地址为XXX的报头:
tcpdump ether src 00:50:04:BA:9B and dst……
八、过滤源主机192.168.0.1和目的端口不是telnet的报头,并导入到tes.t.txt文件中:
Tcpdump src host 192.168.0.1 and dst port not telnet -l > test.txt
九、打印全部进入或离开主机 sundown 的数据包.
tcpdump host sundown
十、打印主机 helios 与主机 hot 或者与主机 ace 之间通讯的数据包
tcpdump host helios and \( hot or ace \)
十一、打印主机 ace 与 任何其余主机之间通讯的IP 数据包, 但不包括与 helios之间的数据包.
tcpdump ip host ace and not helios
十二、打印本地主机与Berkeley网络上的主机之间的全部通讯数据包.
tcpdump net ucb-ether
1三、打印全部源地址或目标地址是本地主机的 IP 数据包(若是本地网络经过网关连到了另外一网络, 则另外一网络并不能算做本地网络. localnet 在实际使用时要真正替换成本地网络的名字.
tcpdump ip and not net localnet
1四、打印长度超过576字节, 而且网关地址是 snup 的 IP 数据包
tcpdump 'gateway snup and ip[2:2] > 576'
1五、参数分析 :-i eth3 在eth3上抓包; -s 84每一个包最多记录84字节; -G 60 每60秒就在打开一个文件记录;
-z ./tcp-add.sh配合-G使用,每次记录完一个文件后执行./tcp-add.sh脚本(后面讲这个脚本)
-w %F,%T.pcap 输出,文件名有时间组成%F表示年月日,%T表示时分秒,如2012-07-16,12:54:54.pcap
再来看这个tcp-add.sh,这个脚本十分简单,实际就是将刚才的记录完的pcap文件名写到ready.txt文件中。
tcpdump -i eth3 -s 84 -G 60 -z ./tcp-add.sh -w %F,%T.pcap
#!/bin/bash # 做为tcpdump的-z参数使用 # 将已经存储完的pcap文件名加入ready.txt等待处理</code> echo $* >> ready.txt
1六、一个TCP包中包含多个mysql协议包,一个协议包就是一条mysql记录。
使用抓包工具开打tcpdump_mysql.ret 文件
# tcpdump -n -nn -tttt -i eth1 -s 65535 'port 3306' -w tcpdump_mysql.ret -C 100
1七、使用tcpdump来抓取执行的sql语句。
# tcpdump -i eth1 -s 0 -l -w - dst port 3306 | strings
1八、ARP包的tcpdump输出信息
使用命令:
#tcpdump arp
获得的输出结果是:
22:32:42.802509 eth0 > arp who-has route tell ICE (0:90:27:58:af:1a) 22:32:42.802902 eth0 < arp reply route is-at 0:90:27:12:10:66 (0:90:27:58:af:1a)
22:32:42是时间戳, 802509是ID号, eth0 >代表从主机发出该分组,arp代表是ARP请求包, who-has route tell ICE代表是主机ICE请求主机route的MAC地址。 0:90:27:58:af:1a 是主机 ICE的MAC地址。
1九、对网卡eth0进行抓包,而且只抓全部进入和离开网络地址59.111.243.17的包,且源端口号为80。
tcpdump –i eth0 net 59.111.243.17 and srcport 80
20、对网卡eth0进行抓包,而且只抓全部进入和离开网络地址59.111.243.17的包,抓包个数指定为10000个,并写入temp.pcap。
tcpdump -i eth0 net 59.111.243.17 -c 10000 -w temp.pcap
2一、Sql语句是经过网络以文本方式传输到mysql服务器端的。所以咱们彻底也能够经过tcpdump这个工具把全部的sql语句捕获到。
tcpdump -i eth0 -A -s 3000 port 3306 -w sql.log
2二、若是想要获取主机210.27.48.1接收或发出的telnet包,使用命令。
tcpdump tcp port 23 host 210.27.48.1
2三、后台抓包, 控制台退出也不会影响,使用命令。
nohup tcpdump -i eth1 port 110 -w /tmp/xxx.cap &
让这个进程在后台运行
tcpdump tcp port 5432 -w ./postgres.cap &
2四、
2五、
2六、
2七、网卡eth0进行抓包,而且只抓全部进入和离开网络地址59.111.243.17的包。
tcpdump -i eth0 net 59.111.243.17
一、tcpdump对 arp/rarp包的输出信息中会包含请求类型及该请求对应的参数. 显示格式简洁明了. 如下是从主机rtsg到主机csam的 rlogin
(远程登陆)过程开始阶段的数据包样例:
arp who-has csam tell rtsg arp reply csam is-at CSAM
第一行表示: rtsg
发送了一个 arp数据包(nt:向全网段发送, arp数据包)以询问 csam
的以太网地址,csam以她本身的以太网地址作了回应(在这个例子中, 以太网地址以大写的名字标识, 而internet地址(即ip地址)以所有的小写名字标识).
二、若是使用 tcpdump -n
, 能够清晰看到以太网以及 ip地址而不是名字标识:
arp who-has 128.3.254.6 tell 128.3.254.68 arp reply 128.3.254.6 is-at 02:07:01:00:01:c4
三、若是咱们使用 tcpdump -e
, 则能够清晰的看到第一个数据包是全网广播的, 而第二个数据包是点对点的:
RTSG Broadcast 0806 64: arp who-has csam tell rtsg CSAM RTSG 0806 64: arp reply csam is-at CSAM
第一个数据包代表:以 arp包的源以太地址是RTSG, 目标地址是全以太网段, type域的值为16进制0806(表示ETHER_ARP即arp包的类型标识).包的总长度为64字节.
四、TCP 数据包
一般tcpdump对tcp数据包的显示格式以下:
src > dst: flags data-seqno ack window urgent options
src 和 dst 是源和目的 IP地址以及相应的端口. flags 标志由S(SYN), F(FIN), P(PUSH, R(RST)等组成,
单独一个.
表示没有flags标识. 数据段顺序号(Data-seqno)描述了此包中数据所对应序列号空间中的一个位置.
ack描述的是同一个链接,同一个方向,下一个本端应该接收的(对方应该发送的)数据片断的顺序号.
window是本端可用的数据接收缓冲区的大小(也是对方发送数据时需根据这个大小来组织数据).
urg(urgent) 表示数据包中有紧急的数据. options 描述了tcp的一些选项, 这些选项都用尖括号来表示(如 <mss 1024>
).
src, dst 和 flags 这三个域老是会被显示. 其余域的显示与否依赖于tcp协议头里的信息.
五、下面是一个从主机trsg到csam的一个rlogin应用登陆的开始阶段.
rtsg.1023 > csam.login: S 768512:768512(0) win 4096 <mss 1024> csam.login > rtsg.1023: S 947648:947648(0) ack 768513 win 4096 <mss 1024> rtsg.1023 > csam.login: . ack 1 win 4096 rtsg.1023 > csam.login: P 1:2(1) ack 1 win 4096 csam.login > rtsg.1023: . ack 2 win 4096 rtsg.1023 > csam.login: P 2:21(19) ack 1 win 4096 csam.login > rtsg.1023: P 1:2(1) ack 21 win 4077 csam.login > rtsg.1023: P 2:3(1) ack 21 win 4077 urg 1 csam.login > rtsg.1023: P 3:4(1) ack 21 win 4077 urg 1
第一行表示有一个数据包从rtsg主机的tcp端口1023发送到了csam主机的 tcp端口login上. S表示设置了 SYN标志. 包的顺序号是768512, 而且没有包含数据.
若是包含有数据,那么数据的表示格式为: first:last(nbytes)
, 其含义是此包中数据的顺序号从first开始直到last结束,不包括last. 而且总共包含nbytes的用户数据.
没有捎带应答即ack, 可用的接受窗口的大小为4096bytes, 而且请求端(rtsg)的最大可接受的数据段大小是1024字节.
主机csam 向主机rtsg 回复了基本相同的 SYN数据包, 其区别只是多了一个 piggy-backed ack
(nt:捎带回的ack应答, 针对rtsg的SYN数据包).
rtsg 一样针对csam的 SYN数据包回复了一 ACK数据包做为应答. .
的含义就是此包中没有标志被设置. 因为此应答包中不含有数据, 因此包中也没有数据段序列号.
提醒! 此ACK数据包的顺序号只是一个小整数1. 有以下解释:tcpdump对于一个tcp链接上的会话, 只打印会话两端的初始数据包的序列号,其后相应数据包只打印出与初始包序列号的差别.即初始序列号以后的序列号, 可被看做此会话上当前所传数据片断在整个要传输的数据中的’相对字节’位置(nt:双方的第一个位置都是1, 即’相对字节’的开始编号). -S
将覆盖这个功能,使数据包的原始顺序号被打印出来.
第六行的含义为:主机rtsg 向 主机csam发送了19字节的数据(字节的编号为2到20,传送方向为rtsg到csam). 包中设置了 PUSH标志.
在第7行,主机csam回应道, 她已经从主机rtsg中收到了21如下的字节, 但不包括21编号的字节. 这些字节存放在主机csam的socket的接收缓冲中, 相应地,csam的接收缓冲窗口大小会减小19字节(nt:能够从第5行和第7行win属性值的变化看出来). csam在第7行这个包中也向rtsg发送了一个字节. 在第8行和第9行, csam 继续向rtsg 分别发送了两个只包含一个字节的数据包, 而且这个数据包带PUSH标志.
若是头部含有虚假的属性信息(好比其长度属性其实比头部实际长度长或短), tcpdump会为该头部显示[bad opt]
.
若是头部的长度告诉咱们某些选项(nt | rt:从下文来看, 指tcp包的头部中针对ip包的一些选项, 回头再翻)会在此包中,而真正的IP(数据包的长度又不够容纳这些选项, tcpdump会显示[bad hdr length]
.
六、安装tshark抓包命令:
[root@hao-01 ~]# yum install -y wireshark
tshark 查看指定网卡,80端口的访问状况:
tshark -n -t a -R http.request -T fields -e "frame.time" -e "ip.src" -e "http.host" -e "http.request.method" -e "http.request.uri"
七、解决tcpdump "drop by kernel" 问题
tcpdump出现丢包 (网卡上drop计数没有
增长,网卡没有丢包),退出tcpdump时显示一下信息:
579204 packets captured
579346 packets received by filter
142 packets dropped by kernel
其中“captured”的计数指的是应用层捕获到的数据,“received by filter”和“dropped by kernel”的计数由内核维护,应用层经过getsockopt来获取。收到一个包,“received by filter”会加1,若是sock的接收buffer被填满时,则把这个数据包丢弃,将“dropped by kernel”加1。
丢包缘由:
通过google以及分析,形成这种丢包的缘由是因为libcap抓到包后,tcpdump上层没有及时的取出,致使libcap缓冲区溢出,从而覆盖了未处理包,此处即显示为dropped by kernel,注意,这里的kernel并非说是被linux内核抛弃的,而是被tcpdump的内核,即libcap抛弃掉的
缘由:Tcpdump 经过网络接口捕获原始数据包,数据包必须解析和执行过滤条件,执行过滤条件需
要耗费一些时间,所以传入数据包必须排队(数据缓存)进行处理,当数据包过多时(处理速度跟不
上缓存速度),缓存区就会被撑爆(缓存区大小默认是2M),此时就会丢弃新近的数据包,直到缓存
区有空间保存新到数据。
例如服务器给客户端发大量数据,Send的频率很高,
那么就有可能在Send时发生错误(缘由多是又多种,多是程序处理逻辑问题,多线程同步问题,缓冲区溢出问题等等)
若是没有对Send失败作处理重发数据,那么客户端收到的数据就会比理论应该收到的少,就会形成丢数据,丢包的现象。
这种现象,其实本质上来讲不是丢包,也不是丢数据,只是由于程序处理有错误,致使有些数据没有成功地被socket发送出去
解决方案:增大缓存区的大小。
1)tcpdump命令可使用 -B 参数来修改,单位是KiB。
2)libpap库中提供函数pcap_set_buffer_size() 。
解决方法:
根据以上分析,能够经过改善tcpdump上层的处理效率来减小丢包率,下面的几步根据须要选用,每一步都能减小必定的丢包率
1. 最小化抓取过滤范围,即经过指定网卡,端口,包流向,包大小减小包数量
2. 添加-n参数,禁止反向域名解析
3. 添加-B参数,加大OS capture buffer size
4. 指定-s参数, 最好小于1000
5. 将数据包输出到cap文件
6. 用sysctl修改SO_REVBUF参数,增长libcap缓冲区长 度(会增长延迟) : /proc/sys/net/core/rmem_default和/proc/sys/net/core/rmem_ma
七、查看链接数
# 查看nf_conntrack表最大链接数
$ cat /proc/sys/net/netfilter/nf_conntrack_max
65536
# 查看nf_conntrack表当前链接数
$ cat /proc/sys/net/netfilter/nf_conntrack_count
7611
当前链接数远没有达到跟踪表最大值,排除这个因素。
八、若是确认服务器因链接跟踪表溢出而开始丢包,首先须要查看具体链接判断是否正遭受DOS攻击,若是是正常的业务流量形成,能够考虑调整nf_conntrack的参数:
nf_conntrack_max决定链接跟踪表的大小,默认值是65535,能够根据系统内存大小计算一个合理值:CONNTRACK_MAX = RAMSIZE(in bytes)/16384/(ARCH/32),如32G内存能够设置1048576;
nf_conntrack_buckets决定存储conntrack条目的哈希表大小,默认值是nf_conntrack_max的1/4,延续这种计算方式:BUCKETS = CONNTRACK_MAX/4,如32G内存能够设置262144;
nf_conntrack_tcp_timeout_established决定ESTABLISHED状态链接的超时时间,默认值是5天,能够缩短到1小时,即3600。
修改链接数大小 :
$ sysctl -w net.netfilter.nf_conntrack_max=1048576 $ sysctl -w net.netfilter.nf_conntrack_buckets=262144 $ sysctl -w net.netfilter.nf_conntrack_tcp_timeout_established=3600
九、
十、
参考 :
经过实例学习 tcpdump 命令 : https://mp.weixin.qq.com/s/VtUWwXYUg96EmFKiHTkrIA
一文搞定tcpdump基本用法 : https://blog.csdn.net/chinaltx/article/details/87469933
tcpdump抓包分析,快速完成接口调试 : https://blog.51cto.com/14010723/2300392