查看网络丢包的命令

查看网络丢包
$ sudo tcpdump -i eth0 port 22 and "tcp[tcpflags] & (tcp-syn)
!= 0"html

 

网络丢包的缘由


防火墙拦截
查看iptables filter表,确认是否有相应规则会致使此丢包行为:

$ sudo iptables-save -t filtercentos

 

链接跟踪表溢出
经过dmesg能够确认是否有该状况发生:

 
$ dmesg |grep nf_conntrack
若是输出值中有“nf_conntrack: table full, dropping packet”,说
明服务器nf_conntrack表已经被打满。缓存

经过/proc文件系统查看nf_conntrack表实时状态:服务器


# 查看nf_conntrack表最大链接数
$ cat /proc/sys/net/netfilter/nf_conntrack_max
65536
# 查看nf_conntrack表当前链接数
$ cat /proc/sys/net/netfilter/nf_conntrack_count
7611cookie

如何解决网络

若是确认服务器因链接跟踪表溢出而开始丢包,首先须要查看具体链接判断是否正遭受DOS攻击,若是是正常的业务流量形成,能够考虑调整nf_conntrack的参数:app

nf_conntrack_max决定链接跟踪表的大小,默认值是65535,能够根据系统内存大小计算一个合理值:CONNTRACK_MAX = RAMSIZE(in bytes)/16384/(ARCH/32),如32G内存能够设置1048576;tcp

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

 

 

Ring Buffer溢出

物理介质上的数据帧到达后首先由NIC(网络适配器)读取,写入设备内部缓冲区Ring Buffer中,再由中断处理程序触发Softirq从中消费,Ring Buffer的大小因网卡设备而异。当网络数据包到达(生产)的速率快于内核处理(消费)的速率时,Ring Buffer很快会被填满,新来的数据包将被丢弃。

如何确认

经过ethtool或/proc/net/dev能够查看因Ring Buffer满而丢弃的包统计
,在统计项中以fifo标识:

 

$ ethtool -S eth0|grep rx_fifo
rx_fifo_errors: 0
$ cat /proc/net/dev

能够看到服务器的接收方向的fifo丢包数并无增长,这里天然也排除这个缘由。
如何解决

若是发现服务器上某个网卡的fifo数持续增大,能够去确认CPU中断是否
分配均匀,也能够尝试增长Ring Buffer的大小,经过ethtool能够查看
网卡设备Ring Buffer最大值,修改Ring Buffer当前设置:

# 查看eth0网卡Ring Buffersize状况最大值和当前设置
$ ethtool -g eth0

# 修改网卡eth0接收与发送硬件缓存区大小
$ ethtool -G eth0 rx 4096 tx 4096

 

netdev_max_backlog溢出

netdev_max_backlog是内核从NIC收到包后,交由协议栈(如IP、TCP)处理以前的缓冲队列。每一个CPU核都有一个backlog队列,与Ring Buffer同理,当接收包的速率大于内核协议栈处理的速率时,CPU的backlog队列不断增加,当达到设定的netdev_max_backlog值时,数据包将被丢弃。


如何确认
经过查看/proc/net/softnet_stat能够肯定是否发生了netdev backlog队列溢出:

$ cat /proc/net/softnet_stat
01a7b464 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
01d4d71f 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
0349e798 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
017e0826 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000

其中:
每一行表明每一个CPU核的状态统计,从CPU0依次往下;
每一列表明一个CPU核的各项统计:第一列表明中断处理程序收到的包总数;第二列即表明因为netdev_max_backlog队列溢出而被丢弃的包总数。
从上面的输出能够看出,这台服务器统计中,并没有由于netdev_max_backlog致使的丢包。

如何解决
netdev_max_backlog的默认值是1000,在高速链路上,可能会出现上述第二列统计不为0的状况,能够经过修改内核参数net.core.netdev_max_backlog来解决:

$ sysctl -w net.core.netdev_max_backlog=2000

 

反向路由过滤

