找到网站有时能打开有时打不开原因

公司网络是一个大的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