linux – 服务器不响应SYN数据包发送SYN / ACK数据包

前端之家收集整理的这篇文章主要介绍了linux – 服务器不响应SYN数据包发送SYN / ACK数据包前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
使用iptraf,tcpdump和wireshark我可以看到一个SYN数据包进入,但只有ACK FLAG被设置在回复数据包中.

我正在使用内核2.6.36运行Debian 5

我已经关闭了window_scaling和tcp_timestamps,tcp_tw_recycle和tcp_tw_reuse:

cat /etc/sysctl.conf 



net.ipv4.tcp_tw_recycle = 0
net.ipv4.tcp_tw_reuse = 0
net.ipv4.tcp_window_scaling = 0
net.ipv4.tcp_timestamps = 0

我附上了wireshark输出的图像.

http://imgur.com/pECG0.png

输出到netstat

netstat -natu | grep '72.23.130.104'

tcp        0      0 97.107.134.212:18000    72.23.130.104:42905     SYN_RECV

我一直在尽一切可能找到解决方案并且还没有弄清楚问题,所以非常感谢任何帮助/建议.

更新1:我已设置tcp_syncookies = 0并注意到我现在每回复50个SYN请求回复1个SYN ACK.尝试连接的主机每秒发送一次SYN请求.

PCAP FILE

解决方法

在遇到同样的问题后,我终于找到了根本原因.

在Linux上,当套接字在TIME_WAIT上并且新的SYN附加(对于同一对ip / port src,ip / port dest)时,内核检查SYN的SEQ号是否为<或>比这个插座收到的最后一个SEQ.

(PS:在附加到此问题的wireshark输出的图像中,seq编号显示为相对,如果您没有将它们设置为绝对,则无法看到问题.捕获将必须显示旧会话也能够比较SEQ数字)

>如果SYN的SEQ ID是>比起前一个数据包的SEQ号,一个新的连接被装箱,一切正常
>如果SYN的SEQ ID是<与前一个数据包的SEQ号相比,内核将发送与前一个套接字相关的ACK,因为内核认为收到的SYN是前一个套接字的延迟数据包.
行为是这样的,因为在TCP的开始处由计算机生成的SEQ号增量,几乎不可能接收到SEQ ID<比仍在TIME_WAIT中的前一个套接字的SEQ号. 计算机带宽的增加使得这几乎不可能实现.但最重要的是,现在大多数系统使用随机ISN(初始SEQ号)来提高安全性.因此,没有什么能阻止新套接字的SEQ号a>比前一个的SEQ号. 每个操作系统都使用不同的算法,这些算法或多或少都是安全的,可以避
http://www.bsdcan.org/2006/papers/ImprovingTCPIP.pdf很好地介绍了这个问题.

还有一些棘手的事情……所以内核会发送一个与旧会话相关的ACK,然后呢?客户端操作系统应该接收(先前会话的)ACK,不理解它,因为对于客户端会话关闭,发送RST.当服务器收到此RST时,它将立即清除套接字(因此它不再在TIME_WAIT中).
在他的一边,客户端正在等待SYN / ACK,因为它没有得到它,它将发送一个新的SYN.同时RST已经发送并且服务器上的会话被清除,因此这个辅助SYN将起作用,服务器将回复SYN / ACK,依此类推.

所以正常的行为是连接应该工作但延迟一秒(直到发送辅助SYN).在杰夫的案例中,他在评论中说他使用的是Fortinet防火墙,这些防火墙(默认情况下)会丢弃与旧会话相关的ACK(因为防火墙看不到与ACK相关的开放会话),所以客户端没有发送任何RST并且服务器无法从TIME_WAIT状态清除会话(当然除了TIME_WAIT计时器结束时).fortinet上的“set anti-replay loose”命令可以允许转发此ACK数据包而不是丢弃.

猜你在找的Linux相关文章