失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > linux如何查看丢弃数据包 导致Linux服务器丢弃数据包?

linux如何查看丢弃数据包 导致Linux服务器丢弃数据包?

时间:2019-06-17 17:22:26

相关推荐

linux如何查看丢弃数据包 导致Linux服务器丢弃数据包?

我们使用Linux作为服务器操作系统时,为了达到高并发处理能力,充分利用机器性能,经常会进行一些内核参数的调整优化,但不合理的调整常常也会引起意想不到的其他问题,本文就一次Linux服务器丢包故障的处理过程,结合Linux内核参数说明和TCP/IP协议栈相关的理论,介绍一些常见的丢包故障定位方法和解决思路。

问题现象

本次故障的反馈现象是:从办公网访问公网服务器不稳定,服务器某些端口访问经常超时,但Ping测试显示客户端与服务器的链路始终是稳定低延迟的。

通过在服务器端抓包,发现还有几个特点:

从办公网访问服务器有多个客户端,是同一个出口IP,有少部分是始终能够稳定连接的,另一部分间歇访问超时或延迟很高

同一时刻的访问,无论哪个客户端的数据包先到达,服务端会及时处理部分客户端的SYN请求,对另一部分客户端的SYN包“视而不见”,如tcpdump数据所示,源端口为56909的SYN请求没有得到响应,同一时间源端口为50212的另一客户端SYN请求马上得到响应。

Shell

1

2

3

4

5

6

7

8

9

10

11

$sudotcpdump-ieth0port22and"tcp[tcpflags] & (tcp-syn) != 0"

18:56:37.404603IPCLIENT.56909>SERVER.22:Flags[S],seq1190606850,win29200,options[mss1448,sackOK,TSval198321481ecr0,nop,wscale7],length0

18:56:38.404582IPCLIENT.56909>SERVER.22:Flags[S],seq1190606850,win29200,options[mss1448,sackOK,TSval198321731ecr0,nop,wscale7],length0

18:56:40.407289IPCLIENT.56909>SERVER.22:Flags[S],seq1190606850,win29200,options[mss1448,sackOK,TSval198322232ecr0,nop,wscale7],length0

18:56:44.416108IPCLIENT.56909>SERVER.22:Flags[S],seq1190606850,win29200,options[mss1448,sackOK,TSval198323234ecr0,nop,wscale7],length0

18:56:45.100033IPCLIENT.50212>SERVER.22:Flags[S],seq4207350463,win65535,options[mss1366,nop,wscale5,nop,nop,TSval821068631ecr0,sackOK,eol],length0

18:56:45.100110IPSERVER.22>CLIENT.50212:Flags[S.],seq1281140899,ack4207350464,win27960,options[mss1410,sackOK,TSval1709997543ecr821068631,nop,wscale7],length0

18:56:52.439086IPCLIENT.56909>SERVER.22:Flags[S],seq1190606850,win29200,options[mss1448,sackOK,TSval198325240ecr0,nop,wscale7],length0

18:57:08.472825IPCLIENT.56909>SERVER.22:Flags[S],seq1190606850,win29200,options[mss1448,sackOK,TSval198329248ecr0,nop,wscale7],length0

18:57:40.535621IPCLIENT.56909>SERVER.22:Flags[S],seq1190606850,win29200,options[mss1448,sackOK,TSval198337264ecr0,nop,wscale7],length0

18:57:40.535698IPSERVER.22>CLIENT.56909:Flags[S.],seq3621462255,ack1190606851,win27960,options[mss1410,sackOK,TSval1710011402ecr198337264,nop,wscale7],length0

排查过程

服务器能正常接收到数据包,问题可以限定在两种可能:部分客户端发出的数据包本身异常;服务器处理部分客户端的数据包时触发了某种机制丢弃了数据包。因为出问题的客户端能够正常访问公网上其他服务,后者的可能性更大。

有哪些情况会导致Linux服务器丢弃数据包?

防火墙拦截

服务器端口无法连接,通常就是查看防火墙配置了,虽然这里已经确认同一个出口IP的客户端有的能够正常访问,但也不排除配置了DROP特定端口范围的可能性。

如何确认

查看iptables filter表,确认是否有相应规则会导致此丢包行为:

Shell

1

$sudoiptables-save-tfilter

这里容易排除防火墙拦截的可能性。

连接跟踪表溢出

除了防火墙本身配置DROP规则外,与防火墙有关的还有连接跟踪表nf_conntrack,Linux为每个经过内核网络栈的数据包,生成一个新的连接记录项,当服务器处理的连接过多时,连接跟踪表被打满,服务器会丢弃新建连接的数据包。

如何确认

通过dmesg可以确认是否有该情况发生:

Shell

1

$dmesg|grepnf_conntrack

如果输出值中有“nf_conntrack: table full, dropping packet”,说明服务器nf_conntrack表已经被打满。

通过/proc文件系统查看nf_conntrack表实时状态:

Shell

1

2

3

4

5

6

# 查看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。

Shell

1

2

3

$sysctl-filter.nf_conntrack_max=1048576

$sysctl-filter.nf_conntrack_buckets=262144

$sysctl-filter.nf_conntrack_tcp_timeout_established=3600

如果觉得《linux如何查看丢弃数据包 导致Linux服务器丢弃数据包?》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。