web-dev-qa-db-fra.com

Nombre de demandes de page par un bot en 5 secondes

J'écris un script qui bloque tous les robots qui demandent des pages, par exemple X fois dans le passé 5 secondes. J'ai besoin de trouver le X ici. Savez-vous quelques valeurs approximatives que je peux utiliser?

6
Manish Pradhan

vous feriez mieux d'utiliser votre pare-feu plutôt que de vous fier à un script php, car après tout, le script php n'affectera que les chargements de page php et non les fichiers statiques tels que les images. De plus, avoir php enregistre toutes les connexions et vérifie> 800 à partir de la même adresse IP pour chaque demande va ajouter une surcharge importante à votre serveur, peut-être même plus que les demandes elles-mêmes!

Si vous avez un serveur linux, vous pouvez utiliser IPTables:

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

ou si vous souhaitez configurer fail2ban pour bloquer les GET excessifs, vous devez être sûr de ne pas bloquer les utilisateurs réels à une limite de 800/2sec

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

Sur Windows Server ... eh bien, je ne pense pas que vous puissiez définir des limites de connexions/s, mais je pense que vous pouvez définir des quotas de bande passante dans les services QoS, ce qui limiterait effectivement le nombre de robots. Ou bien, il existe de nombreux outils tiers qui vous permettraient d'accomplir cela.

Modifier

J'y ai réfléchi un peu plus, et il semble que le moyen le plus efficace de consigner chaque demande d'adresse IP et de vérifier les hits précédents serait de concaténer l'adresse IP et l'heure actuelle en tant que nom de fichier et d'ajouter simplement un seul caractère. incrémenter la taille de fichier de 1 octet à chaque demande. Voici un script de test que j'ai écrit et avec lequel vous pouvez jouer pour vous faire une idée générale:

$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/>';

Exécutez ceci avec $ demandes <$ limites et vous verrez que tout va bien, peu importe le nombre de fois que vous actualisez. Modifiez $ demandes> $ limites et vous verrez que cela s’arrête dès que la taille du fichier atteint 401 octets. Actualisez à nouveau et vous verrez maintenant que vous êtes instantanément banni!

Il est important d’avoir le clearstatcache (); avant chaque vérification de fichier, sinon PHP mettra en cache les résultats initiaux de la taille de fichier et de file_exists et conservera les rapports sous la forme 1 octet et le fichier n'existe pas et ne dépasse jamais votre limite ou ne voit pas le fichier d'interdiction. De plus, vous devrez exécuter périodiquement un script cronjob pour supprimer les anciens fichiers de compteurs ip afin qu'ils ne occupent pas trop d'espace.

5
WebChemist

Merci pour le bon code. Je l'ai modifié de manière à interdire toute session sans session pendant une heure si ce piège est activé. J'appelle cela le piège des inondations extrêmes. Je sais que j'interdirai même les bons robots, ce qui m'amène à ma prochaine question. Servir les Searchbots avec 403 pendant une heure aura-t-il de mauvaises conséquences à long terme pour le site? Voici le code jusqu'à présent -

$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);
}

Qu'est-ce que tu penses?? mauvais choix??

1
Manish Pradhan