在Linux系统中,出现大量的FIN_WAIT1状态通常与TCP连接关闭过程中的问题有关

原因分析

TCP连接关闭过程

1.FIN_WAIT1状态发生在服务器主动关闭TCP连接时,发送FIN包后等待客户端的ACK确认

2.如果客户端没有回应ACK,或者ACK丢失,服务器将保持在FIN_WAIT1状态

网络问题

网络拥塞或客户端故障导致ACK包延迟或丢失,导致服务器长时间处于FIN_WAIT1状态

系统配置

Linux系统的TCP参数配置可能导致问题。例如,tcp_orphan_retries控制了孤儿连接(即应用程序已经关闭,但系统仍保持连接)的重试次数

DoS攻击

FIN_WAIT1状态也可能被用于DoS攻击,攻击者通过不接收数据使服务端卡在FIN_WAIT1状态

解决方法

调整TCP参数

修改/etc/sysctl.conf文件,设置net.ipv4.tcp_fin_timeout和net.ipv4.tcp_orphan_retries以控制连接超时和重试次数

执行/sbin/sysctl -p使配置生效

优化应用程序

确保应用程序正确关闭连接,避免孤儿连接

案例

netstat 查看系统连接情况,出现 FIN_WAIT1

当连接数多时,经常出现大量FIN_WAIT1,可以修改 /etc/sysctl.conf

net.ipv4.tcp_fin_timeout = 10

net.ipv4.tcp_keepalive_time = 30

net.ipv4.tcp_window_scaling = 0

net.ipv4.tcp_sack = 0

然后:

/sbin/sysctl -p

使之生效

fin_wait1状态过多。fin_wait1状态是在server端主动要求关闭tcp连接,并且主动发送fin以后,等待client端回复ack时候的状态。fin_wait1的产生原因有很多,需要结合netstat的状态来分析

分析tcp状态数量异常

netstat -nat|awk '{print awk $NF}'|sort|uniq -c|sort -n

请求80服务的client ip按照连接数排序

netstat -nat|grep ":80"|awk '{print $5}' |awk -F: '{print $1}' | sort| uniq -c|sort -n

netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}' 

 

理论:

先设置fin-wait-1状态,然后再发fin包,

理论上说,fin-wait-1的状态应该很难看到才对,因为只要收到对方的ack,就应该迁移到fin-wait-2了,如果收到对方的fin,则应该迁移到closing状态

修改FIN_WAIT连接的重试次数

vim /etc/sysctl.conf   打开内核配置文件。linux内核是不能直接修改的,把新的配置写入这个文件,会覆盖Linux内核的文件。

net.ipv4.tcp_orphan_retries = 1

把这行代码插入/etc/sysctl.conf 文件,就是把retry次数设为1

TCP通讯流程

 

更多推荐