Linux で実行されている、標準のネットワーク ソケット経由で TCP/IP を使用する C++ で記述された Web アプリがあります。このサービスは、ワイルドで毛むくじゃらのインターネットに開かれています。
自動化されたスクリプトを実行しているスパマーから、定期的に大量の悪質なリクエストを受け取ります。これらを検出してソケットを閉じることができます。現在、完了した有効なリクエストに対して行うのと同じように、ソケット lib を次のように閉じて、丁寧なソケット クローズを行います。
close( mSocket );
しかし、通常、ソケットを閉じると、ソケット接続が終了したことがスパム スクリプトに通知され、すぐに別の不正な要求が開始されることがあります。
システムの開いているソケットをクリーンアップする TCP/IP 接続を終了する最善の方法は何ですか? つまり、私にとってはコストが最も低く、コストが最も高い方法でソケットを閉じたいということです。
@ニコラス・ウィルソン:
TCP_REPAIR を使用するのは良い考えのようです。TCP_REPAIR モードでソケットが閉じられると、FIN または RST パケットは送信されません。リモートソケットはぶら下がったままです。試してみて、また報告します。ここに私の(テストされていない)コードがあります:
if ( abuse )
{
int aux = 1;
if ( setsockopt( mSocket, SOL_TCP, TCP_REPAIR, &aux, sizeof( aux )) < 0 )
reportError( "Tried to do a rude socket close... but could not turn on repair mode.\n" );
}
close( mSocket );
これが機能するかどうかはまた報告します。(@edit: 以下のテスト済みの回答)
@ 「ソケットを開いたままにする」という考え:
これは機能しますが、最適ではありません。攻撃者は、開いているソケットでシステムを飽和させることができます。要求ごとに、開いたままの新しいソケットが作成されます。DOS 攻撃では、最終的にソケットが不足します。
次に、開いているソケットの管理にも問題があります。
- 閉じないでください。開いているソケットは永久に残ります。攻撃者のコスト: 高い - フィンは得られません。私にとってのコスト:より高い。すべてのファイル記述子は最終的に使用されます。
- ソケットごとにスレッドを生成して 10 分間スリープさせてから、ソケットを閉じます。攻撃者のコスト: 高い - フィンは得られません。私にとってのコスト:より高い。私は最終的にソケットを閉じますが、リクエストごとに、攻撃者よりも長くソケットを使い果たし、スレッドのオーバーヘッドがあります。
- 乱用されたすべてのソケットの期限切れを処理するスレッドを生成します。攻撃者のコスト: 高い - フィンは得られません。私にとってのコスト:より高い。2のように、たくさんのソケットが開いたままです。それを管理するための単一スレッドのオーバーヘッド。コードの複雑さ、煩わしさ。