服务器环境

服务商:阿里云
配置:32核128G
系统:Centos6

故障

引子

在排查阿里云服务器故障的时候,需要yum install一个软件。但是发现不能解析域名,随手添加了114dns,依然不行。随后ping 114dns地址,返回如下错误信息:

ping  8.8.8.8;ping: sendmsg: Operation not permitted
ping  114.114.114.114;ping: sendmsg: Operation not permitted
ping  127.0.0.1;ping: sendmsg: Operation not permitted

逐引出nf_conntrack: table full, dropping packet故障。

负载和进程

排查系统负载大约在2左右(32核128G内存配置),没有发现恶意进程在运行。

防火墙

只开放了业务需要的端口,其他的都默认DROP了。

系统&内核日志

使用dmesg查看内存日志的时候发现一堆错误:"连接跟踪表已满,开始丢包",按照以前用cenots6的经验,应该就是iptables的问题了。

nf_conntrack: table full, dropping packet.
nf_conntrack: table full, dropping packet.
nf_conntrack: table full, dropping packet.
nf_conntrack: table full, dropping packet.
nf_conntrack: table full, dropping packet.
nf_conntrack: table full, dropping packet.
nf_conntrack: table full, dropping packet.
__ratelimit: 7825 callbacks suppressed
nf_conntrack: table full, dropping packet.
nf_conntrack: table full, dropping packet.
nf_conntrack: table full, dropping packet.
nf_conntrack: table full, dropping packet.
nf_conntrack: table full, dropping packet.
nf_conntrack: table full, dropping packet.
nf_conntrack: table full, dropping packet.
nf_conntrack: table full, dropping packet.
nf_conntrack: table full, dropping packet.
nf_conntrack: table full, dropping packet.
__ratelimit: 8295 callbacks suppressed

解决

方法一

关闭防火墙,这个最直接,但裸奔不太好。

chkconfig iptables off 
chkconfig ip6tables off 
service iptables stop 
service ip6tables stop 

方法二

参数调优

加大防火墙跟踪表的大小,优化对应的系统参数

1.状态跟踪表的最大行数的设定,理论最大值 CONNTRACK_MAX = RAMSIZE (in bytes) / 16384 / (ARCH / 32),以128G的64位操作系统为例,CONNTRACK_MAX = 128*1024*1024*1024/16384/2 = 4194304
即时生效请执行:

sysctl –w net.netfilter.nf_conntrack_max = 4194304

2.其哈希表大小通常为总表的1/8,最大为1/2。CONNTRACK_BUCKETS = CONNTRACK_MAX / 8

同样128G的64位操作系统,哈希最佳范围是 262144 ~ 1048576 。
运行状态中通过 `sysctl net.netfilter.nf_conntrack_buckets` 进行查看,通过文件`/sys/module/nf_conntrack/parameters/hashsize` 进行设置或者新建 `/etc/modprobe.d/iptables.conf` ,重新加载模块才生效:

options nf_conntrack hashsize = 524288

3.还有些相关的系统参数sysctl -a | grep nf_conntrack可以调优(/etc/sysctl.conf )

net.netfilter.nf_conntrack_max  =   1048576  
net.netfilter.ip_conntrack_tcp_timeout_established  =   3600  
net.netfilter.nf_conntrack_tcp_timeout_close_wait  =   60  
net.netfilter.nf_conntrack_tcp_timeout_fin_wait  =   120  
net.netfilter.nf_conntrack_tcp_timeout_time_wait  =   120 

使用裸表

使用祼表,添加“不跟踪”标识。如下示例更适合桌面系统或随意性强的服务器。因为它开启了连接的状态机制,方便和外部通信。修改 /etc/sysconfig/iptables文件:

*raw 
# 对TCP连接不启用追踪,解决ip_contrack满导致无法连接的问题 
-A PREROUTING -p tcp -m tcp --dport 80 -j NOTRACK 
-A PREROUTING -p tcp -m tcp --dport 22 -j NOTRACK 
-A PREROUTING -p tcp -m tcp --dport 21 -j NOTRACK 
-A PREROUTING -p tcp -m tcp --dport 11211 -j NOTRACK 
-A PREROUTING -p tcp -m tcp --dport 60000:60100 -j NOTRACK 
.....

测试

再次测试发现一切都安静了^-^

参考资料

文章目录