tcp四次挥手相关选项

1、tcp_orphan_retries
主动方发送 FIN 后处于 FIN_WAIT1 状态,收到 ACK 后转为 FIN_WAIT2。如果收不到对方返回的 ACK,内核会定时重发 FIN 报文,其中重发次数由 tcp_orphan_retries 参数控制,默认值是 0 表示 8 次:

$ cat /proc/sys/net/ipv4/tcp_orphan_retries
0

2、TCP 报文有序发送,当发送缓冲区还有数据没发送时,FIN 报文也不能提前发送。
因为TCP 有流控功能,当接收方将接收窗口设为 0 时,发送方就不能再发送数据。
所以,当攻击者下载大文件时,就可以通过将接收窗口设为 0,导致 FIN 报文无法发送,进而导致连接一直处于 FIN_WAIT1 状态。
解决方案是调整 tcp_max_orphans 参数:

$ cat /proc/sys/net/ipv4/tcp_max_orphans 
4096

如果孤儿连接数量大于它,新增的孤儿连接将不再走四次挥手,而是直接发送 RST 复位报文强制关闭。

3、FIN_WAIT_2
TCP 进入FIN_WAIT_2 状态后,如果迟迟收不到对端的 FIN 包,就会一直消耗系统资源。 为了防止这种开销,linux 设置了这个状态的超时时间 tcp_fin_timeout,默认为 60s,超过这个时间就会自动销毁该连接,可以工具实际情况调小。

$ cat /proc/sys/net/ipv4/tcp_fin_timeout
60

4、TIME-WAIT 超时时间

如果没有 TIME-WAIT,而最后一个ACK刚好丢包或延迟了,等我们复用该端口时,假设刚才延迟的ACK报文到达了,新连接就可能被旧的 FIN 报文错误的关闭了。
MSL 全称是 Maximum Segment Lifetime(报文段最大生存时间)。
Linux下 MSL 的值为 30 秒,TIME-WAIT2MSL ,所以 TIME-WAIT60秒。
定义在:
https://elixir.bootlin.com/linux/v5.0/source/include/net/tcp.h#L121

#define TCP_TIMEWAIT_LEN (60*HZ) /* how long to wait to destroy TIME-WAIT
                  * state, about 60 seconds */

为什么是 2 倍的 MSL,这样可以允许报文丢失一次,如果 ACK丢了,对方重发的 FIN 会在第 2MSL 内到达。

5、TIME_WAIT 数量
当 TIME_WAIT 数量超过tcp_max_tw_buckets参数时,新关闭的连接就不再经历 TIME_WAIT 而直接关闭,当服务器的并发连接增多时可以适当调大该参数:

$ cat /proc/sys/net/ipv4/tcp_max_tw_buckets
4096

6、复用 TIME_WAIT 的连接
可以考虑设置为 1 来打开复用:

$ cat /proc/sys/net/ipv4/tcp_tw_reuse 
0

你可能感兴趣的:(tcp四次挥手相关选项)