Restreindre l'accès d'un site à certaines adresses IP

Formation

En Semi-présenciel Paris

Prix sur demande

Appeler le centre

Avez-vous besoin d'un coach de formation?

Il vous aidera à comparer différents cours et à trouver la solution la plus abordable.

Description

  • Typologie

    Formation

  • Méthodologie

    En semi-présentiel

  • Lieu

    Paris

Grâce à cette formation vous pourrez acquérir les connaissances nécessaires qui vous permettrons d’ajouter des compétences à votre profil et obtenir de solides aptitude qui vous offriront de nombreuses opportunités professionnelles.

Les sites et dates disponibles

Lieu

Date de début

Paris ((75) Paris)
Voir plan
7 Cité Paradis, 75010

Date de début

Consulter

Questions / Réponses

Ajoutez votre question

Nos conseillers et autres utilisateurs pourront vous répondre

À qui souhaitez-vous addresser votre question?

Saisissez vos coordonnées pour recevoir une réponse

Nous ne publierons que votre nom et votre question

Les Avis

Le programme

Introduction du cours

Il nous arrive parfois, lorsque l'on est webmaster d'un site, de se retrouver aux prises avec des gens agissant de manière douteuse sur notre site web. Parfois, le problème peut venir de robots qui postent un peu partout sur le site (dans le livre d'or, sur le forum, etc.).

Dans ces circonstances, il est pratique d'avoir des solutions d'urgence qui peuvent être mises en place rapidement et efficacement.

Détecter l'adresse IP du client

Détecter une adresse IP est quelque chose de très simple en soi. Lors de l'exécution des pages PHP, la variable superglobale $_SERVER contient des informations sur la page en cours de chargement, et sur les communications effectuées entre le serveur et le client lors de cette requête. L'entrée REMOTE_ADDR nous donne l'IP du client qui a demandé la page.

Ainsi, ce code affiche l'IP du visiteur :

<?php print ('Votre adresse IP est <strong>' . $_SERVER['REMOTE_ADDR'] . '</strong>'); ?>

C'est donc quelque chose de très simple en soi, comme je l'ai dit. Par contre, il arrive que des internautes se connectent à ce que l'on appelle des serveurs proxy. Un serveur proxy, c'est un serveur qui sert d'intermédiaire entre un visiteur et un site web. L'avantage pour un internaute, c'est que son adresse IP n'est pas affichée directement sur le serveur qui reçoit sa requête ; c'est celle du serveur proxy qui est affichée, car c'est lui qui transmet la requête.

Ce procédé permet de berner les protections de la plupart des sites web. Nous nous créerons donc une fonction qui nous permettra de récupérer l'IP du véritable client. Ce n'est pas difficile, encore une fois.

Lorsque c'est un serveur proxy qui effectue la requête pour un autre client, une nouvelle case est créée dans notre tableau $_SERVER. Cette case a pour clé HTTP_X_FORWARDED_FOR. Elle signifie « effectue la requête pour ». À partir de ça, on peut donc créer notre fonction :

<?php //Retourne la vraie adresse IP function get_ip() { if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) $ip = $_SERVER['HTTP_X_FORWARDED_FOR']; else $ip = $_SERVER['REMOTE_ADDR']; return $ip; } ?>

De manière totalement personnelle, je préfère abréger cela à l'aide d'un ternaire :

<?php //Retourne la vraie adresse IP function get_ip() { return (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR']; } ?>

Assurez-vous d'inclure le fichier dans lequel vous placerez la fonction partout où vous en aurez besoin. Personnellement, je dédie un fichier unique à cette fonction, dans un dossier libs/div/. Cette protection n'est pas fiable à 100 %, car il existe plusieurs niveaux de proxy, des « peu anonymes » aux « super anonymes ». Dans le cas des proxy considérés comme très confidentiels, il est pratiquement impossible de détecter le client pour qui ils effectuent les requêtes, voire de détecter qu'il s'agit d'un proxy. ;) Mais on n'aura rien à se reprocher, car on aura fait tout ce qui était possible.

Nous allons maintenant créer une petite interface nous permettant de bannir rapidement des adresses IP. Je vois deux façons de le faire. La première façon utilise une table MySQL et la seconde un simple fichier texte. Il est peut-être plus astucieux d'utiliser la seconde solution, car le premier cas implique que nous exécutions une requête SQL de plus à tous les chargements de page, sans exception.

Par contre, en utilisant MySQL, il vous sera plus facile d'ajouter des options utiles comme l'affichage de raisons personnalisées pour les bannissements, les débannissements automatiques, etc.

Alors là, on va en bannir, des IP ! :D

Première solution : MySQL

Pour commencer, il vous faut créer une table sur votre base de données (si vous n'en avez pas, passez à la seconde solution ^^ ). Je vous donne une structure d'exemple, changez-la comme vous voulez pour l'adapter à vos besoins :

CREATE TABLE `ban` ( `ban_id` MEDIUMINT( 9 ) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY , `ban_ip` INT NOT NULL , UNIQUE (`ban_ip`) );

Cela fait, nous allons créer un nouveau fichier dont le code ne vous sera donné qu'en guise d'exemple. Prenez note que je n'ai pas pris soin de protéger les codes, car vous seuls savez comment les intégrer à votre site web et à votre interface d'administration. Vous devez protéger l'accès à ces sections ! Bien entendu, il va de soi que je ne vous donnerai pas de fichiers complets, seulement les parties concernées. ;)

Bannir une adresse IP

Pour bannir une adresse IP, nous suivrons cette démarche :

  • on affiche un formulaire demandant l'adresse à bannir ;

  • si le formulaire est posté, on vérifie la validité de l'adresse IP ;

  • si celle-ci est valide, on la convertit en entité numérique grâce à ip2long(), sinon on réaffiche le formulaire avec une erreur ;

  • si tout est valide, on insère une entrée dans notre table et on affiche un message d'information.

Tout d'abord, le formulaire :

<form action="ban.php" method="post">      <fieldset>           <legend>Bannir une adresse IP</legend>           <p><label for="ip">Adresse à bannir : </label></p>           <input type="text" name="ip" id="ip" />           <input type="submit" value="Bannir" />      </fieldset> </form>

Pensez bien à remplacer l'action du formulaire pour y donner le bon nom de page vers laquelle poster. Pour ceux qui se posent la question, la balise <label></label> sert à joindre un bout de texte à un champ de formulaire. Ainsi, en cliquant sur « Adresse à bannir », le focus sera donné au champ dont l'id est « ip ». Très pratique. :)

Maintenant, on va traiter les données de ce formulaire. Le code ci-dessous suppose que vous ayez une connexion MySQL active. Il reprend le formulaire ci-dessus et l'inclut dans le cas où il n'a pas été posté :

<?php $isset = isset($_POST['ip']); //true si le formulaire est posté $erreur = false; //On change cette valeur à la moindre erreur if ($isset) { //Si le formulaire a été posté if (!empty($_POST['ip'])) { $ip = ip2long($_POST['ip']); if ($ip != false && $ip != -1) { //Si l'ip est valide require ('libs/div/is_ban.php'); if (!is_ban($ip)) { mysql_query('INSERT INTO ban (`ip`) VALUES(\'' . $ip . '\')'); print('Cette adresse est désormais non-autorisée.'); } else print ('Cette adresse est déjà bannie.'); } else $erreur = 1; //L'ip est invalide, erreur #1 } else $erreur = 0; //Le champ est vide, erreur #0 } if (!$isset || $erreur !== false) { //Si le formulaire n'a pas été posté ou qu'une erreur a été détectée $erreurs = array('Vous devez entrer une adresse ip.', 'L\'adresse ip est invalide.'); if ($erreur !== false) { //Si on a une erreur, on l'affiche print('<p style="color: red; font-weight: bold;">' . $erreurs[$erreur] . '</p>'); } //On affiche le formulaire print ('<form action="ban.php" method="post"> <fieldset> <legend>Bannir une adresse IP</legend> <p><label for="ip">Adresse à bannir : </label></p> <input type="text" name="ip" id="ip" /> <input type="submit" value="Bannir" /> </fieldset> </form>'); } ?>

Je vous l'ai dit, c'est super simple ! À vous d'inclure ce code à votre panneau d'administration, et je le répète, protégez-le ! ;)

