解決しようとしている問題があります。多くのローカルポート転送がソケットをCLOSE_WAITにインポートしており、多くのリモートポート転送がソケットをFIN_WAIT2にインポートしています。
現時点では、なぜこれが起こるのかわかりません。 sshのバグのようです(2009年1月7日、SuSE11 R4でOpenSSH_6.6.1p1、OpenSSL 0.9.8j-fipsを実行)。しかし、私はソケットスマッシングプログラムを書くことができるようにこれをシミュレートしたいと思います。
私はソケットを開いて死ぬPythonスクリプトを書いてみましたが、スレッドで開いて呼び出しアプリケーションを終了してみました。私はMySQLの接続を試み、それらをぶら下げました。 (それがCLOSE_WAITの原因であるためですが、それを複製することはできません)。保留中の接続を開始する両方のアプリケーションはプライベートソースです。 (1つはScience Logicデータベース接続で、もう1つはCisco CSPCボックスの排他接続です。)
それでは、ソケットをCLOSE_WAIT状態に設定するにはどうすればよいですか?ソケットをFIN_WAIT2状態に設定するにはどうすればよいですか?
答え1
CLOSE-WAITは、ピアシステム(プロセス)がTCP接続側を閉じたときに発生します。これはローカルオペレーティングシステムによって検出され、ローカルプロセスに送信されましたが、ローカルプロセスはサイドを閉じてそれをまだ承認していません。 TCP接続。小さなTCP接続。これは通常、アプリケーションが使用中であるか、一部のソケットを閉じることを「忘れた」、または停止(したがってもはや閉じることができない)のバグがある場合に表示されます。同時に、リモート側には対応するFIN-WAIT-2がありますが、このFIN-WAIT-2は最終的に期限切れになります。
socat
ローカルリスナーと分岐された各サブプロセスにSTOP信号を送信して「停止」し、1秒後にリモート接続を放棄する分岐プロセスとして再現できますsocat
(コマンドでも実行可能socat
)。
ローカルはそれ自体即座に停止し、CLOSE-WAIT 状態を保証します。ローカルではTCP接続を閉じることができないためです。
socat tcp4-listen:5555,reuseaddr,fork system:'kill -STOP $SOCAT_PID'
受信したすべての接続に対して、
socat
子プロセスはフォークされ、それ自体が子プロセスをすぐに停止するシェルをフォークして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
上記のループが完了した後の結果の例:
$ 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
FIN-WAIT-2は最終的に期限切れになりますが、CLOSE-WAITは(停止した)プロセスが存在する限り存在します。基本的なリスニングを中断すると、子が死んですべてsocat
がクリーンアップされます。