找到网站有时能打开有时打不开原因
25 Mar 2013公司网络是一个大的NAT环境,网站的环境也是通过NAT实现的,打开网站一段时间好一段时间又不正常,表现为找不到网站主机,主要表现在winxp和linux 客户端。1、在服务器抓包,发现服务端可以收到客户端的SYN请求,但是没有回应SYN,ACK,也就是说内核直接将包丢弃了;2、通过NAT出口的客户端经常请求Web服务器无响应,telnet服务器端口不通,但是可以ping通。今天看到老王的博客上的一篇文章记一次TIME_WAIT网络故障 恍然大悟。
主要是tcptwrecycle和tcp_timestamps同时开启引起的。
解决方法: 1) 关闭服务其端的tcptimestamps,故障解决,但是这么做存在安全和性能隐患; 2) 关闭tcptw_recycle,故障也可以解决。推荐NAT环境下的机器不要开启该选项;
echo 0 > /proc/sys/net/ipv4/tcp_tw_recycle;
3) 也就是说这两个参数不可能同时启用。
原因:
1) 当tcptwrecycle和tcp_timestamps同时打开时会激活TCP的一种隐藏属性:缓存连接的时间戳。60秒内,同一源IP的后续请求的时间戳小于缓存中的时间戳,内核就会丢弃该请求。NAT只改IP地址信息,但不会改变timestamp(TCP的时间戳不是系统时间,而是系统启动的时间uptime,所以两台机器的的TCP时间戳一致的可能性很小),所以很容易造成连接失败的情况。
2) TIMEWAIT状态是用于保障连接正常关闭的,并不会消耗过多资源。在高并发环境中tcptwrecycle和tcptwreuse经常被打开用户快速回收和重用TIMEWAIT状态的socket,在资源有限的情况下这么多也无可厚非,不过也应该知道这么做会带来的后果。
附:
net.ipv4.tcptwreuse = 1 表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭; net.ipv4.tcptwrecycle = 1 表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。
源码函数:tcpv4connrequest(),该函数是tcp层三次握手syn包的处理函数(服务端); 源码片段: if (tmpopt.sawtstamp && tcpdeathrow.sysctltwrecycle && (dst = inetcskroutereq(sk, req)) != NULL && (peer = rtgetpeer((struct rtable *)dst)) != NULL && peer->v4daddr == saddr) { if (getseconds() < peer->tcptsstamp + TCPPAWSMSL && (s32)(peer->tcpts - req->tsrecent) > TCPPAWSWINDOW) { NETINCSTATSBH(socknet(sk), LINUXMIBPAWSPASSIVEREJECTED); goto dropandrelease; } } tmpopt.sawtstamp:该socket支持tcptimestamp sysctltwrecycle:本机系统开启tcptwrecycle选项 TCPPAWSMSL:60s,该条件判断表示该源ip的上次tcp通讯发生在60s内 TCPPAWSWINDOW:1,该条件判断表示该源ip的上次tcp通讯的timestamp 大于 本次tcp