La fonction ip2long() retourne l'adresse IP sous forme d'entité numérique, je l'ai dit. Si l'adresse IP est invalide, elle retourne -1 avec PHP3 et PHP4, tandis qu'avec PHP5, elle retourne false : un caprice. Vous pouvez modifier le script pour n'effectuer que le test logique qui correspond à la version de PHP que vous utilisez, si vous la connaissez (sinon, phpinfo).

Obtenir la liste des adresses bannies

Pour voir la liste des adresses bannies, il nous suffit de faire une simple requête SELECT sur notre table. Lorsque l'on aura écrit le script pour débannir des adresses, il serait astucieux de placer, sur chaque adresse de cette liste, des liens pour débannir. ;) Le code, vous êtes capables de le faire seuls, je l'espère. :p Enfin, pour rassurer les plus inquiets (le code suppose que vous avez une connexion MySQL active) :

<?php //Quoi de plus bête comme requête :p $req = mysql_query("SELECT * FROM ban"); if($res = mysql_fetch_assoc($req)) { print('<ul>'); do { print ('<li>' . long2ip($res['ban_ip']) . '</li>'); } while($res = mysql_fetch_assoc($req)); print ('</ul>'); } else print ('Aucune adresse IP bannie.'); //Personne de banni, on le signale ?>

