IP-Sperre

IP-Sperre mit PHP und MySQL Oder wie man einen User für eine gewisse Zeit aussperrt.

1. Um was geht's ?
2. Was brauche ich ?
3. Scripte
4. Wie benutze ich dieses Tutorial ?

1. Um was geht's ?

Es geht darum, dass man ab und an einen User für eine gewisse Zeit sperren will. ZB. bei Umfragen oder aber auch damit man einen ?Post Senden'-Button nur einmal drückt etc. Wie ist dies nun zu bewerkstelligen ? Wenn es System ist wo man sich einloggen muss dan legt man einfach eine Table an wo der Username reinkommt und gut ist. Aber wie sieht es bei Sachen aus die keiner Anmeldung bedürfen ? Naja da hält man sich an die IP, dies ist zwar nicht absolut wasserdicht und kann gefaked werden aber dies ist schon mit Mühen verbunden, es geht hier ja nur um einen einfachen Schutz also vernachlässigen wir hier mal die Nachteile, denn anders kann man es nicht machen. Ausser der IP hab ich eigentlich nix von dem User.

2. Was brauche ich ?

Also zuerst brauchen wir mal wieder eine Tabelle in einer Datenbank wo wir die Daten ablegen. Es reicht hierbau eine Tabelle mit 2 Spalten :

Spaltenname typ
ip varchar(15)
timefeld timestamp
Mit dem Befehl :

CREATE TABLE iptest (
ip varchar(16) default '0',
timefeld timestamp(14) NOT NULL)

kann man die Tabelle zB. mit phpMyAdmin erzeugen lassen. Ich habe die Tabelle iptest genannt und sie liegt in der Datenbank testgb. So das waren die Vorbereitungen.

3. Scripte

Wie immer lege ich mal wieder ein var.inc.php vor :

var.inc.php

<?php
// Datenbank Variablen
$dbserver "localhost";
$dbname "testgb";
$dbuser "";
$dbpass "";

// Sonstige Variablen
$stehenlassen 120;
?>

So, was steht drin ? Also, die ersten 4 Variablen die mit $db beginnen sind die Verbindungsvariablen zur MySQL Datenbank, sie müssen entsprechend editiert werden, je nachdem wo das GB laufen soll. Bei den sonstigen Variablen brauchen wir momentan nur eine Variable und zwar $stehenlassen, sie gibt an wielange IP's gesperrt werden sollen, die Angabe ist in Sekunden. Mehr brauchen wir nicht an Variablen.

Also nächstes brauchen wir die Seite die das ganze absendet, das Script ist einfaches HTML und simuliert zB. das Absenden seiner Wahl bei einem Umfragescript etc.

form.php

<html>
<head>
<title>klick it !</title>
</head>
Muss ich ja sicher nicht erklären, oder ?
<body>
<form action="check.php" method="post">

Es wird an die Seite check.php weitergeleitet. Sollte keinem Probleme bereiten, ansonsten mal bei SelfHTML vorbei schaun.

<input type="submit" name="sub" value="test">
<input type="submit" name="sub" value="Lösch die Tabelle">

Das ist ein kleiner Trick den ich von schmalle gelernt habe. Ich hab hier nämlich das Problem das ich zwei Buttons habe die an ein Script weiterleiten, allerdings mit zwei verschiedenen Aufgaben. Ich habe mich immer gefragt wie ich sowas realisieren kann, naja und schmalle hat mir den Kniff verraten. Man gibt seinen Submitbuttons einfach einen Namen, hier haben beide den Namen sub , naja und im Folgescript schaut man einfach nach dem Inhalt von $sub und weiss welcher der beiden Submitbuttons gedrückt wurde.

</form>
</body>
</html>

So und nun brauchen wir noch die check.php , das Herz dieses Tutorials auch wenn es noch ein sehr rudimentäres Herz ist. Aber es ist ja auch nur ein Grundlagentutorial.

check.php

<html>
<head>
<title>check</title>
</head>
<body>
<?php
include("var.inc.php");
?>