反向路由过滤机制是Linux经过反向路由查询,检查收到的数据包源IP是否可路由(Loose mode)、是否最佳路由(Strict mode),若是没有经过验证,则丢弃数据包,设计的目的是防范IP地址欺骗攻击。rp_filter提供了三种模式供配置:

  • 0 - 不验证
  • 1 - RFC3704定义的严格模式:对每一个收到的数据包,查询反向路由,若是数据包入口和反向路由出口不一致,则不经过
  • 2 - RFC3704定义的松散模式:对每一个收到的数据包,查询反向路由,若是任何接口都不可达,则不经过

如何确认
查看当前rp_filter策略配置:

$ cat /proc/sys/net/ipv4/conf/eth0/rp_filter

若是这里设置为1,就须要查看主机的网络环境和路由策略是否可能会致使客户端的入包没法经过反向路由验证了。

从原理来看这个机制工做在网络层,所以,若是客户端可以Ping通服务器,就可以排除这个因素了。

如何解决
根据实际网络环境将rp_filter设置为0或2:

$ sysctl -w net.ipv4.conf.all.rp_filter=2
 
或
 
$ sysctl -w net.ipv4.conf.eth0.rp_filter=2

 

半链接队列溢出

半链接队列指的是TCP传输中服务器收到SYN包但还未完成三次握手的链接队列,队列大小由内核参数tcp_max_syn_backlog定义。

当服务器保持的半链接数量达到tcp_max_syn_backlog后,内核将会丢弃新来的SYN包。

如何确认
经过dmesg能够确认是否有该状况发生:

$ dmesg | grep "TCP: drop open request from"

半链接队列的链接数量能够经过netstat统计SYN_RECV状态的链接得知

$ netstat -ant|grep SYN_RECV|wc -l
0

大多数状况下这个值应该是0或很小,由于半链接状态从第一次握手完成时进入,第三次握手完成后退出,正常的网络环境中这个过程发生很快,若是这个值较大,服务器极有可能受到了SYN Flood攻击。

如何解决
tcp_max_syn_backlog的默认值是256,一般推荐内存大于128MB的服务器能够将该值调高至1024,内存小于32MB的服务器调低到128,一样,该参数经过sysctl修改:

$ sysctl -w net.ipv4.tcp_max_syn_backlog=1024

 

上述行为受到内核参数tcp_syncookies的影响,若启用syncookie机制,当半链接队列溢出时,并不会直接丢弃SYN包,而是回复带有syncookie的SYC+ACK包,设计的目的是防范SYN Flood形成正常请求服务不可用。

$ sysctl -w net.ipv4.tcp_syncookies=1
net.ipv4.tcp_syncookies = 1

 

PAWS

PAWS全名Protect Againest Wrapped Sequence numbers,目的是解决在高带宽下,TCP序列号在一次会话中可能被重复使用而带来的问题。

TIME_WAIT状态的链接须要占用服务器内存资源维持,Linux内核提供了一个参数来控制TIME_WAIT状态的快速回收:tcp_tw_recycle,它的理论依据是:

如何确认
经过netstat能够获得因PAWS机制timestamp验证被丢弃的数据包统计:

$ netstat -s |grep -e "passive connections rejected because of time stamp" -e "packets rejects in established connections because of timestamp”
387158 passive connections rejected because of time stamp
825313 packets rejects in established connections because of timestamp

经过sysctl查看是否启用了tcp_tw_recycle及tcp_timestamp :

$ sysctl net.ipv4.tcp_tw_recycle
net.ipv4.tcp_tw_recycle = 1
$ sysctl net.ipv4.tcp_timestamps
net.ipv4.tcp_timestamps = 1

此次问题正是由于服务器同时开启了tcp_tw_recycle和timestamps,而客户端正是使用NAT来访问服务器,形成启动时间相对较短的客户端得不到服务器的正常响应。

