yubb.de-Logo
Tutorials
yubb@yubb
yubbService
Inside yubb

IP-Sperre mit PHP und MySQL



Angenommen, man möchte sein Gästebuch gegen Spamming schützen, sodass ein Benutzer nur alle 3 Minuten einen Eintrag abgeben kann.
Dafür wird seine IP gespeichert, verbunden mit der Zeit, als der Eintrag abgegen wurde. Bei einem erneuten Eintrag wird überprüft, ob schon 3 Minuten vergangen sind und wenn nicht, so wird der Eintrag verweigert.

Zuerst benötigen wir dafür eine MySQL-Tabelle ipsperre:
Tabelle ipsperre:
ip VARCHAR (15)
time INT (11)


Desweitern hier einmal der komplette Code für eine IP-Sperre in PHP:
PHP-Datei:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<?
function getip() {
    
//wenn der User über nen Proxy in's Internet geht...
    //muss die IP so "geholt" werden...
    
if(getenv("HTTP_X_FORWARDED_FOR"))
        
$ip getenv("HTTP_X_FORWARDED_FOR");
    else
        
//ansonsten so...
        
$ip getenv("REMOTE_ADDR"); 
    return 
$ip
}

mysql_connect("host","name","passwort") or die(mysql_error()); // Verbindet zum Datenbankserver
mysql_select_db("datenbank"); // Wählt die Datenbank

$sperre=time()-180;
$jetzt=time();
$ip getip(); 

mysql_query("DELETE FROM ipsperre WHERE time<$sperre") or die(mysql_error()); // Löscht Einträge, die veraltet sind

$pruef=mysql_query("SELECT ip FROM ipsperre WHERE ip='$ip'") or die(mysql_error());
if(@!
mysql_fetch_array($pruef)) { // Wenn die IP nicht gefunden wurde: Eintrag
    
mysql_query("INSERT INTO ipsperre (ip, time) VALUES ('$ip', '$jetzt')") or die(mysql_error());
    
    
// Weitere Einträge, z.B. ins Gästebuch
}
} else { 
// ansonsten Verweigerung
    
echo "Deine IP wurde in der Datenbank gefunden, du hast nicht drei Minuten gewartet!";
}
?>


Das Script ist größenteils selbsterklärend, dennoch hier die Erläuterungen:
Zuerst kommt eine Funktion, die dem Tutorial von michi zugrunde liegt.
Anschließend kommt eine Verbindung zu der Datenbank, wo das Gästebuch und die IP-Tabelle liegen.

Nun kommen einige Variablen: $sperre ermittelt mit Hilfe time(), wie spät es vor 180 Sekunden (= 3 Minuten und damit die Sperre) war. $jetzt ermittelt die jetzige Zeit, auch mithilfe von time(). Desweiteren wird in $ip mithilfe von michis Funktion die IP des Besuchers ermittelt.

Den nun folgenden Query möchte ich erstmal überspringen, deswegen fangen wir gleich mit dem nächsten Query an (Zeile 22): Es wird in der Tabelle abgefragt, ob ein Eintrag mit einer IP, die dem Besucher gleich ist, vorhanden ist.
Wenn die IP nicht gefunden wurde, so hat der Benutzer in den letzten 3 Minuten nicht geschrieben und darf sich in das Gästebuch eintragen. Nebenbei wird aber auch seine aktuelle IP mitsamt der aktuellen Zeit in die Tabelle ipsperre geschrieben.
Wurde die IP gefunden, so hatr der Benutzer in den letzten 3 Minuten geschrieben und ihm wird das Schreibrecht verweigert.

Aber woher weiß man nun, wer in den letzten 3 Minuten geschrieben hat und wer nicht?
Das Geheimnis liegt in der von mir anfangs übersprungenen Zeile 20: Hier werden alle Einträge in der Tabelle ipsperre gelöscht, wo die gespeicherte Zeit (wir erinnern uns: Das war die Zeit des Eintrages) kleiner ist als $sperre (also jetzt vor 3 Minuten). Denn, wenn der gespeicherte Wert kleiner ist als "jetzt vor 3 Minuten", dann sind auch 3 Minuten um.
Die Einträge, die übrig bleiben, sind noch innerhalb der Sperre. Und nach deren Existenz wird gesucht bzw, mit diesen Werten wird die aktuelle IP des Besuchers verglichen.

Um alles noch einmal zusammenzufassen:
1.) Lösche alle Einträge, die älter als 3 Minuten sind
2.1.) Ist die IP immer noch vorhanden, so verweigere den Eintrag
2.2.) Ist die IP nicht vorhanden, so erlaube den Eintrag und trage die IP mitsamt Zeit in die Tabelle ein.
Da dieser Plan bei jedem Aufruf durchlaufen wird, ist eine gerechte Sperre garantiert, da zuerst veraltete Einträge gelöscht werden, bevor die IP überprüft wird.

Geschrieben von Phil Marx am 18.06.2004 (14900x gelesen)
weiterempfehlen weiterempfehlen   Druckversion Druckversion   kommentieren kommentieren

Sehr praktisch, aber könnteste das noch textdateibasierend machen? Wäre nett.
Geschrieben von dasepp
also irgendwie ist das zwar genau das, was sich suche, dennoch enthält es meiner meinung nach einige fehler!



1. du hast eine } klammer zuviel gemacht. nur 3 klammern im script sind geöffnet, demnach sollten auch nur 3 geschlossen werden und nicht 4 ( vor else sind 2 } klammern, sollte aber nur eine hin)



2. irgendwie ist mir die if funktion dort ein rätsel! das muss doch genau umgekehrt sein:



if(@mysql_fetch_array($pruef)) {

echo "Deine IP wurde in der Datenbank gefunden, du hast nicht drei Minuten gewartet!";

} else {

//eintrag

mysql_query("INSERT INTO ipsperre (ip, time) VALUES ('$ip', '$jetzt')") or die(mysql_error());

}





.... kann auchs ein, dass alles von mir nicht richtig ist, aber eigentlich sollte es das sein! bitte um stellungnahme, ob ich mich geirrt hab, oder der autor :)
Geschrieben von rasmus
Ich fände noch die Idee gut, das ein Cookie beim bannen bei dem Client angelegt wird. Und immer wenn der Client mit einer neuen IP auf der Seite kommt wird dieses Cookie ausgelesen und die jetzige IP in die DB geschrieben. Die alte IP sollte dann gelöscht werden. So kann man User auch auf mehrere Tage hin konstant bannen.
Geschrieben von Carnage
achtung, die tabelle ipsperre mus folgende felder enthalten:

time (int 11)
ip (varchar 15) <-!!!!!

sonst werden nur die ersten 3 ziffern der IP gespeichert, weil der punkt "." ja keine zahl is, ne?
Geschrieben von Monkey
Ihr beide habt Recht, ich habs behoben :)
Geschrieben von Phil Marx
ip INT(11) das muss nen string sein nur mal so nebenbei
Geschrieben von Ka1o