2009-02-01 5 views
7

Was ist der beste Weg, um Bots, böswillige Benutzer usw. davon abzuhalten, PHP-Skripte zu schnell auszuführen? Ist es in Ordnung, wenn ich die Funktionen oder sleep() verwende, um einfach "nichts" zu machen (kurz bevor der gewünschte Code ausgeführt wird), oder ist das einfach dumm und es gibt bessere Möglichkeiten dafür?Verzögerung der Ausführung des PHP-Skripts

Beispiel:

function login() { 
//enter login code here 
} 

function logout() { 
//enter logout code here 
} 

Wenn ich nur setzen, sagt sie, usleep(3000000) vor dem Login- und Logout-Codes, ist das in Ordnung, oder gibt es bessere, klügere Wege zu erreichen, was ich erreichen will?

edit: Basierend auf den unten aufgeführten Vorschläge beachten, wird dann usleep oder sleep nur bewirken, dass der Prozessor aus dem aktuellen Skript lösen durch die aktuellen Benutzer ausgeführt wird, oder ist es weil es aus dem gesamten Dienst zu lösen? Wenn ein Benutzer + Skript eine sleep/usleep aufruft, werden alle gleichzeitigen Benutzer + Skripte ebenfalls verzögert?

Antwort

8

Die Art und Weise die meisten Web-Server arbeiten (Apache zum Beispiel) ist eine Sammlung von Arbeitsthreads zu halten. Wenn ein PHP-Skript ausgeführt wird, führt ein Thread das PHP-Skript aus.

Wenn das Skript sleep(100) ausführt, dauert die Ausführung des Skripts 100 Sekunden. Das bedeutet, dass Ihr Worker-Thread 100 Sekunden lang gebunden ist.

Das Problem ist, Sie haben eine sehr begrenzte Anzahl von Worker-Threads - sagen Sie 10 Threads haben, und 10 Personen anmelden - jetzt Ihr Web-Server keine weiteren Antworten nicht dienen kann ..

Der beste Weg, Rate-Limit-Logins (oder andere Aktionen) ist eine Art von schnellen In-Memory-Speicher-Sache (memcached ist perfekt dafür), aber das erfordert separate Prozess und ist ziemlich kompliziert (Sie könnten dies tun, wenn Sie etwas wie Facebook ausführen ..).

Einfachere, könnten Sie eine Datenbanktabelle, die user_id oder ip_address, first_failed und failure_counter speichert.

Jedes Mal, wenn eine ausgefallene die Anmeldung erhalten, würden Sie (in Pseudocode):

if (first_failed in last hour) and (failure_counter > threshold): 
    return error_403("Too many authentication failures, please wait") 
elseif first_failed in last hour: 
    increment failure_counter 
else: 
    reset first_failed to current time 
    increment failure_counter 

Vielleicht nicht die effizienteste, und es gibt bessere Möglichkeiten, aber es sollte Brute-Forcing ziemlich gut stoppen. Die Verwendung von memcached ist grundsätzlich gleich, aber die Datenbank wird durch memcached ersetzt (was schneller ist)

1

Ihre vorgeschlagene Methode wird alle Benutzer zwingen, unnötig zu warten, bevor Sie sich anmelden.

Die meisten LAMP-Server (und die meisten Router/Switches, tatsächlich) bereits konfiguriert sind Denial-of-Service-Angriffe zu verhindern. Sie tun dies, indem sie mehrere aufeinanderfolgende Anfragen von derselben IP-Adresse ablehnen.

1

Sie möchten nicht schlafen in Ihrem PHP. Dadurch wird die Anzahl der gleichzeitigen Anfragen, die Ihr Server bewältigen kann, erheblich reduziert, da Sie Verbindungen warten lassen müssen.

Die meisten HTTP-Server verfügen über Funktionen, die Sie aktivieren können, um DoS-Angriffe zu vermeiden. Wenn Sie dies jedoch versäumen, sollten Sie IP-Adressen, die Sie schon zu oft gesehen haben, einfach mit einer Nachricht zurücksenden .

Wenn Sie aus irgendeinem Grund nicht darauf zählen können, dass REMOTE_ADDR benutzerspezifisch ist (jeder hinter derselben Firewall usw.), könnten Sie eine Herausforderung im Anmeldeformular darstellen und den entfernten Browser dazu veranlassen, eine erweiterte Berechnung durchzuführen , Faktor eine Zahl), die Sie schnell auf der Serverseite überprüfen können (mit schneller Multiplikation).

2

um Bots, böswillige Benutzer usw. zu stoppen PHP-Skripte zu schnell ausführen?

Ich würde zuerst fragen, was Sie wirklich versuchen zu verhindern? Wenn es sich um Denial-of-Service-Angriffe handelt, dann muss ich sagen, dass Sie nichts tun können, wenn Sie durch das eingeschränkt sind, was Sie PHP-Skripten hinzufügen können. Der Stand der Technik ist weit jenseits dessen, vor dem wir als Programmierer schützen können. Sehen Sie sich die für diesen Zweck entwickelten Sysadmin-Tools an.

Oder versuchen Sie Ihren Dienst zu begrenzen, so dass echte Menschen darauf zugreifen können, aber Bots können nicht? Wenn ja, würde ich mir einige "Captcha" -Techniken ansehen.

Oder möchten Sie verhindern, dass Nutzer Ihre Website jede Sekunde nach neuen Inhalten durchsuchen? Wenn ja, würde ich die Bereitstellung eines RSS-Feeds oder eine andere Art der Benachrichtigung untersuchen, damit sie Ihre Bandbreite nicht auffressen.

Oder ist es etwas anderes?

Im Allgemeinen würde ich weder schlafen sagen() noch usleep() ist ein guter Weg.

-
bmb