C'est très simple et encore une fois, je vous laisse le soin de protéger le tout efficacement.

Débannir une adresse IP

Pour débannir une adresse, nous n'avons qu'à supprimer l'entrée correspondante dans la base de données. Pour rappel, afin de supprimer une entrée dans une table MySQL, nous devons utiliser la requête DELETE. Voici un code tout simple :

<?php if (isset($_GET['ip'])) { mysql_query('DELETE FROM ban WHERE ban_ip=\'' . $_GET['ip'] . '\''); if (mysql_affected_rows() == 0) print ('Cette adresse IP n\'était pas bannie.'); else print ('L\'adresse IP a été débannie.'); } else print ('Vous n\'avez spécifié aucune adresse IP.'); ?>

Vous pouvez maintenant ajouter les liens à votre liste d'adresses IP, avec cette ligne dans votre boucle par exemple :

print ('<li><a href="supp.php?ip=' . $dselect['ban_ip'] . '" title="Débannir cette adresse">' . long2ip($dselect['ban_ip']) . '</a></li>');

Voilà, c'est tout pour MySQL, vous pouvez passer à la dernière partie qui consiste à restreindre l'accès aux adresses IP bannies (non, ça ne se fait pas tout seul :p ).

Seconde solution : un fichier texte

Ici, on va apprendre à utiliser une solution plus légère. Forcément, vu la quantité très mince de ressources consommées par cette alternative, les options possibles en sont réduites. Mais soyez sans crainte, vous pourrez gérer des centaines de bannissements de cette manière : c'est plutôt au niveau des débannissements automatiques et des messages personnalisés que ça se complique. Mais tout ça, c'est facultatif. ;)

Tout d'abord, créez un fichier ips.txt, puis placez-le où vous en avez envie. N'oubliez pas de modifier les chemins d'accès de mes exemples. ;) Ce fichier contiendra une adresse IP par ligne. Vous l'aurez deviné, les adresses figurant dans ce fichier seront interdites d'accès au site.

Bannir une adresse ip

