主题:【求助】关于网站大量 Error 001 应对 -- 铁手
和TIME_WAIT,相对而言,ESTABLISHED的数量并不多。
Established状态 的不多。主要是 ip_conntrack 里面的记录数量在不断增加,而且大部分是“Established”,而这些“Established” time out 的时间又是比较长的。
网上查了一下,似乎net.ipv4.tcp_tw_recycle=1这个比较容易导致问题,建议使用net.ipv4.tcp_tw_recycle = 1。我试试这个看看。
不过我估计还是没用,因为问题似乎不在 netstat 里面的内容,而是和 ip_conntract 相关,这两个似乎不一样。我的理解,后者是和防火墙有关系的,前者只是一般意义上的链接状态。
cat /proc/net/ip_conntrack | awk '{print substr($5, index($5,"=")+1) }' | awk '{a[$1]+=1};END {for( i in a){print i,a[ i ] }}' | sort -n -k 2
结果里面,在某些 ip 后面,有几千的值。至少有500个IP,后面的数值在几十到几百之间。
手头没有iptables的详细资料。我的猜测是iptables里的established和Tcp的established概念不同。
iptables作为一个防火墙可能带有一个连接代理的功能。当连接进来时先代理连接(或者建立连接管理数据表项),之后再转发到TCP/IP的协议栈。这样从Iptable的established指的是防火墙处理的连接。而netstate看到的就是已经过滤的本机的TCP连接。具体的要看iptables的详细说明。如果我猜测正确的话,那些timeout值都是为了遵循TCP协议规定的默认值。可以很放心地根据实际情况缩短。
另外,看看规则上能不能过滤掉这些多余的established连接。
我是最近才正式开始在linux上干活,以上都是猜测,仅做参考。
如果比例比较大,超过30%的话,设这个参数就是有用的。
每个tcp连接都会占用iptable的entry,所以连接数是第一重要的,要先解决连接数问题。然后可能是iptable的entry超时时间的控制。默认的conntrak超时时间比较长。不过这个要看你的iptables具体使用环境而定。
看看你那几千个连接的Ip是不是都在Time_wait或FIN_WAIT1上
这个状态多出现在慢速的连接上,服务器主动关闭连接发送完FIN标志后就处在FIN_WAIT1状态,直到收到客户端的ACK,之后收到客户端发来的FIN,并送出ACK后进入TIME_WAIT状态。处于TIME_WAIT状态的时间是最大包生存时间(MSL for Maximum Segment Lifetime)的两倍。因此一般是2分钟到4分钟时间。
如果连接速度慢那么处在FIN_WAIT1的时间就比较长,搞不好还收不到——如果客户端断掉,或者客户端程序/NAT路由器没有正确处理TCP优雅关闭问题,那么服务器会试图多次重新传送FIN,直到超过重传次数。这个时间甚至可能比TIME_WAIT还长。
影响这两个时间的参数大致有:
MSL——看什么系统可能是30秒也可能是120秒
TCP重试次数,有两个,一个是决定多少次报错,另一个是决定多少次关闭
还有一个是FIN_WAIT2的时间,这个是服务器收到客户端对自己FIN的ACK后进入等待客户端FIN的时间。对于WEB服务器来说这个可以很短(10秒就足够了,因为HTTP客户端肯定不会再发数据过来)
调整这些参数可以缩短上述状态的时间,从而快速释放连接。但是需要注意这些参数同时影响正常的通信
一般用户不应该有几千个连接的。
看看下面的网页,希望有帮助
http://www.heartdemon.com/post/154.html
因为ip_contrack中保存的是一段时间类的链接情况,是累计值。
再执行一下
netstat -an | grep ESTABLISHED | awk '{print substr($5, 1 , index($5,":")-1) }'| awk '{a[$1]+=1};END {for( i in a){print i,a[ i ] }}' | sort -n -k 2
看一下当前链接状态ip统计。
ipconntrack的另外一些参数也看一下,
sysctl -a | grep conntrack
注意ip_conntrack_tcp_timeout_established和ip_conntrack_max。
net.ipv4.netfilter.ip_conntrack_tcp_timeout_established = 432000
net.ipv4.netfilter.ip_conntrack_max = 1048576
建议和我设成一样,缩小timeout,增加max。
另外有个大杀器,既然是table full,那么可以在crontab中加一个任务,定时清理ip_conntrack,呵呵。
当然这样做比较暴力,一般合理调整上面两个值就够了。
这个应该也是一个问题,但是感觉上还不致命。致命的可能是
/proc/sys/net/ipv4/netfilter/ip_conntrack_count
越来越大,超过
/proc/sys/net/ipv4/ip_conntrack_max
一旦超过,就马上出现 error 001。
max 值我已经加大过好几次,虽然还有空间可以加,不过总是想知道到底是什么因素导致 ip_conntrack_count 不断增加。
我注意了一下,在里面的ip 地址里,有不少是只有最后一个值不同,前三位都一样,这个看起来比较邪门。
.ip_conntrack_tcp_timeout_established = 432000 为什么还保留在5天?按我的理解,如果是 web 服务,5分钟应该到头了吧。保留时间长,是不是为了防火墙能够在一段时间内,比如5天内的链接情况来进行判断?
默认TCP空连接是4天到期,这个数值可以缩短。Web服务器的话5分钟是没有问题的。
原理如下,采取何种措施,看具体情况。下面的“【整理】中文网站里面很多内容值得参考。”回帖也说的很详细了。
Adrian Otto
28.07.09 at 10:19
Some readers may be interested to know what ip_conntrack is in the first place, and why it fills up. If you run an iptables firewall, and have rules that act upon the state of a packet, then the kernel uses ip_conntrack to keep track of what state what connections are in so that the firewall rule logic can be applied against them. If you have a system that's getting a lot of network activity (high rates of connections, lots of concurrent connections, etc) then the table will accumulate entries.
The entries remain until an RST packet is sent from the original IP address. If you have a flaky network somewhere between you, and the clients accessing your server, it can cause the RST packets to be dropped due to the packet loss, and leave orphaned entries in your ip_conntrack table. This can also happen if you have a malfunctioning switch or NIC card... not necessarily a routing problem out on the internet somewhere.
Typically when I've seen this trouble crop up is when a server is the target of a DDoS attack. Filling up the ip_conntrack table is a relatively easy way to knock a server off line, and attackers know this.
As Major suggested, you can get short term relief by increasing the size of the table. However, these entries are held in memory by the kernel. The bigger you make the table, the more memory it will consume. That memory could be used by your server to serve requests if you really don't need the stateful firewall capability. Don't waste resources on this feature if you really don't need it.
Another option to consider is turning OFF iptables rules that use ip_conntrack so the state able is not used at all. Anything with "-m state" or "-t nat" can be turned off. If you want to just flush all your iptables rules you can do an "iptables -P" to set a default allow policy and "iptables -F" to flush all the rules. On an RHEL or CentOS system you can just do "service iptables stop".
Once iptables is no longer using ip_conntrack, you can reclaim the memory the table was using by unloading the related kernel modules.
rmmod ipt_MASQUERADE
rmmod iptable_nat
rmmod ipt_state
rmmod ip_conntrack
Then you will have an empty ip_conntrack that will stay empty. I mention this because a lot of sysadmins have hordes of iptables rules installed as a matter of course, and don't recognize the downside of having them present. You can still use iptables, but to avoid the use of ip_conntrack simply don't use rules based on stateful logic.
man iptables 查看 --ctstate 内容,如果防火墙没有依赖这些东西,可以把内核关于 ip_conntrack 的模块黑名单了。
上次就说了是43200.
另外,目前我们生产环境中net.ipv4.netfilter.ip_conntrack_tcp_timeout_established设置为43200.不过我们前端有防dds攻击的策略。
设为5分钟对web服务器来说是可以的,但是不利于保留历史记录进行分析,当然了,如果不需要分析,那就设小一点。
另外netstat分析当前连接数情况如何,如果怀疑那批类似的ip是攻击方,可以在iptable中过滤,但是我觉得可能性不多。真正的ddos攻击不会这么麻烦。
现在看来ddos的攻击可能性不大,因为并发量还真不算大,要真是ddos攻击应该就打死了;而且ddos攻击讲究瞬间上很大的量,一般要打死位置,不会象现在这样还能用,而且一般也就持续几天几周。
06年我有个朋友自己做了婴童产品的网站,做的不错,国内做到前几名,结果被竞争对手请黑客进行ddos攻击。攻击持续一周,流量一直很大,导致这一周网站都打不开。等一周以后,ddos攻击没了,客户也流失的差不多了,就倒闭了。
09年时候他又做了个电子产品的b2c网站,也受到了ddos攻击,这次他就扛住了:-)
几千个链接是可能的。
所以关键还是要用netstat看看当前ESTABLISHED链接的分ip统计情况。