I. Présentation▲
Le module Apache GeoIP, développé et maintenu par la société MaxMind, vous permet non seulement de connaître la provenance de manière relativement fiable d'un visiteur, mais de la faire intervenir dans vos développements ou encore dans la configuration du serveur.
La société MaxMind ne fournit pas seulement des modules pour les différentes versions du serveur web Apache, mais aussi des bibliothèques pour divers langages (C - la base « commune », PHP, Perl, Java, etc.). Cependant, une intégration au niveau du serveur lui-même présente quelques avantages et prérequis.
L'unique condition préalable est de pouvoir accéder au serveur (donc de disposer des droits) pour pouvoir installer ce module et reconfigurer Apache.
Par contre, les enjeux sont multiples.
- Les informations relatives à la géolocalisation sont transmises sous forme de variable d'environnement au langage serveur employé. Leur récupération n'en est que plus aisée et ceci offre une certaine indépendance : il n'y a ainsi nul besoin d'installer une bibliothèque pour chaque langage que vous pourriez être amené à utiliser sur votre serveur.
- Apache devient alors capable d'interagir en fonction de la localisation du client. Il peut ainsi directement effectuer un filtrage des clients, les rediriger…
II. Mise en place▲
Ici ne sera présentée que l'installation du module sous forme dynamique afin de pouvoir l'activer ou désactiver à volonté et pour une mise en place rapide (nous évitant une recompilation complète d'Apache).
II-A. À partir des sources▲
Il est nécessaire de télécharger trois choses avant de commencer :
-
la bibliothèque C, dépendance requise au module que nous compilerons dans un deuxième temps :
Sélectionnezcd ~ wget http://www.maxmind.com/download/geoip/api/c/GeoIP-
1
.4
.5
.tar.gzVérifier éventuellement qu'il n'existe pas de versions plus récentes que ce soit maintenant pour la bibliothèque C comme pour les sources du module que nous abordons ci-dessous.
-
les sources du module propres aux versions de la branche 2 d'Apache :
Sélectionnezwget http://www.maxmind.com/download/geoip/api/mod_geoip2/mod_geoip2_1.
2
.5
.tar.gz - enfin, télécharger une base de données mise à disposition gratuitement (donc plus limitée). Il en existe deux : celle de base dont vous ne pourrez tirer que le pays du client et une seconde fournissant des informations plus précises puisque capable de vous donner la ville et la région de l'internaute.
# La base "pays" uniquement
wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz
# La base "allégée des villes"
wget http://www.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz
La fiabilité des bases de données mises gratuitement à votre disposition est estimée à 98 % pour celle des pays et à 69 % en ce qui concerne celle des villes. Avec une perte supplémentaire d'environ 1,5 % tous les mois si vous ne téléchargez pas sa nouvelle version paraissant de manière mensuelle.
Procédons à leur installation :
-
Comme mentionné plus haut, un certain ordre doit être respecté : il faut commencer par l'API C de GeoIP puisque le module repose sur celle-ci.
Décompressez l'archive :Sélectionneztar xzf GeoIP-
1
.4
.5
.tar.gz -C /usr/local
/srcPuis procédez à la compilation et installation (requérant les droits administrateur) :
Sélectionnezcd /usr/
local
/src/GeoIP-1
.4
.5
/ ./configure --prefix
=
/usr/local
/geoip make make installPour compiler cette bibliothèque, vous devrez posséder sur votre système les fichiers d'entête de la bibliothèque zlib. Si ce n'est pas le cas, cherchez un paquet éponyme suffixé de dev ou devel puis installez-le.
-
Vient ensuite le tour du module Apache. Détarez les sources de celui-ci…
Sélectionneztar xzf ~/mod_geoip2_1.
2
.5
.tar.gz -C /usr/local
/src… puis passez à sa compilation.
Sélectionnezcd /usr/
local
/src/mod_geoip2_1.2
.5
/ apxs2 -i -a -L/usr/local
/geoip/lib -I/usr/local
/geoip/include -lGeoIP -c mod_geoip.cPour cette étape, il vous sera nécessaire de posséder les fichiers d'entête d'Apache. Ceux qui ont donc installé leur serveur sous forme de paquet binaire auront sans doute à chercher un paquet nommé sur le modèle apache2(-threaded|mpm)-dev(el) ou encore httpd-dev(el).
Suivant votre système, la commande apxs2 pourra être plus simplement appelée apxs.
La commande apxs2, telle qu'elle a été utilisée ci-dessus suppose que le répertoire où elle est située figure comme valeur de la variable d'environnement PATH. À défaut, il est possible d'en préciser son chemin.
- Décompressez la base que vous avez récupérée plus tôt à l'aide de gunzip :
gunzip GeoIP.dat.gz
# ou suivant la base choisie
gunzip GeoLiteCity.dat.gz
Pour la déplacer vers un répertoire plus « approprié » :
cp ~/GeoIP.dat /usr/local
/geoip/share/GeoIP/
# ou suivant la base choisie
cp ~/GeoLiteCity.dat /usr/local
/geoip/share/GeoIP/
Pour la suite, assurez-vous que cette base est accessible en lecture de tous (surtout de l'utilisateur sous lequel fonctionne Apache).
Nous pouvons maintenant passer à la configuration d'Apache. Vérifiez tout d'abord la présence d'une ligne LoadModule ressemblant à celle ci-dessous (chemin à adapter) qui chargera notre nouveau module :
LoadModule
geoip_module /usr/lib/apache2/modules/mod_geoip.so
Rajoutez-la à la suite des autres si elle se fait porter absente. Gardez le fichier ouvert en vue de placer une ligne LoadFile avant la précédente, nécessaire au bon fonctionnement du module, afin qu'Apache puisse auparavant charger la librairie geoip de laquelle dépend le module :
LoadFile
/usr/local/geoip/lib/libGeoIP.so
Puis activez et configurez à présent notre module par la mention des lignes suivantes :
<IfModule mod_geoip.c>
GeoIPEnable On
GeoIPDBFile /usr/local/geoip/share/GeoIP/GeoIP.dat # ou /usr/local/geoip/share/GeoIP/GeoLiteCity.dat
</IfModule>
À ce stade vous devriez relancer le serveur et vérifier le bon fonctionnement du tout en poursuivant directement à la partie intitulée.
II-B. Exemple de Debian Etch pour une installation à partir des paquets binaires prévus▲
Dans la mesure où votre système prévoit des paquets pour le module GeoIP, vous avez tout intérêt à les privilégier : son installation n'en sera que plus rapide et plus facile.
Dans le cas de Debian, cela peut se résumer à la commande suivante :
aptitude install libapache2-mod-geoip
Debian vous installera uniquement la base de données « pays ». Si vous prévoyez d'en utiliser une autre ou une version plus à jour, il vous faudra éventuellement décommenter la directive GeoIPDBFile du fichier /etc/apache2/mods-available/geoip.conf en retirant le caractère dièse (#) apparaissant en début de ligne et en modifier la valeur pour pointer sur la vôtre.
Normalement le module devrait être actif par défaut à l'issue de son installation. Assurez-vous-en, en contrôlant la présence des liens symboliques geoip.conf et geoip.load dans le répertoire /etc/apache2/mods-enabled ou exécutez la commande a2enmod, qui le fera pour vous dans le cas contraire :
a2enmod geoip
Enfin, (re)démarrer le serveur web :
/etc/init.d/apache2 force-reload
III. Utilisation▲
Les variables d'environnement pour la base de données de type « pays » sont :
- GEOIP_COUNTRY_CODE : code international du pays (suivant la norme ISO 3166) ;
- GEOIP_COUNTRY_NAME : nom complet du pays (en anglais).
Si GeoIP est incapable de déterminer la provenance de l'utilisateur, les variables ne seront pas définies.
En ce qui concerne la base de données « allégée des villes », viennent s'ajouter à la liste précédente :
- GEOIP_REGION : un code indiquant la région (voir les valeurs plus bas ainsi que leur correspondance pour la France) ;
- GEOIP_CITY : la ville ;
- GEOIP_DMA_CODE : code DMA (Designated Market Area) attribué à une zone où les fréquences (télévision, radio, etc.) sont identiques (concerne les États-Unis, valeur par défaut : 0) ;
- GEOIP_AREA_CODE : indice téléphonique représentant une zone précise (concerne les États Unis, valeur par défaut : 0) ;
- GEOIP_LATITUDE : la latitude ;
- GEOIP_LONGITUDE : la longitude ;
- GEOIP_POSTAL_CODE : le code postal (concerne uniquement les États-Unis, ne sera pas définie pour tout autre pays).
Les valeurs de la variable GEOIP_REGION pour les différentes régions françaises avec leur correspondance sont :
Région |
Code |
---|---|
Alsace |
C1 |
Aquitaine |
97 |
Auvergne |
98 |
Basse-Normandie |
99 |
Bourgogne |
A1 |
Bretagne |
A2 |
Centre |
A3 |
Champagne-Ardenne |
A4 |
Corse |
A5 |
Franche-Comté |
A6 |
Haute-Normandie |
A7 |
Île-de-France |
A8 |
Languedoc-Roussillon |
A9 |
Limousin |
B1 |
Lorraine |
B2 |
Midi-Pyrénées |
B3 |
Nord-Pas-de-Calais |
B4 |
Pays de la Loire |
B5 |
Picardie |
B6 |
Poitou-Charentes |
B7 |
Provence-Alpes-Côte d'Azur |
B8 |
Rhône-Alpes |
B9 |
III-A. Par l'usage d'un langage de programmation côté serveur▲
La récupération des différentes « variables » créées par le module de géolocalisation dépend de la manière dont ce dernier a été configuré. En effet, suivant la valeur de sa directive GeoIPOutput, elles ne seront pas accessibles de la même manière.
- Lorsque GeoIPOutput a pour valeur Notes, les variables relatives à la géolocalisation du client ne sont créées que dans la table interne d'Apache appelée Notes. Ce n'est pas, de ce fait, la méthode la plus facile pour ensuite les atteindre avec un langage serveur.
- En revanche, avec la valeur Env, toutes ces variables sont exportées à la manière des variables d'environnement système. Cette forme facilite fortement leur usage, quel que soit le langage employé côté serveur, comme nous le verrons ci-dessous.
- Enfin, la valeur All (par défaut) est à recommander puisque toutes ces variables seront définies deux fois, selon les méthodes des deux points précédents. Ainsi il n'y a plus lieu de se demander par quel moyen y avoir recours.
III-A-1. PHP▲
Étant donné qu'il est plus courant d'utiliser PHP en tant que module Apache, vous disposez alors sans doute de l'extension apache qui fournit, entre autres, la fonction apache_note. Ainsi que GeoIPOutput ait pour valeur Notes ou All, vous serez en mesure d'exploiter toutes les variables GEOIP.
Cependant, beaucoup trouveront certainement plus naturel de trouver ces informations dans le tableau superglobal $_SERVER. Chose possible dès lors que GeoIPOutput sera positionné à All ou Env.
Ci-dessous, un code PHP listant l'ensemble des variables GEOIP, dans l'hypothèse où elles vous sont mises à disposition comme des variables d'environnement :
III-A-2. Ruby▲
Par contre dans le cas de Ruby, il sera sans doute plus facile de trouver ces variables dans le hash ENV, recensant, comme son nom l'indique, toutes les variables d'environnement (ce qui implique que GeoIPOutput a pour valeur Env ou bien All) du fait de son utilisation CGI. Le code équivalent au script PHP présenté ci-dessus pourrait s'écrire de la sorte :
ENV
.each do
|
k,v|
puts "
#{
k}
=>
#{
v}
"
if
k ~=
/GEOIP/
i
end
III-A-3. Perl▲
Pour des raisons autant de facilité que de portabilité, seule la méthode visant à exploiter l'exportation de ces variables comme variable d'environnement sera présentée (impliquant de nouveau GeoIPOutput à Env ou All). Vous les trouverez donc dans le hachage %ENV :
III-A-4. Autres langages▲
Nous vous invitons, pour ce qui est des autres langages, à consulter leurs documentations respectives ou à vous orienter sur les forums.
III-B. Dans le cadre de la configuration du serveur seul▲
III-B-1. Première application : interdire l'accès à certains utilisateurs étrangers▲
Une première application, allant à l'encontre des principes d'accessibilité et de liberté d'Internet, pourrait être de bloquer des utilisateurs faisant partie de tel ou tel pays voire, pourquoi pas, de n'autoriser que ceux de pays prédéterminés.
En guise d'exemple, nous souhaitons bloquer les internautes russes et chinois. Se présentent deux possibilités :
-
En introduisant une variable d'environnement :
SélectionnezSetEnvIf
GEOIP_COUNTRY_CODE ^CN|RU$ FORBIDDEN=1 Deny from env=FORBIDDENNotre variable d'environnement FORBIDDEN ne sera créée que si l'on sait que le client est russe (code pays « RU ») ou chinois (de code « CN ») d'après le module GeoIP. Le fait que cette variable soit dans ces conditions définies lui vaudra un blocage (le serveur retournera la page d'erreur 403 au lieu de la page attendue).
- À l'aide du module de réécriture :
RewriteEngine
on
RewriteCond
%{ENV:GEOIP_COUNTRY_CODE} ^CN|RU$
RewriteRule
.* - [F]
Strictement la même chose, écrite avec des règles de réécriture. En réalité, le module a été quelque peu détourné de son but premier : le tiret fourni en deuxième paramètre de la directive RewriteRule indique qu'il ne faut pas effectuer de réécriture et c'est l'option F (pour forbidden, située entre les crochets, qui va retourner l'erreur 403 pour nos clients identifiés comme russes et chinois.
III-B-2. Deuxième application : redirection suivant le lieu de connexion▲
Pour ce second exemple d'application, l'objectif consiste à distinguer la provenance de l'utilisateur afin d'éventuellement rediriger celui-ci sur la page qui lui serait potentiellement la plus intéressante. Ici, nous supposerons qu'il s'agit d'un site dédié à la région Corse (code associé : A5 - voir le tableau plus haut ; de domaine corse.fr).
Si l'utilisateur est reconnu comme étant local, nous le redirigerons sur la page vie-pratique.html fournissant diverses informations utiles et actualisées lorsqu'il demandera pour la première fois le document d'index (index.html). Ce premier passage sera marqué par un cookie, expirant après une heure, dans le but de ne pas entraver sa navigation.
On pourrait schématiser cette opération par l'algorithme suivant :
si GEOIP_REGION = "A5" et page_courante = "/index.html" et non cookie_defini("local")
alors
créer_cookie("local", "1", ".corse.fr", 60, "/")
/**
* Paramètres :
* - nom du cookie
* - sa valeur
* - le nom de domaine auquel il est associé
* - durée en minutes avant expiration
* - le chemin sur lequel il s'applique
**/
redirection("/vie-pratique.html")
fsi
Qui se traduirait à l'aide d'une règle de réécriture :
RewriteEngine
on
RewriteCond
%{ENV:GEOIP_REGION} =A5 # Règle n°1
RewriteCond
%{HTTP_COOKIE} !\blocal\b # Règle n°2
RewriteRule
^(:?index.html)?$ /vie-pratique.html [L,CO=local:1:.corse.fr:60:/] # Règle n°3
La première règle permet d'indiquer que seules les connexions établies depuis la région Corse, c'est-à-dire lorsque GEOIP_REGION est égal à A5, sont concernées.
La deuxième vérifie qu'un cookie nommé local n'a pas été créé. Si tel était le cas, on n'abandonnerait là la lecture de la règle, l'internaute ne serait pas redirigé.
Enfin l'opération de réécriture ou redirection, qui sera appliquée si les conditions précédentes ont été remplies et que le document demandé est la page d'index. À ce moment on en profite pour marquer la redirection en créant le cookie (option CO).
IV. Epilogue▲
Bien qu'il existe de multiples solutions pour l'usage de l'« API » GeoIP, prenons pour preuve PHP qui se décline en une extension, en une bibliothèque écrite en PHP pur ou un paquet PEAR. Nous espérons, au travers de cet article, avoir montré tout l'intérêt de la déporter au sein du serveur web. D'autant plus, qu'un module est disponible pour chacune des branches d'Apache (l'installation du module pour une version 1.3 étant sensiblement identique).
Liens Developpez en relation :
Liens externes :
V. Remerciements▲
Nous tenons à remercier RideKick pour sa relecture attentive.