如何解决
若是服务器做为服务端提供服务,且明确客户端会经过NAT网络访问,或服务器以前有7层转发设备会替换客户端源IP时,是不该该开启tcp_tw_recycle的,而timestamps除了支持tcp_tw_recycle外还被其余机制依赖,推荐继续开启:

$ sysctl -w net.ipv4.tcp_tw_recycle=0
$ sysctl -w net.ipv4.tcp_timestamps=1

 

经过dropwatch定位系统内核丢包

ropwatch使用前提:

一、首先内核必须大于等于2.6.30;
二、编译内核时应该加上“NET_DROP_MONITOR=y”;
三、因为dropwatch是依赖Kernel Tracepoint API的,其原理是各个协议层释放skb时收集信息来判断有无丢包,用的很少,不免存在一些BUG致使内核crash,所以具有必定危险性,建议troubleshooting时,最好先切走业务;
 

使用方法:

一、笔者使用的系统是CentOS 6.3,首先须要经过yum安装dropwatch:"yum install dropwatch -y”

二、带参数运行dropwatch:"dropwatch -l kas”,不带参数运行,默认输出的是各个函数的地址信息,不便于观察;

补充一下,使用 -l kas后,会经过“/proc/kallsysms”去映射地址和符号表的对应关系,实测会出各类问题甚至死机,建议不要这么作;能够本身经过/boot/System.Map去查询。

三、开始抓取内核丢包数据:”start”:

[root@localhost ~]$sudo dropwatch -l kas
Initalizing kallsyms db
dropwatch>start
Enabling monitoring...
Kernel monitoring activated.
Issue Ctrl-C to stop monitoring
1 drops at netlink_unicast+251 (0xffffffff814639c1)
1 drops at init_dummy_netdev+50 (0xffffffff81438a10)
2 drops at init_dummy_netdev+50 (0xffffffff81438a10)
2 drops at init_dummy_netdev+50 (0xffffffff81438a10)

1 drops at udp_queue_rcv_skb+953 (0xffffffff8149b113)

2 drops at init_dummy_netdev+50 (0xffffffff81438a10)
1 drops at init_dummy_netdev+50 (0xffffffff81438a10)
1 drops at icmp_sk_init+317 (0xffffffff8149e557)
^CGot a stop messagedropwatch>

 

网卡的驱动程序

ethtool -i eth0 //找到驱动driver: pcnet32

lsmod //找到使用的驱动模块,在里面结果里面找。ps:lsmod | grep pcnet32

 

网络测试工具

mtr 默认发送 ICMP 数据包进行链路探测,经过 -u 参数来指定 UDP 数据包用于探测。相对于 traceroute 只做一次链路跟踪测试,mtr 会对链路上的相关节点作持续探测并给出相应的统计信息。mtr 能避免节点波动对测试结果的影响,因此其测试结果更正确,建议优先使用。

[root@centos ~]# mtr 223.5.5.5

     二、My traceroute [v0.75]

  三、mycentos6.6 (0.0.0.0) Wed Jun 15 23:16:27 2016

     四、Keys: Help Display mode Restart statistics Order of fields quit

     五、Packets Pings

     六、Host Loss% Snt Last Avg Best Wrst StDev

     七、1. ???

     八、2. 192.168.17.20 0.0% 7 13.1 5.6 2.1 14.7 5.7

 默认配置下,返回结果中各数据列的说明以下:

 

  第一列(Host):节点 IP 地址和域名。如前面所示,按 n 键能够切换显示。

  第二列(Loss%):节点丢包率。

  第三列(Snt):每秒发送数据包数。默认值是 10,能够经过参数 -c 指定。

  第四列(Last):最近一次的探测延迟值。

  第5、6、七列(Avg、Best、Wrst):分别是探测延迟的平均值、最小值和最大值。

  第八列(StDev):标准误差。越大说明相应节点越不稳定。

 

 

 

 

 

 

 

转载于:https://www.cnblogs.com/276815076/p/5736272.html

相关文章
相关标签/搜索