解决这类问题,方法很重要,最好的做法其实是阅读官方的RFC,源码,然后进行实际测试验证。
tcp_timestamps,tcp_tw_reuse,tcp_tw_recycle
几篇比较好的解释这三个参数的文章:
https://serverfault.com/questions/502305/linux-networking-port-exhaustion
http://perthcharles.github.io/2015/08/27/timestamp-intro/
http://perthcharles.github.io/2015/08/27/timestamp-NAT/
https://vincent.bernat.im/en/blog/2014-tcp-time-wait-state-linux
RFC: https://tools.ietf.org/html/rfc1323
其中描述的部分可以很容易的验证,还有几个问题没搞清楚。
-
既然是per-host,那么同一个client的多个连接的请求过来,也可能受到timestamps的影响,不只是隐藏在NAT后的多个client会有这个问题。
测试:上面一篇文章中指出当开启timestamps时,处于last_ack状态的连接在收到syn请求后并不会返回rst,而是重发一次fin。
测试条件:将ip_local_port_range范围设为只有一个port;开启tcp_tw_reuse
通过在断开telnet连接时设置IPtables规则模拟ack包丢失,可以看到当重新telnet时,client向server发了syn包,server回了ack,client又发了rst,并再次syn包,server这次发来了syn+ack包,由于有iptables规则,server收不到client回的ack包,因此发了多次syn+ack,当取消iptables规则后,server成功收到ack,连接建立完成。
规则:
iptables -A OUTPUT -p tcp --tcp-flags ALL ACK --source 127.0.0.1 --sport 10240 -j DROP
tcp_fin_timeout不是msl值。https://huoding.com/2016/09/05/542
学到的一些概念:
paws,rrt,rto
原文地址:http://blog.51cto.com/zxdlife/2293798