web-dev-qa-db-ja.com

5秒でのボットによるページリクエストの数

たとえばX過去に5秒のように、ページを要求するボットをブロックするスクリプトを作成しています。ここでXを見つける必要があります。私が使用できるおおよその値を知っていますか?

6
Manish Pradhan

すべてのphpスクリプトは画像のような静的ファイルではなくphpページの読み込みにのみ影響するため、phpスクリプトに依存する代わりにファイアウォールを使用した方がよい場合があります。さらに、すべての接続をphpでログに記録し、すべてのリクエストに対して同じIPから800以上をチェックすると、サーバーに深刻なオーバーヘッドが追加されます。

Linuxサーバーがある場合は、IPTablesを使用できます。

http://blog.bodhizazen.net/linux/prevent-dos-with-iptables/

または、fail2banをセットアップして過剰なGETをブロックする場合、800/2秒の制限で実際のユーザーをブロックしないようにする必要があります。

http://go2linux.garron.me/linux/2011/05/fail2ban-protect-web-server-http-dos-attack-1084.html

Windows Serverでは...接続/秒の制限を設定できるとは思いませんが、ボットを効果的に制限するQoSサービスで帯域幅の割り当てを設定できると思います。または、これを実現できるサードパーティ製のツールがたくさんあります。

編集

私はこれについてもう少し考えていましたが、各IPリクエストを記録して以前のヒットをチェックする最も効率的な方法は、IPアドレスと現在の時間をファイル名として連結し、単一の文字を追加することですリクエストごとにファイルサイズを1バイトずつ増やします。以下に、一般的な考え方を理解するために試すことができるテストスクリプトを示します。

$limit      = 400;
$requests   = 1000;
$log_file   = '/tmp/ip_'.$_SERVER['REMOTE_ADDR'].'_'.time();
$ban_file   = '/tmp/ban_'.$_SERVER['REMOTE_ADDR'];

for($i = 0; $i < $requests; $i++){
    clearstatcache();
    if(file_exists($ban_file)){
        echo "<h1>you've been banned</h1>"; 
        exit;
    }
    $log = fopen($log_file, "a"); 
    fwrite($log,'0');
    fclose($log);       
    if(filesize($log_file) > $limit){
        $log = fopen($ban_file, "w"); 
        fwrite($log,NULL);
        fclose($log);
    }
    else{
        echo filesize($log_file).'<br/>';
    }
}
echo 'final '.filesize($log_file).'<br/>';

これを$ requests <$ limitsで実行すると、何回更新しても問題ないことがわかります。 $ requests> $ limitsを変更すると、ファイルサイズが401バイトに達すると停止します。もう一度更新すると、すぐに禁止されていることがわかります!

clearstatcache()を持つことが重要です。各ファイルをチェックする前に、それ以外の場合、PHPは初期のファイルサイズとfile_existsの結果をキャッシュし、1バイトとファイルが存在せず、制限を超えたり、禁止ファイルを表示したりしないようにレポートし続けます。また、cronjobスクリプトを定期的に実行して、古いIPカウンターファイルを削除し、スペースがいっぱいにならないようにする必要があります。

5
WebChemist

すばらしいコードをありがとう。このトラップがアクティブになった場合、セッションなしで1時間禁止するように修正しました。これをExtreme Flood Trapと呼んでいます。私は次の質問に私を導く良いボットさえ禁止することを知っています。 403でSearchbotsに1時間サービスを提供すると、長期的にはサイトに悪い影響がありますか?これまでのコードは次のとおりです-

$limit      = 400;
$log_file   = 'ip_'.$_SERVER['REMOTE_ADDR'].'_'.time();
$ban_file   = 'ban_'.$_SERVER['REMOTE_ADDR'];

clearstatcache();
if(file_exists($ban_file)){  
    $banlimit = file_get_contents($ban_file)+3600; 
    if(time() < $banlimit){
        if (!tep_session_id()) {
            header('HTTP/1.1 403 Forbidden');
            exit;
        }
    }
}

//creats a file and addes 1 byte of data on each page request
$log = fopen($log_file, "a"); 
fwrite($log,'0');
fclose($log);    

//if the size of the log file is greater than the Request limit size then create a ban file
if(filesize($log_file) > $limit){
    $log = fopen($ban_file, "w"); 
    fwrite($log,time());
    fclose($log);
}

どう思いますか??下手な選択??

1
Manish Pradhan