Protéger ses données exposées sur le WEB n'est pas toujours évident et comporte quelques pièges qui donnent une illusion de sécurité alors qu'il n'en est rien. Ce tutoriel ne va pas, loin de là, couvrir tous les aspects du sujet, mais juste tenter d'apporter quelques bases permettant de se protéger à travers quelques cas pratiques.
Pour tout ce qui suit, ou presque, existe deux méthodes de paramétrages. La plus simple consiste à placer dans le dossier web à protéger un fichier .htaccess qui contiendra une configuration spécifique à ce dossier. Le contenu d'un tel dossier pourrait être :
Cette méthode a le mérite de la simplicité et protège autant le dossier lui-même que les sous-dossiers qu'il contient, sauf si un autre fichier .htaccess y contrevient.
L'autre méthode, sûrement plus pérenne, est de modifier directement un des fichiers de configuration Apache. Ces derniers se trouvent généralement en /etc/httpd et vous pouvez soit modifier /etc/httpd/httpd.conf, soit créer votre propre fichier .conf dans le dossier /etc/httpd/conf.d. A notez que les localisations peuvent changer d'une distribution à l'autre. Dans tous les cas la syntaxe est à peu près la même que pour un .htaccess:
La seule différence ici est donc la balise Directory qui encadre le code qui aurait été dans un fichier .htaccess et qui indique le chemin absolu à protéger, comme la position d'un .htacess l'aurait fait. Une autre différence cependant tient à la manière dont apache gère les deux types de fichier. En effet, un .htaccess est affectif tout de suite, dés que le fichier est créé et contient les données. En revanche un fichier de configuration nécessite le redémarrage du serveur Apache par un redémarrage du serveur apache.
Maintenant le choix .htaccess ou fichier de configuration vous appartient. Tout ce qui suit devrait fonctionner dans les deux cas.
Si nous voulons qu'Apache protège notre dossier, il nous faut lui fournir une liste d'utilisateurs, voire de groupes d'utilisateurs. C'est ce que fait le code suivant en créant d'abord un répertoire et en changeant ses droits, puis en ajoutant avec la commande Apache htpasswd le premier utilisateur (le chemin du dossier et le nom du fichier n'ont aucune importance) :
Pour l'ajout des utilisateurs suivants, le fichier étant déjà créé, le paramètre -c n'est plus nécessaire :
Un utilisateur préalablement créé, pourra être retiré de la manière suivante :
Maintenant si nous vidons le contenu du fichier /var/secured/passwords, nous aurons ceci :
Nous avons donc maintenant les utilisateurs, leur mot de passe, il ne nous reste plus qu'à définir des groupes, même si c'est optionnel. Si nous voulons indiquer que l'utilisateur gaston appartient au groupe webmasters il suffit de créer un second fichier /var/secured/groups contenant les données suivantes :
La syntaxe est ici simple à comprendre. AuthName est le message qui sera affiché dans la boite de dialogue de saisie de l'identifiant et du mot de passe. Gardez cela en tête pour ne pas y mettre de chose trop explicites comme "Bienvenue dans le site contenant tous mes numéros de carte bleue"
.
Le second paramètre, AuthType indique à Apache d'utiliser le protocole Basic pour authentifier l'utilisateur. Comme son nom le laisse présager, ce protocole est le plus simple, le plus compatibles avec tous les navigateurs, mais aussi le moins sécurisé comme nous le verrons un peu plus loin. D'autres type d'authentification existent sous Apache par l'intermédiaire de modules spécifiques, comme nous allons le voire aussi plus loin.
Ensuite nous avons AuthUserFile qui indique le chemin vers le fichier que nous avons créé dans le chapitre précédent, et contenant donc nos utilisateurs et leurs mots de passe.
Enfin, la règle d'authentification à proprement parler, require valid-user. Elle indique à Apache que tout utilisateur ayant réussi à rentrer son mot de passe est autorisé à rentrer dans le dossier. Si nous voulions spécifiquement autoriser Robert à rentrer, nous aurions mis require user robert, et pour Gaston et Martine, cela aurais été require user gaston martine.
Vu que nous avons créé un fichier de groupes d'utilisateur au chapitre précédent, autant en profiter. Et si voulions n'autoriser que le groupe webmaster à rentrer, nous aurions cette fois un fichier .htaccess comme ceci :
Plus complet, les deux chemins vers les deux fichiers mots de passe et groupes sont indiqués (apparition du mot clef AuthGroupFile).
Enfin il est possible de panacher tout cela avec des choses du genre : require user robert, group webmaster. Ceci indique à apache que seuls les membres du groupe webmaster sont autorisés, à l'exception de robert.
Comme je le disais plus haut, il y a de nombreux modules liés à l'authentification disponibles pour Apache sous la forme de modules. Par exemple si vous vouliez utiliser un protocole Digest au lien du simple Basic, vous utiliseriez le module mod_auth_digest.
De même différent modules permettent de vérifier les utilisateurs, groupes et mots de passe sur une base de donnée plutôt qu'un fichier texte, ou encore un serveur ldap par le biais du module mod_authnz_ldap. Il dépends du module Apache d'accès à LDAP, mod_ldap qu'il faut aussi installer. Ce module permet une authentification Basic adossée à un base LDAP. Un bloc de configuration pour un tel système se présente comme cela
Comme vous le voyez l'esprit est à peu prés le même que précédemment. La ligne AuthBasicProvider indique à apache de se baser sur un serveur LDAP plutôt qu'un fichier. Les coordonnées du serveur apparaissent avec la ligne AuthLDAPURL qui indique le nom de la machine, le port en écoute, ainsi que le domaine pris en charge.
Les deux attributs suivant permettent au module apache de se repérer dans les enregistrements LDAP et d'y trouver les utilisateurs. Le paramétrage que j'utilise ici se base sur la disposition standard d'une base LDAP sous Unix et est à adapter pour un ActiveDirectory sous Windows, par exemple.
Enfin la dernière ligne indique à apache de n'autoriser à rentrer que le group ldap spécifié (ici webmasters). L'utilisateur de ldap-user (ex. Require ldap-user Gaston) permettrait de n'autoriser qu'un utilisateur spécifique. Et ici aussi, le panachage est autorisé en séparant les éléments par des virgules.
A ce stade, nous avons déjà pas mal d'outils pour protéger nos données mais si nous nous arrêtions à cela, cela ne servirait à rien... En effet, ce type de sécurité est aussi valable qu'une porte blindée sur des murs en cartons. Car le gros inconvénient du mode basic est que les mots de passes circulent en clair. Protéger par mot de passe un dossier accessible avec le protocole HTTP est donc très dangereux. Une simple écoute active (mode Promisc) du réseau, si par exemple vous utilisez cela de votre bureau, dévoile aussi sûrement vos secrets que si vous les aviez envoyé à tout le monde par courriel. Pour parfaire notre protection il est donc obligatoire de mettre en œuvre le protocole HTTPS, ce que j'aborderais dans un autre article.
Un problème classique est de se retrouver avec une bande passante "volée" parce qu'un Malotru a eu l'indélicatesse de mettre vos images en référence directe sur son site. Ici, pas question de mettre un mot de passe qui bloquerait les utilisateurs légitimes. Les techniques précédentes sont donc inutiles. A la place nous allons utiliser les variables dont nous disposons au sein d'Apache et particulièrement du Referer.
Pour ceux qui ne le savent pas, un navigateur WEB a pour obligation de transmettre au serveur l'adresse WEB de la page qui contient le lien qui a permis d'arriver sur notre site. Cette indiscrétion est déjà bien connu et c'est elle qui permet de savoir d'où viennent nos visiteurs. Cette adresse est le fameux Referer.
Ce qui est un peu moins connu c'est que chaque élément lié à une page de notre site (ex. une image ou une feuille de style), est demandée au serveur distant avec lui aussi un Referer. Sauf que cette fois, c'est l'adresse de notre propre site qui est passé par le navigateur, ce qui est somme toute très logique.
En d'autres termes, toute demande d'image n'ayant pas notre site pour Referer, est sûrement l'objet d'un vol de bande passante… C'est cette caractéristique que nous allons exploiter avec ce code qui peut aussi bien être, comme toujours, dans un .htaccess qu'un fichier de configuration Apache.
Ce qui se passe c'est que si le Referer est bien notre site, nous positionnons une variable acces_local à 1. Ensuite nous ajoutons une règle qui interdit le téléchargement des images (Deny from all) sauf pour les requêtes qui ont la variable acces_local définie. Voilà, c'est tout. La directive FilesMatch est elle là pour n'opérer cette sécurité que sur les fichiers images, feuilles de style, scripts, etc. Il serait en effet un peu idiot d'appliquer cette règles au fichier .php par exemple, cela interdirait systématique l'accès du site à tout le monde….
Vous aurez remarqué dans l'exemple précédent la syntaxe un peu étrange du paramètre de la directive SetEnvIfNoCase. On appelle cela une expression régulière . Une expression régulière est une sorte de motif permettant de décrire une chaîne de caractère attendue. On peut ainsi créer des expressions régulières décrivant un numéro de téléphone ou une adresse courriel. Dans l'exemple précédent, elle signifiait "toute les URL qui commencent par (symbole ^) http://www.monsite.net/". Les \. étaient là pour indiquer que l'on voulait que le vrai caractère . soit utilisé, car sinon, ce symbole a un sens particulier dans une expression régulière.
Maintenant imaginons qu'un vilain spammeur qui me fasse des misères et que son adresse IP varie de 81.95.144.X à 81.95.147.X. Je peux le bloquer par la configuration suivante :
C'est à peu prés le même exemple que précédemment sauf que cette fois on utilise, non pas Referer mais Remote_Addr qui est l'adresse IP du navigateur client. Je ne vais pas faire ici un cours sur les expressions régulière, il y a de magnifique tutoriaux sur ce sujet.
Juste un dernier exemple, si cette fois c'est la chaîne d'identification ( User Agent ) d'un navigateur que je veux bloquer, par exemple un bot malveillant :
Là, j'utilise une directive un peu spéciale qui a le même rôle que les précédentes mais cette fois sur la variable User_Agent sans distinction de majuscules/minuscules.
Bien évidement, vous pouvez mettre une liste complète de définitions avant d'insérez votre directive Deny :
Cette méthode n'est pas aussi fiable que je le voudrais car les adresses change, et les chaînes d'identification de navigateur aussi. Mais au moins est-ce un moyen de contrer efficacement une attaque ponctuelle. Pour une liste complète des directives touchant à la définition de variables, je vous renvoie à la documentation d'Apache.
Même si cela fonctionne, passer par les variables pour interdire une IP avec des expressions régulières est un peu sauvage pour un usage courrant. Si vous voulez pour votre dossier, ne soit accessible que pour une seule IP, ou un groupe d'IP, nous pouvons plus simplement utiliser la directive Deny From. Par exemple ici, pour n'autoriser que l'IP 192.168.0.10 nous utiliserons la configuration suivante :
Nous pouvons assouplir la règle en enlevant un group de chiffre à la fin de l'IP. Par exemple Allow from 192.168.0 autorise les adresses allant de 192.168.0.0 à 192.168.0.255, à se connecter.
Pour finir, un petit mélange. Imaginons que nous protégions notre dossier par mot de passe via LDAP mais qu'en même temps nous ayons besoins que les clients se connectant d'un adresse IP spécifique, puise le faire sans mot de passe. Cela nous donnerais le code suivant :
Rien d'inconnu maintenant dans ces syntaxes, à l'exception de la dernière ligne, qui fait toute la différence. En effet, elle indique à Apache que l'une ou l'autre des conditions suffit à autoriser l'accès : soit l'IP, soit le mot de passe.
L'article est déjà long et nous sommes loin d'avoir totalement couvert le sujet. J'espère seulement que cela vous donnera assez de pistes pour trouver la solution qui convient le mieux à vos besoins. L'agressivité et l'automatisation des attaques comme en témoignent souvent les fichiers de traces, prouvent que ce genre de précaution est simplement obligatoire. Il n'y a à ma connaissance pas de moyens systématique de valider qu'un serveur est correctement fermé, et ce qui est réellement ouvert. Google permet par le biais d'une requête de type site:mon-site.com d'avoir la liste de ce qu'il voit mais cela se limite à ce qui a été lié, quelque part, sur le Web, ce qui est loin d'être suffisant.
Car croire que le seul fait de ne pas publier sur le web le lien vers un dossier le rend invisible est pure crédulité comme en témoigne cette ânerie là, , que j'avais trouvé par hasard, en bidouillant l'URL d'annulation d'un courriel de pub, sans l'aide google.
- répondre
Dab, le 4 May, 2008 - 22:37A noter le module mod_security pour protéger les applications Web et mod_cband, mais là je m'égare un peu, qui permet de limiter la bande passante.
- répondre
Ulhume, le 5 May, 2008 - 07:06@Dab Je viens de regarder ce que permettait de faire mod_secutity (http://www.onlamp.com/pub/a/apache/2003/11/26/mod_security.html) et c'est vraiment très intéressant. merci pour le tuyau.
- répondre
Chimrod , le 5 May, 2008 - 09:28On peut également rajouter fail2ban, qui, avec une règle adaptée permet de bannir les ips en fonction des codes d'erreurs d'apache ( 401, 403 etc ), et éviter que l'ip revienne avant un petit moment. ( Couplé avec mod-security c'est très efficace ! )
- répondre
Ulhume, le 5 May, 2008 - 10:01Pas mal du tout ça, je vais le coupler dés ce soir avec mon module d'anti-spam qui renvoie une erreur 666.
- répondre
Corbier , le 5 May, 2008 - 16:29Coquille dans le titre
Protégrer ?!?
- répondre
Ulhume, le 5 May, 2008 - 17:14@Corbier J'aurais bien voulu faire croire à un jeu de mot mais tu as parfaitement raison
Poster un nouveau commentaire