Pour bannir une adresse ip, nous devons ajouter une ligne contenant l'adresse en question au fichier ips.txt. Nous allons élaborer notre script en suivant les étapes suivantes :

  • on affiche le formulaire demandant l'adresse à bannir ;

  • si le formulaire est posté, on vérifie la validité de l'adresse IP ;

  • si celle-ci est valide, on la convertit en entité numérique grâce à ip2long(), sinon on réaffiche le formulaire avec une erreur ;

  • si tout est valide, on ajoute une ligne dans notre fichier, et on affiche un message d'information.

Le formulaire demandant l'adresse IP est le même que celui que vous auriez écrit si vous aviez opté pour la solution MySQL :

<form action="ban.php" method="post">      <fieldset>           <legend>Bannir une adresse IP</legend>           <p><label for="ip">Adresse à bannir : </label></p>           <input type="text" name="ip" id="ip" />           <input type="submit" value="Bannir" />      </fieldset> </form>

Maintenant, nous allons traiter les données de ce formulaire. Pour ouvrir notre fichier, nous utiliserons la fonction fopen() et nous ouvrirons le fichier en mode 'a', un mode d'écriture qui place le pointeur à la fin du fichier. Pour ouvrir votre fichier, le dossier qui le contient et lui-même doivent avoir un chmod de 777. Voici le code, dont la structure est la même que celui de la première solution :

<?php $isset = isset($_POST['ip']); //true si le formulaire est posté $erreur = false; //On change cette valeur à la moindre erreur if ($isset) { //Si le formulaire a été posté if (!empty($_POST['ip'])) { $ip = ip2long($_POST['ip']); if ($ip != false && $ip != -1) { //Si l'IP est valide require ('libs/div/is_ban.php'); if (!is_ban(long2ip($ip))) { $fichier = fopen('ips.txt', 'a'); //On ouvre en mode 'a' fwrite($fichier, $ip . "\n"); //On ajoute la ligne avec l'IP fclose($fichier); //On ferme le fichier print('Cette adresse est désormais non-autorisée.'); } else print ('Cette adresse est déjà bannie.'); } else $erreur = 1; //L'IP est invalide, erreur #1 } else $erreur = 0; //Le champ est vide, erreur #0 } if (!$isset || $erreur !== false) { //Si le formulaire n'a pas été posté ou qu'une erreur a été détectée $erreurs = array('Vous devez entrer une adresse IP.', 'L\'adresse IP est invalide.'); if ($erreur !== false) { //Si on a une erreur, on l'affiche print('<p style="color: red; font-weight: bold;">' . $erreurs[$erreur] . '</p>'); } //On affiche le formulaire print ('<form action="ban.php" method="post"> <fieldset> <legend>Bannir une adresse IP</legend> <p><label for="ip">Adresse à bannir : </label></p> <input type="text" name="ip" id="ip" /> <input type="submit" value="Bannir" /> </fieldset> </form>'); } ?>

Maintenant que nous pouvons bannir des adresses IP, nous allons voir comment récupérer la liste des adresses bannies. ;)

Obtenir la liste des adresses bannies

Pour récupérer cette liste, nous devrons tout d'abord lire le contenu de notre fichier et le stocker dans une variable. Pour ce faire, nous utiliserons la fonction file() qui nous retourne un array contenant les différentes lignes du fichier. Si ce n'est déjà fait, créez un fichier ips.txt que vous laissez vide. Voici un exemple très simple :

<?php //On récupère les adresses dans un tableau $adresses = explode("\n", file_get_contents('ips.txt')); $nbr = count($adresses); if ($nbr != 0) print ('<ul>'); //S'il y a des adresses, on ouvre une liste foreach ($adresses as $key=>$value) { if ($value != '') print ('<li>' . long2ip($value) . '</li>'); //On affiche l'ip } if ($nbr != 0) print ('</ul>'); //On ferme la liste s'il y a lieu else print ('Aucune adresse IP bannie.'); //Personne de banni, on le signale ?>

Appeler le centre

Avez-vous besoin d'un coach de formation?

Il vous aidera à comparer différents cours et à trouver la solution la plus abordable.

Restreindre l'accès d'un site à certaines adresses IP

Prix sur demande