
Serverfaultコミュニティの皆様へ
次のような問題があります。パケット データで特定の文字列が検出された場合、ネットワークの両側で TCP 接続を直ちにリセット (切断) する必要があります。両側のアプリケーションを制御することはできず、接続を中止するには Linux iptables (または同様のツール) のみを使用できます。
私の最初のアイデアは、次の iptables ルールを使用して、目的を達成することでした。
/usr/sbin/iptables -A INPUT -p tcp --dport 1234 -m string --algo bm --string 'BAD STRING' -j REJECT --reject-with tcp-reset
これは、TCP RST パケットをクライアントに送信することでリモート側では完全に機能し、クライアントは直ちに切断されます。残念ながら、強制切断時にローカル側には通知されず、サーバー プロセス (接続) は永久にハングします。
特定の条件 (この場合は IP パケット内の文字列の一致) に基づいて、両側ですでに確立されている接続を直ちに切断する必要があることは、それほど珍しいことではないと思いました。そこで、Google 検索を実行しましたが、驚いたことに、妥当な時間内に使えるものは見つかりませんでした。
iptables を使用してネットワークの両側で TCP 切断を実現する方法はありますか? そうでない場合、他にどのようなツールを使用できますか (クライアント/サーバー アプリケーションを制御できないことに注意してください)?
貴重なご回答を頂き誠にありがとうございます!
よろしくお願いします、
イェンス
答え1
使用できますxt_リセット例えば、-j RESET
答え2
アプリケーションにタイムアウトを設定することができます。
別の解決策としては、TCP KeepAlive を構成して、10 分ごとなど、より頻繁にチェックすることです。
一部のアプリケーションは、アプリケーション レベルで KeepAlive を実装します。例: SSH、apache。
キープアライブが送信され、リモート エンドで接続が閉じられると、リモート エンドから RST を受信します。
ステートフル ファイアウォールは、一定期間非アクティブな状態が続くと接続を忘れます。つまり、しばらく (30 分または 1 時間) トラフィックがない場合、パケットが破棄され、接続が半分開いた状態になることがあります。
実装しようとしている特定のソリューションについて質問するよりも、解決しようとしている特定の問題について質問する方が良いと思います。
答え3
残念ながら、強制切断時にローカル側に通知されません。
そうあるべきです。tcp-reset は、接続が閉じられていることをクライアントに通知することを意味します。リセットが送信されたときにクライアントがハングしている場合は、IPTables を実行しているホストから返されるリセットを適切に処理していないことを意味します。その問題に対処する手段がない限り、これを実現する方法は思いつきません。