web-dev-qa-db-ja.com

LinuxでのTCP接続の強制終了

クライアントマシンが停止している場合、ハングした状態の1つのアプリケーションにいくつかの接続が切断されています。

->192.168.1.214:49029 (ESTABLISHED)

サーバーを再起動せずにLinuxコマンドラインからこれらのオプションを終了する方法はありますか?

検索の結果、tcpkillと呼ばれるソリューションが見つかりました。しかし、私にはうまくいきません。それは永久にそのIPをブロックするので。

58
Vivek Goel

元の場所: http://rtomaszewski.blogspot.sk/2012/11/how-to-forcibly-kill-established-tcp.html

ソケットを「強制終了」するには、TCPリセットパケットを送信する必要があります。これを送信するには(そして相手側に受け入れられるには)、実際のTCPシーケンス番号を知っている必要があります。

1)前述のtcpkillメソッドは、ネットワーク上で受動的にスニッフィングし、この接続の有効なパケットが到着するのを待つことにより、SEQ番号を学習します。次に、学習したSEQ番号を使用して、RSETパケットを両側に送信します。ただし、接続がアイドル/ハングし、データフローがない場合、何も実行されず、永久に待機します。

2)別の方法は、killcxSourceforgeへのリンク )と呼ばれるPerlスクリプトを使用します。これは、スプーフィングされたSYNパケットをアクティブに送信し、回答からSEQ番号を学習します。次に、tcpkillと同じ方法でRSETパケットを送信します。

別のアプローチ(達成したいことに基づく)は、gdbデバッガーを使用して、このソケット/接続を所有するプロセスにアタッチし、その代わりにclose() syscallを発行することです-詳細- answer

ハングした接続のみを処理したい(反対側が停止している)場合は、さまざまなタイムアウト(TCPキープアライブなど)があり、システムで適切に構成されていれば、そのような接続を自動的に閉じます。

36
Marki555

Linuxカーネル> = 4.9では、キー-Kを指定してiproute2からssコマンドを使用できます

ss -K dst 192.168.1.214 dport = 49029

カーネルはCONFIG_INET_DIAG_DESTROYオプションを有効にしてコンパイルする必要があります。

32
Pavel

tcpkillがそれをやってくれるかもしれません。 Ubuntuではdsniffパッケージに含まれています。

何かのようなもの:

$ Sudo tcpkill -i wlan0 Host 192.168.1.214

(または、他のtcpdumpのような、どの接続を強制終了するかを表す式)。

19
jcv

行う-ルートとしてnetstat -tunp|grep 49029。出力の最後の列には、その接続を担当するプロセスのPIDとプログラム名が表示されます。

運が良ければ、その接続のための単一のプロセスがあります。

運が悪いと、さらに複雑になります(PIDは、その1つの接続以上の原因になります)。これはどんなサービスですか?

なぜそのセッションを終了したいのですか?

6
Nils

tcpkillは、死んだ(ハングした)接続を閉じることができません。これはlibpcapに基づいており、送信するパケットを作成しますFINパケット。接続がすでに停止している場合、正しいシーケンス番号を取得できません。

唯一の方法はプロセスを閉じることです。そのため、make where everywhereはSPOFではありません。

1
alswl

iptablesREJECT--reject-with tcp-reset、パケットと一致したときにRSTをリモートに送信します。

0
Runlong Lin

これを行う方法に関する優れたオプションのリストであるMarki555回答に追加します。

私は別のオプションを見つけました-これは長いですが、アイドル接続でも機能します。カーネルデバッガーを使用してTCPシーケンス番号を取得し、hping3を使用してFINパケットを送信すると思います)。送信元 https://blog.habets.se/2017 /03/Killing-idle-TCP.html

0
Lars Nordin