Pet*_*ner 5 networking ssh tcp socket
我有一个问题,我正在尝试解决以下问题:大量本地端口转发使套接字陷入 CLOSE_WAIT,而大量远程端口转发使套接字陷入 FIN_WAIT2。
目前我不知道为什么会发生这种情况。似乎是 ssh 中的错误(在 SuSE11 R4 上运行 OpenSSH_6.6.1p1、OpenSSL 0.9.8j-fips 07 Jan 2009)。但是,我想模拟这个,以便我可以编写一个套接字粉碎程序。
我尝试编写打开套接字并死掉的Python脚本,我尝试在线程中打开它们并杀死调用应用程序。我尝试过建立 MySQL 连接并让它们悬空(因为这是导致 CLOSE_WAIT 的原因,但我无法复制它)我可以尝试 1000 种其他方法,但没有一种可能会导致这种情况发生。启动挂起连接的两个应用程序都是闭源的:((一个是 Science Logic 数据库连接,另一个是来自 Cisco CSPC 盒的某些专有连接)
那么我需要做什么才能使套接字陷入 CLOSE_WAIT 状态,以及如何使套接字陷入 FIN_WAIT2 状态?
当对等系统(进程)关闭其一侧的 TCP 连接时,会发生 CLOSE-WAIT,这已被本地操作系统检测到并传输到本地进程,但本地进程尚未通过关闭其一侧的 TCP 连接来确认这一点TCP 连接。当应用程序繁忙、有错误使其“忘记”关闭其某些套接字或挂起时(因此无法进一步关闭),这种情况通常会变得可见。同时远端会有相应的FIN-WAIT-2,但是这个FIN-WAIT-2最终会过期。
它可以通过本地侦听和分叉socat进程来重现,该进程将向每个分叉子进程发送 STOP 信号socat以“挂起”它,以及 1 秒后放弃的远程连接(也可以通过命令完成socat):
local 将立即停止自身以保证 CLOSE-WAIT 状态,因为它无法关闭 TCP 连接的一侧:
socat tcp4-listen:5555,reuseaddr,fork system:'kill -STOP $SOCAT_PID'
Run Code Online (Sandbox Code Playgroud)
对于每个收到的连接,子socat进程都会被分叉,并且本身会分叉一个 shell,该 shell 会立即停止该子socat进程(使用继承变量$SOCAT_PID),防止它(检测远程端已关闭并)关闭其 TCP 连接端。
远程(或者在本例中也是本地的,以保持简单)将在 1 秒不活动后放弃,并沿着对等方的 CLOSE-WAIT 获取关联的 FIN-WAIT-2 状态:
for i in $(seq 1 5); do socat -T 1 -u tcp4:127.0.0.1:5555 -; echo $i; done
Run Code Online (Sandbox Code Playgroud)
上述循环完成后的示例结果:
$ ss -tn sport == 5555 or dport == 5555
State Recv-Q Send-Q Local Address:Port Peer Address:Port
FIN-WAIT-2 0 0 127.0.0.1:33836 127.0.0.1:5555
FIN-WAIT-2 0 0 127.0.0.1:33846 127.0.0.1:5555
FIN-WAIT-2 0 0 127.0.0.1:33842 127.0.0.1:5555
CLOSE-WAIT 1 0 127.0.0.1:5555 127.0.0.1:33840
CLOSE-WAIT 1 0 127.0.0.1:5555 127.0.0.1:33836
CLOSE-WAIT 1 0 127.0.0.1:5555 127.0.0.1:33842
FIN-WAIT-2 0 0 127.0.0.1:33840 127.0.0.1:5555
CLOSE-WAIT 1 0 127.0.0.1:5555 127.0.0.1:33846
CLOSE-WAIT 1 0 127.0.0.1:5555 127.0.0.1:33834
FIN-WAIT-2 0 0 127.0.0.1:33834 127.0.0.1:5555
Run Code Online (Sandbox Code Playgroud)
FIN-WAIT-2 最终会过期,但只要(已停止的)进程存在,CLOSE-WAIT 就会一直存在。打断主要的聆听socat会杀死它的孩子并清理一切。
| 归档时间: |
|
| 查看次数: |
1848 次 |
| 最近记录: |