Hier werden die ?globalen' Variablen included. Dies macht Sinn bei grösseren Projekten bei denen bestimmte Daten von vielen Scripten benötigt werden, zB. Die Daten zur Konnektierung zur Datenbank, durch das includen hat man den Vorteil dass man die Daten nur einmal verändern muss, anstatt das man jedes Script ändern müsste.

<?php
$conn 
= @mysql_connect($dbserver,$dbuser,$dbpass);
if (!
$conn
{
die(
"Sorry, Datenbank nicht gefunden !");
}
?>

Hier wird eine Verbindung zum MySQL-Server aufgebaut, das @ Zeichen unterdrückt eine Fehlermeldung wenn der Versuch fehlschlägt, dies geschieht wieder aus Schönheitsgründen, naja und dann wird geschaut ob die Verbindung zustande kam. if(!$conn) ist wieder so ein kleiner Kniff, denn eigentlich will man ja wissen ob es geklappt hat, aber es sinnvoller zu schaun ob es nicht geklappt hat, denn dann brechen wir das Script ab und müssen nur einen Befehl in die if-Klammer setzen, ansonsten müssten wir alle weiteren Befehle einklammern. Das ! Zeichen negiert den Ausdruck $conn, falls dieser also FALSE ist dann wird der if Ausdruck TRUE, denn Minus mal Minus ist ja auch Plus. Es werden hier viele logische Elemente benutzt die es lohnt sich vor Augen zu führen da man sich dadurch eine Menge an Programmierarbeit sparen kann. Ausgenutzt wird das mysql_connect ein FALSE zurück gibt wenn die Verbindung nicht zustandekommt. Da aber der if Befehl überprüft ob der Ausdruck TRUE ist müssen wir ihn negieren , also Fragen wir ?WENN (if) NICHT (!) VERBINDUNG ($conn) DANN TUE DIES (die)". Es macht öfters sinn sich die Programmzeilen, gerade bei Abfragen, in ?Deutsch' zu übersetzten, dann wird der es manchmal einfachen, besonders bei komplexeren logischen Ausdrücken.

<?mysql_select_db($dbname,$conn);?>

Hier wird dann die Datenbank ausgewählt, dieser Befehl ist nötig wenn mehrere Datenbanken auf den DB-Server existieren. Damit wird die erstellte Verbindung $conn mit der Datenbank $dbname ?verbunden'. Es kann ja durchaus sein dass man mehrere Verbindungen zu verschiednen Datenbanken aufbaut.

<?php
if ($sub == "test")
?>

So, hier testen wir jetzt welchens value der Submitbutton hatte. Ist dieser test dann wird die IP Sperren Routine durchlaufen, ansonsten geht's weiter unten nach else weiter.

<?php
{
$ip $HTTP_SERVER_VARS["REMOTE_ADDR"];
?>

Hier wird nun die IP eingelesen und in die Variable $ip geschrieben. Diese Variablen sind sogenannte Umgebungsvariablen und es gibt sehr viele von ihnen, abrufen kann man sie mit dem Befehl phpinfo(); Dann wird alles angezeigt was es so gibt.

<?php
$zeit 
time ();
?>

Hier wird erstmal die aktuelle Zeit festgestellt und gespeichert.

<?php
$nichtmehrgueltig 
$zeit-$stehenlassen;
?>

So, in $nichtmehrgueltig wird der Timestamp gespeichert ab dem gesperrt wird.

<?php
$query 
"DELETE FROM iptest WHERE timefeld <= ".$nichtmehrgueltig;
mysql_query($query,$conn);
?>

Jetzt kommen wir zum Eingemachten, zuerst wird alles aus der Tabelle gelöscht was zu alt ist, was also wieder gütig ist. Sprich es wird freigegeben was älter ist als $nichtmehrgültig. Das muss zuerst passieren bevor man abfragt ob der User ?legal' hier ist. Hmm, mir fehlen gerade die Wort zum beschreiben, die Idee ist ja alle aus zu sperren die zu früh wiederkommen, hier werden jetzt die aus der Tabelle gestrichen die schon lange genug weg waren und nicht wiederkehrten.

<?php
$query 
"SELECT * FROM iptest WHERE ip = '".$ip."'";
$result mysql_query($query,$conn);
?>

Nachdem wir jetzt alle gestrichen haben die wiederkommen dürfen lesen wir aus der Tabelle aus ob die aktuelle $ip schon in der Tabelle drinsteht...

<?php
$rows 
mysql_num_rows($result);?>

..denn ist dies der Fall, dann ist die Variable $rows > 0. Hier wird jetzt mit dem Befehl mysql_num_rows festgestellt wieviele Datensätze gefunden wurden in der Tabelle. Unsere Bedingung ist ja dass die IP noch nicht vorhanden sein darf. Ist sie vorhanden dann ist die IP gesperrt. Hier ist jetzt Vorsicht geboten, es gibt eine Falle auf die man reinfallen kann. Es reicht nämlich nicht zu prüfen ob $result TRUE ist, denn $result ist immer TRUE wenn der SQL-Query legal ist. Man könnte ja annehmen wenn der Query keine Datensätze zurückliefert dass $result FALSE ist , dies ist aber nicht der Fall !!

<?php
if ($rows >= 1)
//Nun schauen wir ob $rows >= 1 ist,.... 
{
echo 
"Sorry diese IP ist noch gesperrt !";

//...ist dies der Fall steht die IP schon in der Tabelle und das wird ausgegeben. 
else

//echo "Okay sie werden jetzt $stehenlassen sec. lang gesperrt !";
//Wenn nicht dann wird ausgegeben dass man jetzt $stehenlassen Sekunden gesperrt ist.
$query "INSERT INTO iptest VALUES ("$ip", $zeit)";
mysql_query($query,$conn); 
}
//Und dies wird in die Datenbank eingetragen, also der aktuelle Timestamp in Form der 
//Variable $zeit und die aktuelle IP.
}
else
{
$query "DELETE FROM iptest";
mysql_query($query,$conn);
echo 
"Daten wurden gelöscht !";
//Dies ist nun der else Teil der $sub Abfrage, hier hatten man ja die Möglichkeit die gesamte 
//Tabelle, nur den Inhalt dieser, zu löschen. Das wird hier geamcht, ist keine Kunst wie man 
//sieht, eifach der DELETE Befehl ohne Bedingung und das Teil ist leer.
}
mysql_close($conn); 
?>
?>

Jetzt schliesen wir noch die Connection zur Datenbank und die Hexerei hat ihr Ende. Das war es schon wieder, wie man sieht ist es garnicht so schwer sowas zu realisieren wenn man weiss wie es geht. Ich muss gestehen dass ich beim erstenmal auch zuerst einmal da stand und nicht so recht wusste wie ich es machen soll. Aber mit ein wenig nachdenken geht's recht einfach, wie man sieht.

<br>
<form action="form.php" method="post">
<input type="submit" name="sub" value="nochmal">
</form>
</body>
</html>

Dieser kleine Form Teil ist nur dazu da wieder auf die form.php zurück zu kommen.

4. Wie benutze ich das Tutorial ?

Also zuerst muss man die Tabelle anlegen und dann die Seite form.php aufrufen. Wenn man auf test drückt dann wird die IP überprüft und das Ergebnis gemeldet, der andere Button löscht einfach den Tabelleninhalt für weitergehende Tests ?

Viel Spass und ich hoffe es hilft Spass mit php und MySQL zu erhalten. Comments und Verbesserungen sind erwünscht.

Mit freundlichen Grüßen.
JoelH

Erfahrungen

Es sind noch keine Kommentare vorhanden.

Hier Kannst Du einen Kommentar verfassen


Bitte gib mindestens 10 Zeichen ein.
Wird geladen... Bitte warte.
* Pflichtangabe

Verwandte Beiträge

Wird geladen... Bitte warte.
Wird geladen... Bitte warte.

Tutorial veröffentlichen

Tutorial veröffentlichen

Teile Dein Wissen mit anderen Entwicklern weltweit

Du bist Profi in deinem Bereich und möchtest dein Wissen teilen, dann melde dich jetzt an und teile es mit unserer PHP-Community

mehr erfahren

Tutorial veröffentlichen