— MAR : 130 MAD

HORS-SÉRIE CAN : 18,00 $ cad LES GUIDES DE € —

DOM TOM : 13,90 ���� € —

— BEL/PORT.CONT : 13,90

CH : 18,00 CHF € — France METRO : 12.90 E

LEAPACH GUIDE COMPLET POUR METTRE EN PLACE ET BIEN CONFIGURER VOTRE SERVEUR WEB

Tutoriels Des pas-à-pas Aller plus loin pour passer rapidement

C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 Des éléments de à la pratique Programmer con guration avancée pour des besoins plus pour le Web  ques Installation et PHP, Python, Perl spéci ff rement, ...) guration (LDAP, chi con et Ruby : Introduction quelques bases Édité par Les Éditions Diamond Installer son premier ’il faut savoir pour bien L 15066 - 66 H - F: 12,90 € - RD ’Apache serveur et choisir Tout ce qu programmer avec le mécanisme cation le sur les origines d les langages du et sur ses principales d’authenti fonctionnalités Web plus adapté www.ed-diamond.com Retrouvez toutes nos publications Editi ns

lEs diamond sur www.ed-diamond.com

GNU/Linux Magazine Hors-Série est édité par Les éditions Diamond

B.P. 20142 / 67603 Sélestat Cedex Tél. : 03 67 10 00 20 / Fax : 03 67 10 00 21 E-mail : [email protected] [email protected] Service commercial : [email protected] Sites : www.gnulinuxmag.com www.ed-diamond.com Directeur de publication : Arnaud Metzler Rédacteur en chef : Denis Bodor Secrétaire de rédaction : Véronique Sittler Remerciements à Sébastien Maccagnoni-Munch Conception graphique : Kathrin Scali Responsable publicité : Tél. : 03 67 10 00 27 Service abonnement : Tél. : 03 67 10 00 20 Impression : pva, Druck und Medien-Dienstleistungen GmbH, Landau, Allemagne Distribution France : (uniquement pour les dépositaires de presse) MLP Réassort : Plate-forme de Saint-Barthélemy-d’Anjou. Tél. : 02 41 27 53 12 Plate-forme de Saint-Quentin-Fallavier. Tél. : 04 74 82 63 04 Service des ventes : Distri-médias : Tél. : 05 34 52 34 01 IMPrIMé en Allemagne - PrINTED in Germany Dépôt légal : A parution N° ISSN : 0183-0864 Commission Paritaire : K78 976 Périodicité : Bimestrielle Prix de vente : 12,90 Euros

La rédaction n’est pas responsable des textes, illustrations et photos qui lui sont communiqués par leurs auteurs. La reproduction totale ou partielle des articles publiés dans GNU/Linux Magazine France Hors-série est interdite sans accord écrit de la société Les éditions Diamond. Sauf accord particulier, les manuscrits, photos et dessins adressés à GNU/Linux Magazine France Hors-série, publiés ou non, ne sont ni rendus, ni renvoyés. Les indications de prix et d’adresses figurant dans les pages rédactionnelles sont données à titre d’information, sans aucun but publicitaire. Toutes les marques citées dans ce numéro sont déposées par leur propriétaire C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 respectif. Tous les logos représentés dans le magazine sont la propriété de leur ayant droit respectif.

Les articles non signés contenus dans ce numéro ont été rédigés par les membres de l'équipe rédactionnelle des Éditions Diamond.

2 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe préface nternet est un enchevêtrement de différents outils matériels et logiciels, qui n’ont pour point commun que de savoir communiquer avec les mêmes protocoles. Le Web, qui utilise Internet, présente la même hétérogénéité : il existe de nombreux navigateurs web, comme il existe de nombreux serveurs Iweb ; il existe de nombreux langages de programmation, comme il existe de nombreux systèmes de bases de données. Et tout ce monde cohabite joyeusement, toujours grâce à des protocoles ouverts et standardisés. Parmi les serveurs web, il y en a un qui sort du lot : le serveur HTTP Apache. Celui-ci, basé sur l’ancêtre des serveurs web (NCSA HTTPd), a rapidement gagné en notoriété, car il est le fruit de la collaboration de nombreux développeurs, experts dans leurs domaines : la fondation Apache a ainsi permis de créer l’un des meilleurs serveurs web, performant et polyvalent. Aujourd’hui, Apache dessert 60% des sites web. Vous avez sûrement déjà lu (ou entendu) le terme « LAMP », qui désigne une architecture de serveur web qui fait office de « standard de fait ». Apache, c’est le « A » de LAMP : Linux, Apache, MySQL et PHP. Il a gagné cette notoriété grâce à une forte modularité, qui lui permet de proposer de nombreuses fonctionnalités avancées – pas nécessairement compatibles entre elles, mais activables ou désactivables à la demande – parmi lesquelles on retrouve différentes méthodes d’authentification, la possibilité de desservir plusieurs sites web sur un seul serveur, le chiffrement de données avec le protocole SSL... On peut également utiliser de nombreux langages de programmation, parmi lesquels on retrouve les « poids lourds » que sont PHP, Perl, Python et Ruby. Nous ne pouvons bien sûr pas aborder ici tous les aspects de ce serveur : on se concentrera sur les fonctionnalités les plus couramment utilisées, les incontournables, afin de vous permettre d’apprendre à monter un site web « comme un pro ». Nous devrons cependant occulter certains aspects, on abordera ainsi que certaines méthodes d’authentification, certaines manières d’implémenter le support des langages de programmation, une seule bibliothèque de chiffrement SSL (car Apache supporte aussi bien OpenSSL que GnuTLS), etc. On essaiera tout de même d’approfondir certains points, qui pourront paraître exotiques ou inutiles à certains, mais qui donnent indéniablement matière à réflexion et qui vous donneront sans aucun doute l’envie d’approfondir le sujet et de plonger dans la documentation officielle de ce projet. Finalement, vous retrouverez des tutoriels qui vous permettront de rapidement mettre en œuvre certaines configurations spécifiques, à commencer, justement, par la mise en place d’un serveur LAMP. Nous démarrerons bien évidemment par les notions de base avec un éventail d’articles grâce auxquels, nous l’espérons, vous ferez des découvertes utiles, à mettre en application pour vos propres besoins. C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 La rédaction

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 3 sommaire GNU/Linux magazine Hors-série N°66 apacHe iNtrodUctioN

page 08 Le Web, un peu d'histoire 1 page 10 Le protocole HTTP page 16 La fondation Apache page 20 Présentation d'Apache

iNstaLLatioN

page 26 Mon premier Apache C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 page 36 Configuration basique 2 page 46 Authentification proGrammer poUr Le web page 62 Sites dynamiques et CGI 3 page 66 PHP, le langage du Web dynamique page 70 Perl, un classique toujours d'usage page 74 Les possibilités offertes par Python page 78 Ruby, un langage révélé par son framework

aLLer pLUs LoiN

page 84 Authentification avec LDAP page 102 Chiffrement et 4 authentification SSL

tUtorieLs

page 126 Installer LAMP sur Ubuntu page 130 Déménagement et redirection

C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 5 page 132 phpMyAdmin sur Ubuntu page 134 Protection contre les DoS avec « mod_evasive » page 136 Le framework Django sur Ubuntu page 140 Statistiques avec AWStats 1 C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5

6 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe iNtrodUctioN 1 à découvrir dans cette partie... page 08 Le Web, un peu d'histoire Arrivé quelques années après le réseau Internet, le web est né au CERN dans les années 80. Petite rétrospective pour comprendre comment tout cela s'est mis en place.

page 10 Le protocole HTTP Ce protocole de communication est la base du Web. Inventé en même temps que ce dernier, c'est lui qui permet aux ordinateurs de demander des pages web aux serveurs.

page 16 La fondation Apache Apache est peut-être un serveur web, mais c'est également une fondation importante, réunissant des centaines de développeurs : un incontournable du Web.

page 20 Présentation d'Apache Le serveur HTTP Apache est le plus connu et l'un des premiers à avoir existé. Devenu un

C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 poids lourd du secteur, il a commencé « tout petit » comme beaucoup de logiciels.

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 7 Installation : mon premier Apache 1 iNtrodUctioN

Le web : UN peU d’Histoire C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5

lors qu’Internet, en tant qu’interconnexion de réseaux, existe depuis la fin des années 60, le Web (www, World Wide Web) lui-même est bienA plus jeune ! Retour sur son histoire...

8 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe Introduction : le web - un peu d'histoire

1 Internet et le Web

Tâchons de dissocier Internet et World Wide Web. Internet désigne l’interconnexion mondiale de réseaux, permettant à des milliards d’équipements disséminés dans le monde de communiquer. Le Web, de son côté, désigne le système hypertexte constitué de l’ensemble des pages desservies par les serveurs HTTP de par le monde. Ce n’est qu’une des applications d’Internet, aux côtés de la messagerie électronique (e-mail) ou des messageries instantanées, par exemple.

2 La création du Web

Alors qu’Internet est créé entre les années 60 et 70 (d’abord appelé ARPANET) par les militaires américains, le Web a été inventé en Europe par Tim Berners-Lee en 1989, année où il a soumis au CERN un premier jet de ses spécifications ; après évolution de sa proposition par lui-même et Robert Cailliau, une première démonstration a eu lieu en 1990 et le premier système www a été mis à la disposition de la communauté des physiciens des hautes énergies en 1991, via la bibliothèque de logiciels du CERN. Ce n’est qu’un peu plus tard que ce système fut connecté à Internet, ce qui a permis sa diffusion dans le monde. (crédits : Paul Clarke, via Wikimedia Commons) Tim Berners-Lee, Le premier serveur web américain a été mis en place en décembre 1991 au Centre de l’inventeur du web l’accélérateur linéaire de Stanford (SLAC), en Californie.

3 Les premiers navigateurs web

à cette époque, seuls deux navigateurs web existaient : la version ayant servi au développement d’origine, disponible uniquement sur des machines NeXT et une version en mode ligne, très simple à installer et à exécuter, mais limitée en puissance et peu conviviale. Tim Berners-Lee lança alors un appel via Internet pour que d’autres développeurs puissent apporter leurs connaissances, l’équipe de développement du CERN n’était pas suffisamment importante pour prendre à sa charge ces développements. C’est alors que le National Center for Supercomputing Applications (NCSA) de l’université de l’Illinois développa le premier navigateur web convivial, baptisé MOSAIC, qu’il publia en 1993 pour l’environnement X-Window. L’essentiel de l’équipe ayant développé MOSAIC a quitté le NCSA pour C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 créer Netscape Navigator, publié en 1994. Netscape Navigator a donné naissance à Mozilla Firefox en 2004... Vous connaissez la suite ! Microsoft, de son côté, a développé Internet Explorer à partir de 1995, ce qui a mené à la première guerre des navigateurs à partir de 1996, gagnée par Microsoft en 1998 : Internet Explorer détenait alors 96% Le premier navigateur web convivial, de parts de marché. ▪ NCSA MOSAIC

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 9 Installation : mon premier Apache 1 iNtrodUctioN

Le protocoLe Http

C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 our communiquer, un serveur et un client ont besoin d’utiliser un protocole commun. Pour le Web, ce protocole s’appelle HyperText Transfer Protocol ; il Pa été inventé par Tim Berners-Lee, comme pierre angulaire du World Wide Web.

10 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe Introduction : le protocole HTTP

à savoir 1 Versions de HTTP IETF et RFC L’Internet Engineering Lors de l’invention du Web, Tim Berners-Lee a envisagé l’utilisation du Task Force est un groupe informel (pas de statut, protocole FTP pour transférer les documents hypertextes le composant. pas de membres, pas Cependant, FTP est limité au simple transfert de fichiers et ne supporte pas d’adhésion, ouvert à tout la notion de formats de données. C’est pourquoi il a imaginé un nouveau individu...) qui participe à protocole, qu’il a appelé HTTP... l’élaboration des standards pour Internet. Les travaux de l’IETF sont répartis en 1.1 HTTP/0.9 une centaine de groupes de travail. La première version publique de ce protocole est HTTP/0.9. Elle a été pré- L’IETF publie notamment sentée au début des années 90, en même temps que le Web lui-même. Ce les RFC (Requests For numéro de version a en réalité été donné lorsque la version HTTP/1.0 est Comments), qui tiennent sortie : à l’origine, aucun numéro de version n’avait été donné à ce protocole. lieu de normes sur Internet. Ce protocole est extrêmement simple : Notons que, traditionnel- 1. Connexion du client au serveur, lement et ce depuis 1978, 2. Envoi par le client d’une requête GET, l’IETF publie un ou plu- sieurs canular(s) chaque 3. Envoi de la réponse par le serveur, 1er avril : Internet par 4. Fermeture de la connexion par le serveur. pigeon voyageur, messages subliminaux par Telnet, La requête a la forme suivante : etc. Ne les confondons pas Fichier avec des normes réalistes ! GET /chemin/d/une/page.html

La réponse correspond directement et intégralement au fichier demandé, dans le cas d’une page HTML cela donnerait : Fichier Exemple

Ceci est une page d’exemple.

1.2 HTTP/1.0 C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 En mai 1996, le protocole HTTP/1.0 devient standard de l’IETF et est décrit dans la RFC 1945. Cette version du protocole intègre notamment le support des serveurs HTTP virtuels (hôtes virtuels, voir plus loin), la gestion de cache et l’identification. Le déroulement des connexions est le même qu’avec HTTP/0.9 : connexion, requête, réponse, déconnexion.

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 11 Introduction : le protocole HTTP 1 1.2.1 Requête

La requête est plus évoluée ; elle prend la forme suivante : Fichier [ligne vide] [ligne vide]

La première ligne ressemble à la requête en HTTP/0.9, avec l’ajout du nom du protocole à la fin ; la méthode peut être GET comme avec HTTP/0.9, elle peut également être HEAD ou POST. Vous retrouverez plus loin l’explication détaillée de ces méthodes. Les lignes d’en-tête permettent de donner au serveur des détails sur la requête. Vous retrouverez plus loin des détails sur ces en-têtes. Le corps de la requête correspond aux données que le client envoie au serveur ; par exemple, dans le cas d’une requête POST (généralement utilisée lorsqu’on remplit un formulaire), les données sont transmises au serveur dans cette section. Par exemple, une requête pourra avoir la forme suivante : Fichier GET /page.html HTTP/1.0 Host: example.com Referer: http://example.com/ User-Agent: CERN-LineMode/2.15 libwww/2.17b3

1.2.2 Réponse

à l’instar de la requête, la réponse du serveur est plus complexe avec HTTP/0.9. Elle prend la forme suivante : Fichier [ligne vide]

La première ligne inclut le code réponse – les plus connus sont 200 (lorsque la requête s’est bien déroulée) et 404 (lorsque la page n’est pas trouvée) – ainsi qu’une description textuelle de ce code réponse. De la même manière que dans la requête, les lignes d’en-tête permettent de préciser au client des détails sur la réponse du serveur. Vous retrouverez plus loin des détails sur ces en-têtes. Le corps de la réponse est, bien sûr, le contenu du fichier demandé. Par exemple, une réponse pourra avoir la forme suivante : Fichier C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 HTTP/1.0 200 OK Date: Fri, 31 Dec 1999 23:59:59 GMT Server: Apache/0.8.4 Content-Type: text/html Content-Length: 59 Expires: Sat, 01 Jan 2000 00:59:59 GMT Last-Modified: Fri, 09 Aug 1996 14:21:40 GMT

12 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe Introduction : le protocole HTTP

Fichier Exemple

Ceci est une page d’exemple.

1.3 HTTP/1.1

La version HTTP/1.1 est sortie en janvier 1997, décrite dans la RFC 2068 ; elle a été révisée en juin 1999, cette révision est décrite dans la RFC 2616. Elle ajoute le support du trans- fert en pipeline (plusieurs requêtes en une seule connexion) et la négociation de type de contenu et améliore la gestion du cache.

La syntaxe des requêtes et réponses est identique à la syntaxe avec HTTP/1.0, en remplaçant bien sûr la mention HTTP/1.0 par HTTP/1.1 dans la première ligne de la requête et de la réponse.

Le déroulement d’une connexion est légèrement différent, car avec cette version du proto- cole, le serveur ne ferme pas la connexion après avoir envoyé une réponse ; la connexion reste ouverte en attente d’une nouvelle requête, éventuellement accompagnée d’une instruc- tion de fermeture de la connexion, ou en attente de la fermeture de la part du client.

La conversation peut alors correspondre au cheminement suivant : 1. Connexion du client au serveur, 2. Envoi par le client d’une requête GET, 3. Envoi de la réponse par le serveur, 4. Envoi par le client d’une seconde requête GET avec demande de fermeture de connexion, 5. Envoi de la seconde réponse par le serveur, 6. Fermeture de la connexion par le serveur.

2 Méthodes

La première ligne d’une requête HTTP précise avant tout une méthode d’interrogation. Chaque méthode demande au serveur d’effectuer une action différente. Voici une liste (non exhaustive) des méthodes HTTP les plus courantes : → GET : récupération du contenu d’un document ; → HEAD : récupération des en-têtes de la réponse uniquement – cette méthode est utilisée par un client web lorsqu’il souhaite des informations sur un document sans le télécharger en entier ; → POST : envoi de données au serveur – ces données sont ensuite traitées par une

C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 application côté serveur, un script PHP par exemple ; → PUT : stockage d’un fichier à l’URL mentionnée par le client ; → DELETE : suppression du fichier à l’URL mentionnée par le client ; → CONNECT : accès à un serveur web sécurisé (HTTPS) par l’intermédiaire d’un serveur d’authentification.

Dans les faits, les méthodes les plus utilisées sont GET, HEAD et POST.

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 13 Introduction : le protocole HTTP 1

3 En-têtes

Le protocole HTTP, à partir de la version 1.0, permet d’ajouter des en-têtes, aussi bien à à savoir la requête qu’à la réponse. De très nombreux en-têtes existent, nous n’allons pas tous les lister. Voyons quelques-uns des plus courants d’entre eux... Liste complète des en-têtes La liste exhaustive des en-têtes peut être consultée 3.1 Côté client (requête) dans la RFC 2616 ; mais si vous essayez de Le client web peut donner différents détails au serveur pour l’aider à desservir les bonnes lire une RFC, vous vous données ou dans un but statistique. En voici un extrait. rendrez vite compte que → Un des en-têtes les plus importants pour les requêtes HTTP est Host ; il est même ces documents ne sont obligatoire avec HTTP/1.1. Cet en-tête permet d’indiquer au serveur l’hôte virtuel pas des plus évidents à comprendre. Vous pourrez que l’on souhaite interroger (voir plus loin pour une explication détaillée des hôtes consulter cette liste plus virtuels). agréablement sur la page → L’en-tête Referer permet d’indiquer au serveur le site qui nous renvoie vers « List of HTTP header cette adresse (cela offre notamment la possibilité aux webmestres d’effectuer des fields » de Wikipédia en anglais. statistiques de provenance des visiteurs). → User-Agent contient la désignation du navigateur qui effectue la requête auprès du serveur (c’est cette valeur-là que l’on change pour faire passer notre navigateur pour un autre auprès de sites faisant du filtrage sur le navigateur utilisé). → L’en-tête Accept, quant à lui, permet d’indiquer au serveur le type de fichier que l’on à savoir souhaite recevoir en réponse à la requête ; cela permet au serveur de desservir une même donnée dans différents formats, selon le contexte. Le cache du → L’en-tête Accept-Language, quant à lui, permet de préciser la langue dans navigateur laquelle on souhaite recevoir le document ; cela permet de gérer un site multilingue Tout navigateur digne de directement au niveau du serveur. Ces en-têtes entrent dans le cadre du mécanisme de ce nom est équipé d’un multivues, que nous aborderons plus loin. cache. Ce cache permet de conserver en mémoire → L’en-tête Authorization contient les informations d’authentification auprès tout ou partie d’une page, du serveur web ; nous verrons cet en-tête plus en détail dans le chapitre dédié à afin de ne pas avoir à l’authentification. relancer un transfert pour des données qui sont déjà → L’en-tête Connection permet de gérer les connexions persistantes. Avec HTTP/1.1 connues. les connexions sont persistantes par défaut, alors on pourra surtout trouver l’en-tête Ce mécanisme est efficace Connection: close qui demande au serveur de fermer la connexion à la fin de uniquement si le serveur la requête. retourne les bonnes informations, notamment l’en-tête Expires : à partir de là, le navigateur sait 3.2 Côté serveur (réponse) qu’il peut conserver tel ou C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 tel fichier jusqu’à telle ou Le serveur peut fournir de nombreuses informations au client lorsqu’il répond aux telle date. requêtes. Parmi celles-ci, les plus courantes sont les suivantes : → Date contient la date à laquelle la réponse est générée. → Server permet d’identifier le logiciel faisant fonctionner le serveur qui a répondu. → Content-Type précise au client le format de la donnée retournée, l’aidant à l’interpréter.

14 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe Introduction : le protocole HTTP

→ Content-Length indique la taille → 301 Moved Permanently : le serveur totale du fichier retourné, cela permet au indique ici que la ressource demandée a navigateur de valider qu’il a bien reçu la été déplacée à une adresse différente, il réponse complète. indique le nouvel emplacement dans l’en-tête Location ; → Expires contient la date précise à laquelle le fichier expire ; cette information est très → 307 Moves Temporarily : par cette utile pour les navigateurs : elle leur permet erreur, le serveur signale que la ressource de savoir combien de temps conserver une peut être temporairement trouvée à une donnée en cache. autre adresse, mais que pour des requêtes futures il faudra toujours passer par l’adresse → Last-Modified contient la date à laquelle courante ; le fichier a été modifié pour la dernière fois ; il est également retourné lors d’une requête → 401 Unauthorized : ce code est HEAD, cela permet éventuellement au client retourné quand une requête est dirigée web de vérifier qu’un document en sa vers une ressource protégée, il faut possession est toujours à jour. alors refaire la requête, mais avec des Notons que tous ces en-têtes sont facultatifs : informations d’authentification dans l’en-tête il ne faut pas s’appuyer de manière Authorization ; inconditionnelle sur ceux-ci, que ce soit côté → 404 Not Found : on a tous rencontré cette serveur ou côté client... erreur un jour ou l’autre, elle indique que le fichier demandé n’existe pas ;

→ 405 Method Not Allowed : le serveur Codes signale là que la méthode utilisée pour la 4 requête (GET, POST, etc.) est incorrecte par réponse rapport à ce que la ressource supporte ;

Un serveur web peut retourner un grand → 500 Internal Server Error : par ce nombre de codes réponse différents. Ces codes code, le serveur indique qu’il a rencontré sont classés dans 5 grandes catégories : un problème interne lorsqu’il a essayé de → du code 100 au code 199 : simple message récupérer les données de réponse ; informatif ; → 503 Service Unavailable : ce code → du code 200 au code 299 : ces codes indique que le serveur ne peut pas répondre indiquent que la requête s’est déroulée avec pour le moment, il indique optionnellement succès ; le délai à attendre avant la remise en service dans l’en-tête Retry-After. → du code 300 au code 399 : ces codes d’erreur correspondent à des redirections : le client HTTP a une ou des actions complémentaires à effectuer ; → du code 400 au code 499 : ceux-là indiquent 5 HTTPS qu’il y a un problème dans la requête (incomplète ou incorrecte) ; Une connexion chiffrée (sécurisée) avec le → du code 500 au code 599 : ces derniers protocole SSL ou TLS n’est pas très différente C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 codes correspondent aux erreurs propres aux d’une connexion classique non chiffrée : une serveurs. fois le chiffrement négocié et en place, les requêtes sont les mêmes que sur un serveur Listons certains de ces codes, parmi les plus HTTP classique. Bien sûr, la négociation du courants : chiffrement a un coût non négligeable en termes → 200 OK : la requête s’est correctement de processeur, les connexions persistantes sont déroulée et la réponse est retournée ; encore plus justifiées dans ce cas. ▪

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 15 Le protocole HTTP 1 iNtrodUctioN

La foNdatioN apacHe

Ce document est la propriété exclusive de jean-paul garrigos ([email protected]) - 26 avril 2013 à 01:35 eur serveur HTTP est le premier et le plus connu de leurs projets, mais la fondation Apache va bien plus loin que cela : OpenOffice.org, Subversion, Tomcat... Cette Lfondation gère d’autres projets d’envergure. Faisons le tour du propriétaire...

16 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe Introduction : la fondation Apache

La fondation et à savoir 1 ses projets ApacheCon La fondation Apache (de son nom exact Apache Software Foundation) La conférence de la fondation est une organisation à but non lucratif, dont l’objectif est développer Apache (ApacheCon) permet des logiciels open source. L’ensemble des logiciels développés par cette de réunir les développeurs fondation sont protégés par la licence Apache. des différents projets Cela aurait peu de sens de donner ici la liste complète des projets de la Apache et de présenter les technologies et les logiciels fondation Apache : cette liste est consultable sur le site de la fondation. développés par la fondation. La fondation supporte plus de 100 projets, programmés dans près de 30 Elle se déroule à chaque langages différents par plusieurs centaines de développeurs bénévoles ; fois dans un lieu différent : elle compte plus d’une centaine de membres. Ces bénévoles, développeurs Canada en 2011, Allemagne et membres, sont répartis dans le monde : il n’y a pas de groupe local plus en 2012, États-Unis en 2013... important qu’un autre.

La fondation Apache n’a aucun employé : autant le bureau que les développeurs sont bénévoles. Les dépenses de la fondation portent sur les conférences officielles (appelées « ApacheCon »), l’infrastructure informatique et les relations publiques.

1.1 Historique

L’histoire d’Apache a commencé en 1995, lorsque huit développeurs se sont réunis pour améliorer le serveur HTTP du NCSA (National Center for Supercomputing Applications), le NCSA HTTPd. à cette époque, ce serveur HTTP était utilisé par 95% des sites sur Internet ; la majorité de ces sites sont passés sur le serveur Apache. à savoir Ce groupe de développeurs s’est rapidement fait connaître sous le nom Le nom Apache « The Apache Group ». Le nom « Apache » a été La fondation Apache a été formée le 25 mars 1999, tout d’abord pour choisi pour faire honneur à la nation des Apaches, chapeauter le serveur HTTP ; elle a rapidement pris sous son aile d’autres reconnus pour leur projets. supériorité stratégique et pour leur forte endurance. C’est aussi un jeu de mots 1.2 Organisation des projets sur « a patchy web server », car le serveur HTTP Le bureau de la fondation Apache est chargé de gérer la communication Apache était d’abord une autour des projets et de les superviser dans leur ensemble, mais il série de patches pour le C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 serveur NCSA HTTPd ; en n’a aucune autorité en matière de choix techniques. La fondation est effet, en anglais « Apache » composée de plusieurs « projets de premier niveau » (nommés Project se prononce comme « a Management Committees), qui ont chacun un certain nombre de patchy ». Ce jeu de mots n’est « sous-projets ». cependant pas la raison première du nom. Les décisions techniques se font de manière indépendante au niveau de ces projets.

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 17 Introduction : la fondation Apache 1

1.3 Quelques projets...

Parmi les plus populaires des projets de la fondation Apache, on peut retrouver :

→ le serveur HTTP Apache, projet créé en 1995 ayant contribué à fonder la fondation en 1999 ;

à savoir → le serveur LDAP Apache Directory, projet créé en 2002 sous le nom Compatibilité « LDAPd » et donné à la fondation en 2003 ; GNU GPL → la suite bureautique OpenOffice.org, créée en 2000 par Sun Microsystems et donnée à la fondation en 2011 par Oracle ; La compatibilité avec la licence GNU GPL signifie → le filtre anti-spam SpamAssassin, créé en 2001 et donné à la fondation qu’il est juridiquement en 2004 ; facile de faire interagir du code provenant de la → le logiciel de gestion de versions Subversion, créé par CollabNet en 2000 fondation Apache avec et donné à la fondation en 2010 ; du code provenant de → le serveur HTTP en Java Tomcat, projet interne à Sun Microsystems la FSF (Free Software Foundation) : des bouts donné à la fondation en 1999. de code protégés par ces On peut constater que, malgré une orientation globale plutôt tournée vers le deux licences peuvent être Web, la fondation Apache ne se limite pas à cela et chapeaute de nombreux réutilisés dans un seul et projets logiciels différents. même logiciel.

2 La licence Apache

La licence Apache (en version 2, existant depuis 2004) est une licence libre compatible avec la licence GNU GPL v3.

Cette licence permet, comme toute autre licence open source, la réutilisation, la redistribution et la modification du code.

Les points de différence, qui ont notamment fait que cette licence en version 1.0 et 1.1 n’était pas compatible avec la GNU GPL, portaient sur quelques points de détail comme la façon de présenter la licence au sein du code, l’inclusion d’éventuelles autorisations de ré-exploiter un brevet logiciel (aux États-Unis), etc.

C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 2.1 Permissivité

Notons aussi que la licence Apache est permissive : il n’est pas obligatoire de publier sous licence Apache un logiciel qui contient des bouts de code sous licence Apache, contrairement à la GNU GPL, qui force à publier tout code utilisant du code GNU GPL sous la même licence (on caractérise parfois de « virales » de telles licences).

18 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe Introduction : la fondation Apache

Lorsque l’on développe du code sous GNU GPL, on est assuré que tout développeur réutilisant le code publie son logiciel sous GNU GPL également ; lorsque l’on développe du code sous licence Apache, on permet aux autres développeurs de publier leur logiciel sous la licence de leur choix, seul le bout de code réutilisé reste sous licence Apache.

2.2 Licence et propriété du code à savoir Membres Contrairement à d’autres structures de promotion et d’hébergement de logiciels libres, tout projet hébergé par la fondation Apache doit fondateurs obligatoirement être publié sous licence Apache et faire l’objet d’un contrat de Les personnes à l'origine de la fondation Apache licence de contributeur, donnant à la fondation Apache la possibilité d’utiliser n'ont pas d'autre lien et surtout de protéger le logiciel en question, notamment d’un point de vue que celui d'avoir voulu légal : cela contribue à la protection du code source concerné. créer le meilleur serveur Tout contributeur reste propriétaire du code qu’il a écrit : il ne s’agit que d’une HTTP possible : c'est grâce à Internet qu'ils autorisation explicite donnée à la fondation Apache par contrat et non d’un se sont rencontrés et don (et changement de propriétaire) pur et simple du code source. par Internet qu'ils ont travaillé ensemble. Il s'agit par exemple de Brian Behlendorf, l'un des fondateurs de la société Le projet Apache Organic, Inc. (créatrice du site web du magazine 3 HTTP Server Wired), de Roy Fielding, l'un des principaux Bien qu’il ait contribué à la création de la fondation, le serveur HTTP est un auteurs de la spécification HTTP, ou encore du projet comme les autres, avec son équipe de développeurs et son organisation cryptologue anglais propre. Aujourd’hui, plus une seule ligne de code ne provient du serveur Ben Laurie. NCSA HTTPd : tout le code a été réécrit.

Depuis avril 1996, le serveur HTTP Apache est le serveur web le plus populaire. En décembre 2012, il est utilisé pour desservir plus de 60% des sites web.

En raison de cette grande popularité, on appelle souvent ce serveur simplement « Apache ». Mais ne nous y trompons pas : dire « j’utilise Apache » n’a en réalité pas de sens, il faudrait dire « j’utilise le serveur HTTP Apache » ou « mon serveur HTTP est Apache HTTP Server » pour qu’on sache de quoi il est question... ▪ C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 Références Site de la fondation Apache : http://www.apache.org/

Site de la conférence Apache : http://www.apachecon.com/

Site du serveur HTTP Apache : http://httpd.apache.org/

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 19 La fondation Apache 1 iNtrodUctioN

préseNtatioN d’apacHe

u sein de la fondation Apache, le serveur HTTP continue d’évoluer. Il a bien sûr C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 atteint aujourd’hui un seuil de maturité qui fait que les évolutions se font en douceur,A mais nous allons voir qu’il est le fruit de beaucoup de réflexions et de choix, grâce auxquels nous disposons aujourd’hui d’un outil puissant et modulaire.

20 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe Introduction : présentation d'Apache

1 Histoire

1.1 Naissance

Nous l’avons vu, le serveur HTTP Apache est basé sur le démon httpd, développé par Rob McCool au NCSA (National Center for Supercomputing Applications), ce même NCSA qui a créé le premier navigateur web convivial. Rob McCool a été l’un des premiers employés de Netscape, en suivant ses collègues du NCSA dans la création de la société : le serveur NCSA httpd a donc rapidement été orphelin... Pendant quelques mois à partir de mi-1994, chaque webmestre y allait de son patch à ce serveur, pour lui permettre de supporter telle ou telle option. Un groupe informel s’est créé parmi ces webmestres, c’est ainsi que le groupe Apache (the Apache Group) est né. Ce groupe a réuni un maximum de ces patches, les a fusionnés dans ce qui était à l’époque la version 1.3 du serveur httpd du NCSA, le serveur Apache 0.6.2 a ainsi été publié en avril 1995. Très rapidement, une nouvelle architecture serveur a été inventée, avec une structure modulaire telle qu’on la connaît aujourd’hui, pour donner naissance à Apache 0.8.8 en août de la même année, puis à Apache 1.0 en décembre 1995. Courant 1995, le serveur Apache a dépassé celui du NCSA en popularité pour devenir le premier serveur utilisé sur Internet, il n’a jamais quitté cette place depuis.

1.2 Évolution

La version 1.3 d’Apache (dernière évolution de la version 1) est sortie en 1999, apportant de nombreuses améliorations. Cette version est restée longtemps préférée de certains administrateurs, notamment en raison des changements dans la licence d’Apache 2.0 qui n’ont pas plu à tout le monde... Apache 2.0 alpha est publié en 2000, suivi d’Apache 2.0 « stable » en 2002, puis d’Apache 2.2 en 2005 et Apache 2.4 en 2012, chaque version apportant son lot de nouvelles fonctionnalités... Aujourd’hui, les distributions Linux incluent souvent encore Apache 2.2 (c’est le cas de Debian et Ubuntu) : il va leur falloir quelques mois avant de pouvoir intégrer la dernière version proprement. C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 1.3 Part de marché

La popularité du serveur HTTP Apache a varié depuis 1996, gagnant ou perdant des parts de marché selon les périodes, mais il a toujours conservé une très grande avance sur ses compétiteurs, représentant toujours plus de 50% des sites web desservis. En 2009, il a dépassé les 100 millions de sites web desservis.

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 21 Introduction : présentation d'Apache 1

2 Modularité et fonctionnalités

L’une des grandes forces d’Apache est sa modularité. Nous l’avons vu, ce logiciel a adopté une structure modulaire dès l’une des toutes premières versions, avant même la sortie de la version 1.0 « stable ».

Cette modularité a permis de développer de nombreuses fonctionnalités de manière totalement indépendante. Les fonctionnalités de base sont elles aussi développées sous forme de modules, même si lors de la compilation par les éditeurs de distributions, certaines sont intégrées statiquement dans l’exécutable binaire et ne peuvent être désactivées.

Faisons le tour de quelques fonctionnalités implémentées par ces modules... De nombreux autres modules sont également disponibles !

2.1 Chiffrement

Apache supporte – bien évidemment – le protocole sécurisé HTTPS, qui permet de chiffrer les communications afin d’en empêcher la lecture par un tiers.

Ce support est disponible avec le module mod_ssl.

2.2 Hôtes virtuels

Une seule instance du serveur HTTP Apache est capable de desservir de nombreux sites différents, cela grâce aux hôtes virtuels : selon l’hôte demandé par le client HTTP (en général un navigateur web), le serveur répondra d’une manière adaptée...

Cette fonctionnalité est offerte par le module core : elle fait partie des fonctionnalités de base.

2.3 Journalisation

Apache permet bien sûr d’enregistrer des journaux (logs), afin de tracer d’éventuels problèmes rencontrés. Mais les possibilités en termes de journalisation vont plus loin ; on peut notamment personnaliser les journaux relatifs aux requêtes effectuées par les clients.

Ces fonctionnalités sont offertes par les modules mod_log_config, mod_log_debug, mod_ log_forensic et mod_logio.

2.4 Authentification C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 Apache propose de nombreuses possibilités en termes d’authentification des utilisateurs : authentification simple, utilisation des données d’une base SQL, d’une base LDAP, de fichiers DBM... Ces fonctionnalités sont fournies par différents modules, dont le nom commence systématiquement par « auth » : mod_auth_basic ou mod_authnz_ldap, par exemple.

Par ailleurs, des modules fournis par d’autres organisations ou personnes sont disponibles, comme le module auth_kerb pour l’authentification Kerberos.

22 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe Introduction : présentation d'Apache

2.5 Traitement conditionnel

Apache peut être configuré afin d’effectuer un traitement conditionnel, le module mod_setenvif permettant de mettre en place des variables d’environnement selon les en-têtes fournis par le client, ces variables d’environnement pouvant être utilisées par certaines directives de configuration ou par des scripts appelés lors des requêtes.

2.6 Alias et redirections Définition De nombreuses approches pour les alias et les redirections sont possibles avec Apache : un alias de base permet de desservir une donnée qui n’est normalement pas dans Proxy et reverse l’arborescence d’un site web ; une redirection permet de renvoyer directement un code proxy d’erreur de la famille des 300 sans autre traitement ; une règle de réécriture permet de Un proxy permet rediriger les requêtes finement selon l’URL demandée ou les en-têtes de la requête (pour de centraliser et rediriger un navigateur mobile vers une version spécifique du site, par exemple). éventuellement filtrer les accès à Internet au sein Ces fonctionnalités sont offertes par les modules mod_alias et mod_rewrite. d’un réseau ; cela permet par exemple de mutualiser les ressources et de servir 2.7 Proxy de cache au niveau du réseau, en ne chargeant une Apache peut également être utilisé comme proxy ou comme reverse proxy. De même image qu’une seule fois, même pour plusieurs nombreuses configurations sont possibles à ce niveau, il peut d’ailleurs supporter clients. différents protocoles : AJP, CONNECT, FastCGI, FTP, HTTP et SCGI. Il permet également Un reverse proxy, c’est la de faire de la répartition de charge... même logique côté serveur ; Cette fonctionnalité est éclatée en plusieurs modules, le module mod_proxy en étant c’est un serveur qui reçoit la base et les autres modules dont le nom commence par « proxy_ » fournissant les les requêtes des clients et fonctionnalités plus précises, comme mod_proxy_ftp pour le protocole FTP. qui les redirige vers un ou plusieurs serveurs web, tout en cachant les données qu’il peut, afin de limiter la 2.8 WebDAV charge sur les serveurs web eux-mêmes. Le protocole WebDAV permet d’utiliser des méthodes HTTP supplémentaires, afin de gérer un stockage centralisé de données (généralement des fichiers) avec gestion des versions ; ces méthodes sont par exemple PROPFIND, COPY, MOVE.... Certains outils de gestion électronique de documents (GED) implémentent le protocole WebDAV à leur niveau, mais Apache2 est capable de gérer cet aspect également. Cette fonctionnalité est supportée par le module mod_dav.

2.9 Sécurité

Il est également possible de mettre en œuvre des processus d’audit et de filtrage des requêtes, afin d’empêcher certains types d’attaques par exemple, comme le Cross-Site C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 Scripting ou les injections SQL. Cette fonctionnalité est apportée par l’infrastructure logicielle ModSecurity, qui propose un module Apache mod_security. En réalité, ModSecurity est né sous la forme d’un module Apache, ce n’est que par la suite qu’il a été compartimenté pour être également utilisable avec d’autres serveurs HTTP pour devenir un pare-feu d’applicatif web ( firewall) à part entière. ▪

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 23 2 C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5

24 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe iNstaLLatioN 2 à découvrir dans cette partie... page 26 Mon premier Apache Découvrons l'architecture de base du serveur HTTP Apache, la méthode pour l'installer et sa modularité. Le « petit serveur web » a grandi et a gagné en complexité et en performance.

page 36 Configuration basique Une fois le serveur HTTP Apache installé, que faire ? Configurer les accès aux documents, les sites à desservir, les autorisations et les enregistrements système.

page 46 Authentification Quand on a des documents confidentiels, on n'a pas envie de les partager avec n'importe qui : filtrons alors les accès à un site selon des noms d'utilisateurs et mots de passe. C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 25 Installation : mon premier Apache 2 iNstaLLatioN

moN premier apacHe e nombreuses solutions existent pour desservir des sites web ; le serveur HTTP

C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 de la fondation Apache reste cependant le leader sur ce marché, avec plus de la moitié desD sites l’utilisant dans le monde. Nous appellerons cet incontournable « Apache » par la suite, mais rappelons-nous que ce n’est pas le seul projet de cette fondation ! Nous aborderons plus précisément la version 2 de ce logiciel, qui est également appelée « Apache2 ».

26 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe Installation : mon premier Apache

1 Installation

L’installation d’Apache à proprement parler est très simple à partir du moment où l’on utilise une distribution Linux digne de ce nom. En effet, il est à retenir tellement populaire qu’il est fourni sous forme de paquet pour l’ensemble des distributions. Son installation se résume donc à une commande (en tant que Commandes super-utilisateur du système) : exécutées → sous Debian GNU/Linux : Nous donnerons Terminal ici comme ~# apt-get install apache2 exemple de nombreuses commandes : ne → sous Ubuntu Linux : les exécutez pas Terminal aveuglément ! ~# apt-get install apache2 Certaines sont incompatibles entre elles, → sous Red Hat Enterprise Linux et Fedora : certaines sont Terminal redondantes, certaines ne ~# yum install httpd servent qu’à vous montrer Détaillons l’installation sous Debian Squeeze (version 6) : des aspects Terminal d’Apache. ~# apt-get install apache2 Lecture des listes de paquets... Fait Construction de l’arbre des dépendances Lecture des informations d’état... Fait Les paquets supplémentaires suivants seront installés : apache2-mpm-worker apache2-utils apache2.2-bin apache2.2-common libapr1 libaprutil1 libaprutil1-dbd-sqlite3 libaprutil1-ldap ssl-cert Paquets suggérés : apache2-doc apache2-suexec apache2-suexec-custom openssl-blacklist Les NOUVEAUX paquets suivants seront installés : apache2 apache2-mpm-worker apache2-utils apache2.2-bin apache2.2-common libapr1 libaprutil1 libaprutil1-dbd-sqlite3 libaprutil1-ldap ssl-cert

C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 0 mis à jour, 10 nouvellement installés, 0 à enlever et 0 non mis à jour. Il est nécessaire de prendre 2 073 ko dans les archives. Après cette opération, 6 963 ko d’espace disque supplémentaires seront utilisés. Souhaitez-vous continuer [O/n] ?

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 27 Installation : mon premier Apache 2 Parmi les dépendances du paquet, on remarque particulièrement apache2-mpm-worker. C’est en réalité ce paquet qui contient le binaire qui est exécuté lorsque l’on démarre Apache : le fichier /usr/sbin/apache2 est un lien vers ce « MPM » : Terminal ~# ls -l /usr/sbin/apache2 lrwxrwxrwx 1 root root 33 4 mars 11:42 /usr/sbin/apache2 -> ../lib/apache2/mpm-worker/apache2

En réalité, Apache2 offre une modularité non seulement au niveau des compléments qu’on peut y ajouter (support de langages, extensions diverses), mais également au niveau de la manière dont les connexions sur le serveur sont gérées. On parle alors de Multi-Processing Modules (ou MPM), chargés de définir la politique de gestion de ces connexions. Par défaut, le modèle installé par Debian est « worker », mais plusieurs sont proposés : Terminal ~# apt-cache search apache2-mpm apache2-mpm-event - Apache HTTP Server - event driven model apache2-mpm-itk - multiuser MPM for Apache 2.2 apache2-mpm-prefork - Apache HTTP Server - traditional non-threaded model apache2-mpm-worker - Apache HTTP Server - high speed threaded model

2 Les MPM

Faisons un tour de ces modules...

2.1 MPM Prefork

Ce module fonctionne de la même manière qu’Apache 1.3 ; le multithreading n’est absolument pas pris en charge et les connexions sont traitées par des forks. Ce module offre donc une stabilité et une isolation exemplaires, permettant d’utiliser un service HTTP basé qui ne serait pas « thread safe » ; les requêtes et les processus sont totalement isolés, de cette manière un problème sur l’un des processus forkés ne pourra pas impacter l’ensemble du serveur web.

C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 L’aspect négatif de ce module est bien sûr les performances. Faire un fork est plus gourmand en processeur que de créer un thread. On échange donc une perte de performances contre un gain de stabilité et d’isolation. Précisons cependant que la perte de performance ne se ressent pas sur des serveurs à faible trafic : c’est sur des serveurs très chargés que cet aspect pourra être important.

28 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe Installation : mon premier Apache

Dans la pratique, ce module est de moins en moins utilisé, car les bibliothèques utilisées sur un serveur Apache sont « thread safe »... sauf le module pour PHP mod_php5, qui reste l’un Définition des plus utilisés. Thread ou fork ? Le multithreading est une approche 2.1.1 Configuration de Prefork qui a pour particularité de lancer des fils d’exécution (threads) parallèles, Ce module ne nécessite généralement pas de configuration partageant un même espace mémoire. particulière, car il se régule automatiquement en reposant C’est une approche très efficace sur la gestion des processus par le système d’exploitation pour exécuter plusieurs instructions sous-jacent. en parallèle au détriment de la compartimentation des données : c’est Cinq paramètres de configuration permettent cependant de aux différents fils de gérer les accès à contrôler finement cette gestion... la mémoire, pour être « thread-safe ». MaxClients, la plus importante (et la plus utile) de ces Les forks sont des créations de options, détermine le nombre total de requêtes pouvant être nouveaux processus indépendants ; chacun de ces processus a son espace exécutées simultanément vers le serveur : cette variable peut mémoire qui n’entre pas en conflit être ajustée à la baisse (pour limiter les risques de plantage avec les autres – il reste bien sûr ou de ralentissement liés à une sur-utilisation du processeur la possibilité de créer des espaces ou de la mémoire) ou à la hausse (pour accepter un plus mémoire partagés. Les forks sont grand nombre de visiteurs simultanés). La valeur par défaut cependant plus gourmands en est de 256. mémoire que les threads. Avec ce module, le nombre maximum de clients est égal au nombre maximum de processus (forks) d’« écoute » qu’Apache va exécuter. Cette valeur est limitée par le paramètre ServerLimit, lui aussi à 256 par défaut pour Prefork. StartServers indique le nombre de processus à créer au démarrage d’Apache : il s’agit du nombre de processus à retenir « en attente de clients », prêts à desservir les pages ou applications web. Il n’est généralement pas nécessaire Le paramètre ServerLimit de modifier ce paramètre, étant donné que le nombre de Il s’agit d’un paramètre commun processus est dynamique (dans la limite de MaxClients). représentant le nombre maximal Ce paramètre (dont la valeur par défaut est de 5) peut être de processus pouvant être exécutés augmenté si on met en place un serveur qui doit « encaisser », simultanément. Il convient de ne dès sa mise en production, de très nombreuses requêtes pas configurer ce paramètre trop (par exemple dans le cas d’un cluster de haute disponibilité, haut afin d’éviter les surcharges où plusieurs centaines de connexions peuvent passer d’un de la mémoire. Par mesure de sécurité, cette valeur ne pourra serveur à l’autre en quelques secondes). jamais dépasser 20 000 (ou 200 000 MinSpareServers et MaxSpareServers déterminent spécifiquement pour Prefork). respectivement le minimum et le maximum de processus Notons qu’un changement de cette actifs « en attente de requête ». Apache se charge de conserver valeur n’est pris en compte que dynamiquement un certain nombre de processus « en écoute » lorsqu’Apache est arrêté puis relancé en plus des processus en cours de traitement de requêtes : (stop puis start), mais pas lors d’un simple redémarrage d’Apache C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 il crée de nouveaux processus si le nombre courant est (restart). en-dessous de la valeur minimale, ou en « tue » si ce nombre est au-dessus de la valeur maximale. Modifier ces valeurs (qui sont respectivement à 5 et 10 par défaut) n’a de sens que sur des serveurs à charge fortement variable où on s’attend à accueillir de nombreuses connexions supplémentaires en très peu de temps (cas de l’« effet Slashdot »).

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 29 Installation : mon premier Apache 2 MaxRequestsPerChild, enfin, permet de définir le nombre maximal de requêtes qu’un seul processeur pourra desservir. Cela permet de ne pas créer un nouveau processus à chaque nouvelle requête mais de réutiliser les processus existants. Sa valeur par défaut est de 10 000. Il faut être très prudent avec ce paramètre : si l’application desservie a une fuite de mémoire, cette fuite s’additionne dans la limite de cette valeur. Par exemple, si un script PHP a une fuite de mémoire de 1 Ko par requête et que chaque processus peut traiter 10 000 requêtes, chaque processus peut avoir 10 Mo de fuite de mémoire ; avec la limite par défaut de 256 processus simultanés, on peut monter jusqu’à 2,5 Go uniquement en fuite de mémoire. De plus, avec une valeur de 0 (c’est la valeur configurée par de nombreuses distributions par défaut), un processus n’expire jamais. Les paramètres par défaut de chaque MPM sur Debian sont donnés dans le fichier /etc/apache2/apache2.conf. Dans le cas du Définition module Prefork, les valeurs par défaut de Debian sont les suivantes : Effet Slashdot Fichier L’« effet Slashdot » tire son nom du site StartServers 5 communautaire Slashdot. MinSpareServers 5 org, l’un des sites MaxSpareServers 10 d’actualité informatique MaxClients 150 les plus fréquentés, MaxRequestsPerChild 0 notamment par la communauté des « nerds » et « geeks ». Lorsqu’un site web fait l’objet d’une news sur ce site, il peut arriver que l’engouement 2.2 MPM Worker des visiteurs de Slashdot soit tellement fort que le Ce module est installé par défaut avec Apache2 ; c’est celui qui nombre de visites dépasse devrait être privilégié lorsque c’est possible. Là où le module Prefork ce que l’administrateur du site a prévu et le rende utilise les forks pour créer de nouveaux processus, le module inaccessible. On dit que le worker se base sur les threads ; c’était l’une des grandes nouveautés site a été « slashdotté ». d’Apache 2.0, sorti en 2002. On appelle également Le principal avantage des threads est de partager le même espace cet effet « SDOS » pour mémoire : il n’est plus nécessaire de créer un nouveau processus, Social Denial of Service. en dupliquant constamment des données ; on reste toujours dans le Cela arrive également même espace mémoire, avec le même contexte, etc. Les plateformes régulièrement lors d’événements importants, multiprocesseurs et multicœurs étant maintenant la norme, il est par exemple la sortie évident que le fonctionnement en plusieurs threads est la voie à d’un nouveau produit très privilégier. attendu. Ce module a en réalité une approche hybride, combinant

C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 multiprocessus et multithreads. Cette approche permet de combiner les avantages des deux techniques : performances brutes supérieures et sécurité par rapport au plantage d’un processus. Ce module lance plusieurs processus, qui eux-mêmes sont divisés en plusieurs threads. Apache est alors capable de desservir simultanément autant de requêtes que le nombre total de threads lancés par l’ensemble des processus.

30 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe Installation : mon premier Apache

2.2.1 Configuration de Worker

La configuration de ce module passe par six paramètres... StartServers a la même signification qu’avec Prefork : il indique le nombre de processus à lancer dès le démarrage. Sa valeur par défaut est de 3, limitée par à retenir ServerLimit comme pour Prefork. Valeurs par défaut ThreadsPerChild , de son côté, définit le nombre Nous voyons ici deux de threads créés au sein de l’un de ces processus – types de valeurs par ce nombre est invariable ; dès qu’un processus est défaut : d’un côté les créé, il contient ce nombre de threads. à l’instar de valeurs par défaut ServerLimit pour StartServers, cette valeur est d’Apache même, qui sont limitée par ThreadsLimit, qui a une valeur de 64 codées « en dur » lors de la compilation (ce sont par défaut. les valeurs données au MaxClients a la même signification que pour Prefork, sein des paragraphes) c’est le nombre total de requêtes traitées simultanément : et les valeurs par défaut ici, ce sera le nombre de threads exécutés ; à diviser par le pour Debian, qui sont faciles à modifier (elles nombre de threads par processus (ThreadsPerChild) sont configurées dans le pour obtenir le nombre maximal de processus exécutés. fichier /etc/apache2/ MaxRequestsPerChild représente ici le nombre de apache2.conf). requêtes qui seront traitées par un processus ; à diviser par le nombre de threads par processus pour obtenir le nombre de requêtes traitées par thread en moyenne. Comme pour le MPM Prefork, le système est capable de se réguler tout seul et ne nécessite pas de reconfiguration particulière, sauf dans des cas très spécifiques. à retenir Les paramètres par défaut du MPM Worker sur Debian, À l’instar de ServerLimit, dans le fichier /etc/apache2/apache2.conf, sont ThreadLimit a une valeur les suivants : qui ne pourra jamais Fichier dépasser 20 000 (valeur codée « en dur »). StartServers 2 MinSpareThreads 25 MaxSpareThreads 75 ThreadLimit 64 ThreadsPerChild 25 MaxClients 150 MaxRequestsPerChild 0

Si on exécute la commande pstree sur une machine avec ce MPM et la configuration par défaut d’Ubuntu, on constate qu’il y a en effet deux processus de lancés, C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 contenant chacun 26 threads - un thread de gestion et 25 threads d’écoute : Terminal ~# pstree | grep apache2 |-apache2-+-apache2 | `-2*[apache2---26*[{apache2}]]

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 31 Installation : mon premier Apache 2 2.3 MPM Event

Worker et Prefork sont les MPM les plus utilisés et les plus stables, mais il faut également compter avec d’autres modules... Le MPM Event, fourni comme paquet Debian, est conçu spécialement pour les sites devant traiter un nombre important de connexions persistantes. Notons toutefois que, comme la documentation officielle et la description du paquet Debian l’indiquent, ce MPM reste expérimental pour Apache 2.2 : il faut faire très attention si on l’utilise... ou passer à Apache 2.4, version dans laquelle ce MPM est stabilisé. Lorsqu’un client distant envoie une requête, il lui est possible de garder la connexion ouverte afin d’envoyer d’autres requêtes. Le principal avantage de ce fonctionnement est d’éviter de réitérer les opérations d’ouverture et fermeture de socket à chaque à savoir requête. Le problème avec Worker et Prefork, c’est qu’un thread ou un processus est alors monopolisé par un client, dans l’attente MPM sur d’autres systèmes de données de sa part. D’autres MPM existent, notamment Le MPM Event propose alors de dédier un thread à l’attente sur d’autres systèmes d’exploitation. de connexions et à la gestion de la persistance, déportant ainsi On retrouve par exemple le MPM uniquement les tâches de traitement des requêtes aux autres netware optimisé pour la gestion threads, sans aucun verrou spécifique aux clients. des threads sur un système Novell NetWare, le MPM os2 pour le Les paramètres de configuration de ce MPM sont les mêmes que système d’exploitation IBM OS/2 ceux de Worker. On notera toutefois que, étant donné l’aspect ou le MPM winnt pour les serveurs expérimental de ce MPM et des risques de dysfonctionnement Microsoft Windows... induits, les connexions chiffrées SSL/TLS ainsi que bon nombre de mécanismes de filtrage sont proscrits.

2.4 MPM ITK

Le MPM ITK est un module développé de manière indépendante (c’est-à-dire hors du giron de la fondation Apache) qui permet une séparation de privilèges au niveau des VirtualHosts. Il devient possible de faire fonctionner chacun des hôtes virtuels sous une identité (UID et GID) différente. Dès lors, les scripts, les données et les fichiers de configuration d’un hôte virtuel n’ont plus besoin d’être lisibles par les autres. Cela devrait plaire à n’importe quel administrateur soucieux de bien séparer les sites, ou encore à celui devant gérer plusieurs utilisateurs n’ayant rien en commun. Ce MPM est basé sur Prefork, il hérite donc de ses avantages et de ses inconvénients, notamment la non-utilisation des threads, source de problèmes de performance sur des serveurs C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 très chargés. Cela est d’autant plus vrai que la séparation des privilèges implique un processus minimum pour chaque hôte virtuel. Ce MPM accepte les mêmes paramètres que Prefork, auxquels on ajoute les suivants, à configurer dans chaque hôte virtuel (VirtualHost)...

32 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe Installation : mon premier Apache

AssignUserID permet de spécifier l’UID et le GID des processus desservant cet hôte virtuel. En l’absence de ce paramètre, le couple UID/GID par défaut de la configuration d’Apache sera utilisé. MaxClientsVHost est l’équivalent de MaxClients, au niveau de l’hôte virtuel. Cela permet de limiter les ressources consommées par un hôte, ou au contraire d’en privilégier un par rapport aux autres. NiceValue, dans le même ordre d’idées, permet de spécifier une valeur de nice (« niceness ») pour les processus de l’hôte en question. Ce MPM étant distribué indépendamment et moins utilisé, notons qu’il est moins testé que Worker et Prefork ; il n’est cependant pas expérimental et fonctionne correctement.

Configuration Définition 3 et modules Niceness La valeur de nice, ou niceness Lors de l’installation du paquet apache2, un certain nombre en anglais, est une notion liée à d’éléments de configuration ont été mis en place (répertoires et l’exécution des processus sur un fichiers). Ainsi, on retrouve dans le répertoire /etc/apache2 système UNIX. Cette valeur définit une configuration par défaut fonctionnelle et prête à accueillir nos la priorité de chaque processus modifications, selon nos besoins. lorsque le noyau doit décider à quel processus donner la main. D’ailleurs, un site web de base est déjà desservi : en allant à l’adresse Par défaut, cette valeur est de 10. http://127.0.0.1 (ou à l’adresse IP du serveur, si Apache est installé Lorsque la valeur est plus grande (le sur une machine tierce) dans un navigateur web, on voit s’afficher le processus est plus « sympathique », célèbre « It works! ». nice en anglais), le processus a une plus faible priorité ; au contraire, plus la valeur est petite plus le processus est prioritaire. Cette valeur va de -20 à 19.

Ça marche, le serveur HTTP lui-même nous le dit !

Sur les distributions Debian, Ubuntu et leurs dérivées, la C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 configuration d’Apache2 est répartie dans plusieurs fichiers. On retrouve alors dans le fichier de configuration apache2.conf tous les éléments qui concernent le serveur dans son ensemble – ce fichier est très rarement modifié. Par le biais d’instructions Include, ce fichier en appelle d’autres, de manière à répartir cette configuration.

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 33 Installation : mon premier Apache 2 On appelle de cette manière les fichiers et ensembles de fichiers suivants : → mods-enabled/*.load et mods-enabled/*.conf pour l’activation des modules. Les fichiers .load regroupent les directives de chargement des modules (LoadModule), alors que les fichiers .conf comprennent les éléments de configuration propres aux modules en question ;

→ httpd.conf pour les paramètres spécifiques à l’administrateur/au système. Généralement, ce fichier est vide et inutilisé ;

→ ports.conf pour les ports TCP en écoute ; c’est ici qu’on retrouvera les directives Listen (indiquant d’écouter sur le port HTTP 80 et le port 443 si le module SSL est activé), ainsi que les directives NameVirtualHost, permettant de configurer les hôtes virtuels (voir plus loin) ; à savoir → sites-enabled/* pour la configuration spécifique L'arborescence que l'on découvre ici est spécifique aux distributions des sites. Un fichier 000-default est en place avec Debian, Ubuntu et leurs dérivées. l’installation par défaut. C’est ce fichier qui détermine Cette organisation des fichiers ne comment afficher la page « It works! » que nous avons vue sera pas retrouvée sur d'autres plus haut ; distributions, par exemple Fedora ou Red Hat. Ces dernières proposent → conf.d/* pour les éléments de configuration une organisation bien plus simplifiée complémentaires ; en général des configurations globales au (fichiers /etc/httpd/httpd.conf et serveur que l’on peut modifier. /etc/httpd/conf.d/*.conf) ; c'est une autre approche, ni meilleure, ni Notons que la configuration spécifique aux sites web est dans moins bien : à chacun de configurer des fichiers spécifiques et non dans apache2.conf ou son serveur web comme il l'entend. httpd.conf. C’est une bonne pratique à conserver : diviser la On peut d'ailleurs tout à fait configuration dans plusieurs fichiers, un fichier par site. mettre en place sous Fedora une configuration telle que celle de Ceux qui auront lu les paragraphes précédents en consultant Debian, et inversement. le contenu du répertoire /etc/apache2 sur leur ordinateur n’auront pas manqué de remarquer la présence des répertoires mods-available et sites-available. En réalité, les répertoires mods-enabled et sites- enabled ne contiennent que des liens symboliques vers leurs équivalents en *-available. C’est encore là un bon exemple à suivre : créer des configurations dans un répertoire « available » et activer ces configurations à la demande avec des liens. En réalité, ces liens symboliques sont gérés par des commandes spécifiques :

C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 → a2ensite pour activer un site (apache2 enable site) ;

→ a2dissite pour désactiver un site (apache2 disable site) ;

→ a2enmod pour activer un module (apache2 enable module) ;

→ a2dismod pour désactiver un module (apache2 disable module).

34 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe Installation : mon premier Apache

Ces commandes peuvent être utilisées de deux manières : soit directement avec le nom d’un site (d’un fichier de sites-available, en vérité) ou d’un module en argument, soit sans aucun argument ; dans ce dernier cas, la commande proposera la liste des sites ou des modules qui peuvent être activés : Terminal ~# a2ensite Your choices are: default default-ssl Which site(s) do you want to enable (wildcards ok)? ~# a2enmod ssl Enabling module ssl. See /usr/share/doc/apache2.2-common/README.Debian.gz on how to configure SSL and create self-signed certificates. Run ‘/etc/init.d/apache2 restart’ to activate new configuration!

Notons que le contenu des fichiers est chargé par ordre alphabétique : si un fichier doit forcément être chargé avant un autre, charge à l’administrateur de les nommer de manière adéquate. En réalité, toutes les fonctionnalités d’Apache2 sont implémentées sous forme de modules. Certains d’entre eux sont simplement compilés directement dans Apache de manière statique. Pour en connaître la liste, il suffit d’exécuter apache2 avec l’option -l : Terminal ~# apache2 -l Compiled in modules: core.c mod_log_config.c mod_logio.c worker.c http_core.c mod_so.c

Conclusion

Arrêtons là cette présentation du serveur HTTP Apache. Nous avons vu comment cet outil s'articule, les différents modes de fonctionnement qu'il propose, ainsi que son architecture modulaire. En réalité, avec la simple commande apt-get install apache2 nous avons déjà un serveur prêt à faire son office ; mais sa configuration reste minimale et on peut l'affiner de différentes manières. Nous allons voir par la suite les principaux points de configuration :

C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 les hôtes virtuels et l'authentification. ▪

Références Documentation Apache sur les MPM : http://httpd.apache.org/docs/2.4/mpm.html Site web du MPM ITK : http://mpm-itk.sesse.net/

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 35 Installation : mon premier Apache 2 iNstaLLatioN

coNfiGUratioN basiqUe C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5

ne fois un serveur Apache en place, il est nécessaire de le configurer afin de répondre à nos besoins. Cette configuration se fait à travers un certain nombre de fichiers, à Umodifier avec votre éditeur de texte préféré.

36 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe Installation : configuration basique

Définition URL 1 Les hôtes virtuels Le sigle URL (pour Universal Resource Très souvent, un serveur matériel est largement surdimensionné par Locator) désigne la rapport aux besoins d’un seul site web ; cela d’autant plus que les chaîne que l’on appelle couramment « adresse serveurs récents sont de plus en plus puissants. De plus, placer toutes web », utilisée pour vos applications et toutes vos données dans des sous-répertoires de pointer de manière unique /var/www n’est pas très élégant. Heureusement, un concept simple vers une ressource sur permet d’obtenir une solution parfaitement adaptée : les hôtes virtuels. Internet : document HTML, image, son, vidéo, Dans les grandes lignes, lorsque l’on saisit l’adresse (URL) d’un site e-mail, forum Usenet, etc. dans un navigateur, une requête DNS transforme cette adresse textuelle (appelée FQDN, pour Fully Qualified Domain Name) en adresse IP numérique. Cette adresse IP est celle de votre machine où réside le serveur Apache (votre serveur web). Cette association FQDN/adresse IP n’est pas nécessairement exclusive : un nombre illimité de FQDN peuvent être associés à une seule et même adresse IP. à partir de là, lorsque votre navigateur web interroge un serveur, il précise le FQDN qu’il recherche et le serveur HTTP - Apache en l’occurrence - est capable de desservir des données différentes selon le serveur demandé. L’hôte physique est le même, mais il s’agit virtuellement, pour les navigateurs (clients) qui s’y connectent, de serveurs différents : dans la terminologie d’Apache, on parle alors d’« hôtes virtuels ». Dans le cas de figure le plus courant, on souhaite donc héberger deux sites web ou plus, ayant des adresses (URL) différentes, mais avec une seule interface réseau et une seule adresse IP.

1.1 Configuration

La configuration d’Apache utilise des balises sous la forme <...> / , à l’instar des langages HTML et XML. Un hôte virtuel est défini avec un bloc tel que le suivant : Fichier DocumentRoot /var/www [...]

C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5

Nous définissons donc ici un hôte virtuel. L’argument en ouverture du bloc, « *:80 », correspond à l’interface physique et au port sur lequel écouter. L’adresse IP de l’interface physique peut être remplacée par *, comme ici, pour indiquer que cet hôte virtuel doit être desservi sur toutes les interfaces réseau. C’est le cas pour la plupart des serveurs.

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 37 Installation : configuration basique 2 On peut également rencontrer, à la place de l’adresse IP, directement un FQDN ; dans ce cas, il sera résolu lors du démarrage d’Apache et l’adresse IP résultante sera utilisée. Notons également qu’une adresse IPv6 doit être placée entre crochets [ et ]. Enfin, le mot-clé _default_ permettra de créer un point de chute pour les connexions sur des adresses IP non configurées, le cas échéant. On pourrait donc également rencontrer la forme suivante : Fichier DocumentRoot /var/www [...] à retenir Nom, alias et DNS Il n’y a aucun lien direct 1.1.1 ServerName et ServerAlias entre les noms et alias que l’on définit dans la Nous avons ainsi vu comment délimiter la configuration de deux hôtes configuration d’Apache virtuels différents, avec des balises . Mais nous et les DNS qui pointent n’avons pas encore indiqué dans la configuration à quelle adresse web vers le serveur. Si un (URL) correspond chaque hôte virtuel... serveur HTTP Apache est configuré pour desservir Cette distinction se fait avec les directives ServerName et une certaine adresse, ServerAlias, à inclure dans le bloc VirtualHost : que ce soit par le biais → ServerName permet d’identifier précisément l’hôte virtuel, c’est son d’un ServerName ou d’un ServerAlias, une nom principal ; entrée correspondante → ServerAlias permet de donner un ou plusieurs noms doit obligatoirement complémentaires, par lesquels les visiteurs pourront également être créée dans le accéder au site concerné. serveur DNS gérant la zone en question : les On peut également utiliser des astérisques (wildcards) pour indiquer que serveurs DNS ne sont pas le site doit être desservi pour n’importe quel sous-domaine. renseignés « par magie » lorsque l’on configure Un hôte virtuel peut donc être défini de la manière suivante : Apache. Fichier ServerName monserveur.fr ServerAlias *.monserveur.fr DocumentRoot /var/www [...]

1.1.2 NameVirtualHost

Dans les deux cas, Apache devra avoir été « prévenu » de la définition de tels hôtes virtuels, par l’intermédiaire de la directive NameVirtualHost.

C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 Dans la configuration par défaut proposée par Debian et Ubuntu, cette directive est placée dans le fichier /etc/apache2/ports.conf, associée à la définition du port en écoute : Fichier NameVirtualHost *:80 Listen 80

38 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe Installation : configuration basique

Il n’est généralement pas nécessaire de modifier cette configuration (sauf cas particuliers), vu qu’elle correspond à l’usage que l’on en fait la plupart du temps.

1.1.3 Plusieurs fichiers

Conformément aux bonnes pratiques indiquées par la configuration par défaut de Debian et Ubuntu, il est préférable de placer un hôte virtuel ou un groupe d’hôtes liés dans un seul fichier de configuration. Ces fichiers de configuration seront à placer dans le répertoire /etc/apache2/ sites-available, puis activés avec la commande a2ensite.

1.2 Ordre de priorité

L’ordre des directives est important. En effet, si Apache ne sait pas définir précisément quel hôte virtuel distribuer, il fait au mieux et prend le premier à savoir qui correspond. Le répertoire /srv Cela est notamment important lorsque l’on accède au serveur directement par Historiquement, les son adresse IP ou si on lui demande une URL qu’il ne connaît pas : dans ce cas, fichiers correspondant il retourne le premier hôte virtuel qui correspond à l’adresse IP définie. aux sites web sont placés C’est pour cela que l’hôte virtuel de la configuration par défaut d’Apache2 dans le répertoire /var/ www. Cependant, cet usage sur Debian et Ubuntu est dans un fichier 000-default : ces trois zéros ne correspond pas à lui permettent d’être évalué en premier lieu et de servir d’hôte par défaut. l’objectif initial du point Autrement dit, ne placez pas une application critique et privée dans le de montage /var, à savoir tout premier hôte virtuel : n’importe qui pourrait y accéder sans même l’hébergement de données connaître son URL ! variables comme des logs, des tampons, des files d’attentes... C’est pourquoi le point de 1.3 Exemple montage /srv a été intégré à la FHS (Filesystem Imaginons deux sites, que nous appellerons Bachi et Bouzouk et que nous Hierarchy Standard) : rendrons accessibles par les adresses « www.bachi.org », « bachi.org », celui-ci a pour objectif « www.bouzouk.net », « w.bouzouk.net » et « bouzouk.net ». d’héberger les données Nous allons placer les données de ces deux sites dans les répertoires relatives aux serveurs en suivants : fonctionnement sur la machine : sites web, bases → /srv/www/bachi de données... → /srv/www/bouzouk De plus, les outils systèmes automatiques ne doivent Pour cette démonstration, nous placerons dans ces répertoires des pages normalement pas toucher HTML très simples, qui nous permettront de vérifier le bon fonctionnement à /srv, ce qui permet de notre configuration. de s’assurer que toute Une telle situation serait matérialisée par les deux fichiers suivants : donnée dans /srv y a été placée manuellement et → /etc/apache2/sites-available/bachi : est gérée manuellement Fichier

C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 par l’administrateur du système. ServerName www.bachi.org ServerAlias bachi.org DocumentRoot /srv/www/bachi [...]

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 39 Installation : configuration basique 2 → /etc/apache2/sites-available/bouzouk : Fichier ServerName www.bouzouk.net ServerAlias w.bouzouk.net bouzouk.net DocumentRoot /srv/www/bouzouk [...]

Nous savons comment définir des hôtes virtuels... Voyons maintenant comment les configurer !

2 Configuration d’un site

La majorité de la configuration d’Apache se fait dans ces fichiers « sites-available » ; les paramètres sont pour la plupart spécifiques à chaque site, c’est pourquoi ils doivent être placés dans les blocs VirtualHost (à l’instar de ServerName et ServerAlias).

Avant tout, le paramètre DocumentRoot, que nous venons de rencontrer, permet de signaler à Apache où il doit chercher les fichiers à desservir. Ce paramètre peut être défini dans le contexte global ou dans les hôtes virtuels. Contexte, vous dites ?

2.1 Contextes

Chaque paramètre peut être défini dans un ou plusieurs contexte(s). Le contexte définit la portée du paramètre en question. Les contextes possibles sont les suivants :

→ La configuration du serveur, que l’on peut également appeler « contexte global », contient tous les paramètres qui ne sont pas définis dans un bloc ; le paramètre NameVirtualHost, que nous avons vu plus haut, ne peut être défini que dans ce contexte ;

→ Chaque hôte virtuel est un contexte, un paramètre configuré dans un hôte virtuel étant actif uniquement pour celui-ci ;

→ Au sein des hôtes virtuels ou dans le contexte global, on peut définir des droits selon les répertoires grâce à un bloc [...] : dans ce cas, le contexte est limité à ce répertoire et ses sous-répertoires ;

→ Les fichiers .htaccess permettent également de définir des contextes : les paramètres dans ces fichiers ne sont actifs que dans le répertoire où ils sont placés et ses sous-répertoires. C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 2.1.1 .htaccess

Vous avez sûrement déjà entendu parler de fichiers .htaccess : ces fichiers permettent de modifier certains aspects de la configuration d’Apache sans avoir accès aux fichiers de configuration ; c’est très utile sur des serveurs où les webmestres n’ont pas accès au serveur en tant que root : ils peuvent alors définir certains points de configuration de manière indépendante.

40 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe Installation : configuration basique

L’utilisation ou non de ces fichiers est conditionnée par la directive AllowOverride. Ce paramètre spécifie quels types de directives présentes dans un .htaccess peuvent prévaloir sur la configuration système. None bloque toute modification de la configuration et désactive ce mécanisme dans son ensemble, All autorise tous les cas d’utilisation de ces fichiers. Les autres arguments acceptés par cette directive sont : à retenir → AuthConfig permet de modifier la configuration des méthodes d’authentification. C’est l’un des cas les plus courants d’utilisation du Fichiers .htaccess fichier .htaccess, avec une demande de et performances login/pass simple pour l’accès au contenu d’un répertoire ; Bien que très utiles → Limit permet l’utilisation des directives concernant l’accès au serveur dans certains cas, les (Allow, Deny et Order – voir plus loin pour la signification de ces fichiers .htaccess ont directives) ; un impact négatif sur les performances. En → FileInfo permet d’autoriser la manipulation des directives sur les effet, à chaque requête, fichiers (types MIME, pages d’erreur, filtres, règles de réécriture...) ; Apache doit alors relire et réinterpréter ce → Indexes concerne la manipulation des paramètres concernant fichier pour modifier l’indexation des répertoires et sa présentation ; temporairement sa → Options autorise la modification de la configuration des options sur configuration. De plus, les répertoires. Apache recherche ce fichier dans le répertoire Cette directive n’est acceptée que dans le contexte de répertoires. cible de la requête, mais également dans ses répertoires parents, de 2.2 DirectoryIndex manière récursive et cela, à chaque requête La directive DirectoryIndex permet de préciser les fichiers d’index également. à utiliser lorsqu’une requête est dirigée vers un répertoire et non vers un Lorsque vous avez fichier. Cette directive est acceptée dans les quatre contextes. accès aux fichiers de configuration d’Apache, En argument de cette directive est donné un certain nombre de noms de il est préférable d’y fichiers ; ils sont essayés dans l’ordre. Notons que l’on n’est pas obligé insérer directement les de pointer vers des fichiers du répertoire en question : on peut donner directives nécessaires, le chemin relatif vers un fichier dans un sous-répertoire, ou encore un sans passer par un fichier .htaccess, et désactiver chemin absolu vers un autre fichier, un script CGI par exemple. totalement leur utilisation Par défaut sur Debian, sa valeur est la suivante : (AllowOverride None). Fichier DirectoryIndex index.html index.cgi index.pl index. index.xhtml index.htm

Cette fonction peut être complètement désactivée avec l’argument disabled.

2.3 Options C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 La directive Options permet de spécifier des options à appliquer quant au traitement des requêtes à destination du contexte courant (elle est acceptée dans les quatre contextes). Avec l’argument None, aucune option n’est activée ; avec l’argument All, toutes les options sont activées, sauf MultiViews. Les options peuvent être précédées de « + » (pour forcer leur activation) ou « - » (pour forcer leur désactivation).

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 41 Installation : configuration basique 2 Voyons les options les plus courantes : → ExecCGI autorise l’exécution de scripts CGI (voir plus loin) ;

→ FollowSymlinks précise au serveur de suivre les liens symboliques placés dans ce répertoire. Notez que le fait de désactiver cette option ne doit pas être considéré comme un mécanisme de sécurité. Si vous souhaitez interdire l’utilisation des liens symboliques dans un répertoire de votre arborescence web, supprimez-les tout simplement ;

→ Indexes permet d’afficher le contenu du répertoire si un fichier d’index n’y est pas présent – cet affichage est géré par le module autoindex d’Apache2 – désactiver cette option est équivalent à l’utilisation de la directive DirectoryIndex disabled ;

→ MultiViews active le mécanisme de multivues (si le module negotiation est chargé – c’est le cas dans l’installation par défaut de Debian).

Contenu d’un répertoire, généré par le module autoindex

2.4 Négociation de contenu et multivues

La notion de négociation de contenu est présente dans le standard HTTP/1.1. Il s’agit, pour le serveur, de pouvoir choisir la façon la plus adaptée de présenter un contenu en fonction des préférences du navigateur qui aura émis la requête. Un exemple typique est la langue préférée de l’utilisateur distant. Le navigateur précise la langue souhaitée dans l’en-tête HTTP et le serveur essaie de faire le choix le plus approprié en fonction des données dont il dispose. Ce sont les concepts de ressources et de représentations qui sont mis en œuvre. Le navigateur demande une ressource et Apache dispose d’une ou plusieurs représentations (variantes) qu’il va donc négocier. Un autre exemple concerne le format. Avec des ressources graphiques, les différentes variantes d’une représentation peuvent être différents formats de plus ou moins bonne qualité. L’algorithme de négociation d’Apache utilisé pour faire le choix de la représentation à desservir est détaillé dans la documentation officielle du serveur. Vous pouvez affiner son

C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 fonctionnement via des fichiers de correspondance de types pour chaque ressource. Notez que cette option, bien que présente dans les fichiers de configuration, n’est que rarement d’un grand intérêt ; les fonctionnalités qu’elle adresse sont souvent gérées par l’application web desservie. De plus, il est nécessaire de bien comprendre qu’à l’instar des fichiers .htaccess ce mécanisme induit une charge sur le système hébergeant les sites. Dans la majorité des cas, désactiver le module (ou au moins l’option MultiViews) est une bonne idée.

42 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe Installation : configuration basique

2.5 Autorisations d’accès

Les directives Order, Allow et Deny permettent de définir les autorisations d’accès, selon les éléments fournis par les requêtes (adresses IP, nom d’hôte, user-agent...) :

→ Allow définit les clients autorisés ;

→ Deny définit les clients interdits ;

→ Order définit l’ordre dans lequel évaluer ces deux directives.

Les possibilités fournies par Allow et Deny sont complexes. Nous nous penchons ici uniquement sur la fonctionnalité la plus basique : l’autorisation ou l’interdiction selon l’adresse IP du client. La syntaxe de ces directives est : Fichier Allow from Deny from

Dans le cas du filtrage par adresse IP du client, la définition est simplement cette adresse IP... La définition peut être remplacée par all pour signaler qu’on autorise ou qu’on interdit tous les clients. La directive Order peut prendre deux formes : Order allow,deny pour vérifier les autorisations avant les interdictions ou Order deny,allow pour vérifier les interdictions avant les autorisations. Il est important de noter que toutes les directives Allow et Deny sont vérifiées : par conséquent, si un hôte a des critères lui permettant d’être autorisé et interdit, c’est la dernière règle qui sera utilisée : interdiction pour Order allow,deny ou autorisation pour Order deny,allow.

2.5.1 Exemples

Commençons par la configuration la plus courante : Fichier Order allow,deny Allow from all

Cette configuration permet d’autoriser l’accès à tous les clients, sans exception. Si l’on veut autoriser l’accès à tous les hôtes d’un réseau sauf l’un d’entre eux, la configuration ressemblera à :

C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 Fichier Order allow,deny Allow from 192.168.0 Deny from 192.168.0.42

Ici, tout le réseau 192.168.0.x est autorisé sauf l’adresse 192.168.0.42.

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 43 Installation : configuration basique 2 Si on prend les mêmes lignes, mais qu’on inverse l’ordre : Fichier Order deny,allow Allow from 192.168.0 Deny from 192.168.0.42

L’accès est alors autorisé pour 192.168.0.42, car la ligne Allow est Définition interprétée en dernier. Syslog Syslog est une infrastruc- ture systématiquement 2.6 Alias installée sur les serveurs Une autre directive souvent rencontrée est Alias, ainsi que sa petite Linux, qui peut gérer les logs (journaux) du système sœur ScriptAlias. Ces deux directives sont gérées par le module alias. de manière centralisée. Pour ordonner les fichiers à desservir proprement, on aimerait parfois Cette infrastructure permet les stocker ailleurs que dans DocumentRoot ; on a même parfois besoin par exemple de rediriger d’avoir une arborescence totalement différente entre le serveur web et les logs vers un serveur tiers, afin de centraliser les systèmes de fichiers. C’est là que la directive Alias entre en jeu : les journaux d’un ensemble elle permet de faire pointer un chemin (une adresse web) vers un autre de serveurs dans une seule répertoire du système. base. Par exemple, si les images sont stockées dans /srv/commun/images L’utilisation de Syslog mais doivent être accessibles dans /images sur le site web, la directive n’est pas systématique : suivante peut être utilisée : la configuration par Fichier défaut d’Apache sur Debian n’utilise pas Syslog, cela ne Alias /images /srv/commun/images pose aucun problème. Il est conseillé d’utiliser cette méthode plutôt que des liens symboliques. La directive ScriptAlias est à utiliser à la place d’Alias lorsque le répertoire en question contient des scripts CGI (voir plus bas).

à savoir 2.7 Journaux Variables d’environnement Enfin, les dernières directives très courantes sont ErrorLog, LogLevel et CustomLog. Ces trois directives permettent de configurer Les variables l’enregistrement de journaux. d’environnement peuvent être utilisées ErrorLog prend comme seul argument l’endroit où stocker les journaux dans la configuration d’erreur : d’Apache, sous la forme ${}. → soit le chemin d’un fichier pour directement stocker dans un fichier ; La configuration par → soit le mot syslog pour envoyer les logs à syslog, suivi de défaut sur Debian définit : est remplacé par le nom d’un des notamment la variable dispositifs de syslog (par défaut, local7) ; APACHE_LOG_DIR, qui peut être utilisée dans les C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 → soit le chemin d’une commande à exécuter, précédée d’un « pipe » |. directives ErrorLog et CustomLog. LogLevel permet de définir le niveau minimal des messages qui seront enregistrés dans les journaux pointés par ErrorLog. Les différents niveaux disponibles sont, par niveau décroissant de sévérité : emerg, alert, crit, error, warn, notice, info, debug, trace1, trace2, trace3, trace4, trace5, trace6, trace7, trace8. Sur un serveur de production, il est conseillé d’utiliser un niveau entre info et crit.

44 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe Installation : configuration basique

CustomLog est une directive proposée par le module log_config (compilé « en dur » sur Debian), qui permet de définir où stocker les journaux de l’ensemble des requêtes effectuées. Cette directive a la syntaxe suivante : Fichier CustomLog «»

La cible peut être : → le chemin d’un fichier ; → le chemin d’une commande précédée d’un « pipe » |. Le format est une chaîne de caractères où les différentes données que l’on peut intégrer sont préfixées par le signe %. Par exemple, %h sera remplacé par le nom de l’hôte qui fait la requête, %m par la méthode de la requête (GET, POST, etc.), %u par le nom d’utilisateur s’il y a authentification, %r par la première ligne de la requête... La liste complète peut être trouvée dans la documentation officielle du serveur HTTP Apache. Le format peut également être remplacé par un nom de format, qui aura été défini par la directive LogFormat. La configuration par défaut de Debian définit les noms de formats vhost_combined, combined, common, referer et agent ; le format le plus utilisé sera combined.

2.8 Exemple

En compilant toutes ces connaissances, on peut constituer une configuration comme l’exemple suivant, tout à fait correct pour un serveur de production : Fichier ServerName www.monsite.fr ServerAdmin [email protected]

DocumentRoot /srv/www /monsite Options Indexes FollowSymLinks -MultiViews AllowOverride None Order allow,deny Allow from all

ScriptAlias /cgi-bin/ /srv/cgi/cgi-bin/ AllowOverride None Options +ExecCGI -MultiViews Order allow,deny Allow from all

ErrorLog ${APACHE_LOG_DIR}/monsite.fr/error.log LogLevel warn

C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 CustomLog ${APACHE_LOG_DIR}/monsite.fr/access.log combined

Références Documentation d’Apache : http://httpd.apache.org/docs/2.4/fr/ ▪

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 45 Installation : mon premier Apache 2 iNstaLLatioN

aUtHeNtificatioN

uel que soit le type de site web que l’on désire mettre en place, un moment arrive où le besoin se fait sentir de restreindre C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 Q l’accès à certaines ressources : stockage de données privées, interfaces d’administration... Apache met à disposition, en standard, un certain nombre de mécanismes d’authentification et de traitement ; d’autres mécanismes peuvent être installés par ajout de modules.

46 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe Installation : authentification

1 Précisions

Commençons par un peu de jargon. Dans les dernières versions du serveur HTTP Apache (à partir d’Apache 2.2), une normalisation des noms des modules d’authentification a eu lieu : on distingue les modules auth_*, authn_*, authz_* et authnz_*. Cette convention de nommage permet de distinguer authentification et autorisation. L’authentification (ou identification) est le procédé permettant de s’assurer qu’une entité est bien celle qu’elle prétend être. Au quotidien, cette identification peut être effectuée en montrant sa carte d’identité. L’autorisation, en revanche, est l’acte de vérifier et valider qu’une entité (préalablement authentifiée) est bien en droit d’accomplir une action précise. On peut donc distinguer les familles de modules suivantes : → authn : ce sont les modules ne traitant que de l’authentification ; → authz : ce sont les modules ne traitant que de l’autorisation ; → authnz : ce sont les modules couvrant les deux fonctionnalités ; → auth : ce sont les modules « frontaux », chargés de la méthode de communication des données, mais n’effectuant pas eux-mêmes les actions d’authentifier ou d’autoriser. Il convient en effet de faire la différence entre le type d’authentification HTTP (modules auth_*) et le back-end d’authentification utilisé (modules authn*). Le type d’authentification HTTP définit la manière dont les données sont transmises entre le client et le serveur (basic ou digest, par exemple) alors que le back-end d’authentification implémente la manière dont les données d’authentification sont stockées et interrogées.

2 Les types d’authentification

Deux types d’authentification sont disponibles lorsqu’on parle de transmission de données par le protocole HTTP (nous excluons ici ce qui concerne le protocole chiffré HTTPS, qui sera traité plus loin). Des deux types disponibles, basic et digest, le premier est le plus simple et le plus courant. Le second, bien que standard, peut poser problème avec certaines applications basiques, ainsi qu’avec les anciennes versions d’Internet Explorer (IE5 et IE6).

2.1 Basic C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5

La méthode d’authentification basic est décrite dans les RFC 1945 (HTTP/1.0) et 2617 (HTTP Authentication : Basic and Digest Access Authentication). C’est la plus simple à mettre en œuvre, car elle possède la caractéristique (déplaisante) de faire circuler le mot de passe en clair sur le réseau. Il est donc très facile de sniffer ce type de données en transit à chaque requête et de voler le mot de passe de l’utilisateur. Par contre, c’est la méthode qui fonctionnera à coup sûr avec tous les clients HTTP.

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 47 Installation : authentification 2 L’échange entre le client et le serveur HTTP est alors le suivant :

1. Le client demande une URL au serveur sans préciser d’authentification ;

2. Le serveur répond avec le code d’erreur 401 Unauthorized accompagné d’un en-tête WWW-Authenticate: Basic realm="" où la description (le realm) aura été configurée par l’administrateur d’Apache ou par le webmaster ;

3. Le navigateur demande éventuellement le nom d’utilisateur et le mot de passe à son utilisateur et retente la requête, en ajoutant l’en-tête Authorization: Basic où la est constituée du nom d’utilisateur et de son mot de passe, séparés par un double-point, le tout encodé en base64 ;

4. Le serveur vérifie les données d’authentification envoyées par le Définition client, puis : 4a. si l’authentification est correcte, il retourne la ressource Base64 demandée, Base64 est une norme 4b. si l’authentification échoue, il renvoie une erreur 401, de codage utilisant puis retour à l’étape 2. 64 caractères, chaque caractère représentant La configuration et le choix de ce type d’authentification côté 6 bits de l’information serveur Apache se font avec la directive AuthType Basic. d’origine. Les caractères Voici un exemple de configuration : utilisés sont les lettres Fichier majuscules, les lettres minuscules, les chiffres AuthType Basic ainsi que + et /. Cela AuthName «ma zone privee» permet de s’assurer que AuthBasicProvider file les données ne seront pas AuthUserFile /etc/apache2/users altérées lors du transport Require valid-user des données, car ces 64 caractères sont identiques On utilise ici le back-end file (voir plus loin pour des détails sur dans toutes les variantes locales de la table ASCII. les back-ends) ; la directive Require valid-user permet de restreindre l’accès aux utilisateurs dont l’authentification est valide ; Attention, il ne faut pas AuthUserFile file confondre codage et la directive est nécessaire pour le back-end , chiffrement : le premier nous la rencontrerons à nouveau plus loin. ne sert qu’à changer le format d’une donnée et est réversible sans clé ni mot de passe. Base64 ne 2.2 Digest protège pas les données L’authentification digest est définie dans la RFC 2617, qui remplace transmises. la RFC 2069 (An Extension to HTTP : Digest Access Authentication). Elle offre un peu plus de sécurité en ne laissant pas transiter le mot de passe entre le navigateur et le serveur : le mot de passe est alors C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 hashé. En contre-partie, le mécanisme est bien plus complexe et la configuration demande plus de paramètres pour être efficace. L’échange entre le client et le serveur HTTP est alors un peu plus complexe qu’avec basic : 1. Le client demande une URL au serveur sans préciser d’authentification ;

48 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe Installation : authentification

2. Le serveur répond avec le code d’erreur 401 Unauthorized accompagné d’un en-tête WWW-Authenticate: Digest , où les détails peuvent être le niveau de protection, le domaine de protection, l’algorithme à utiliser, l’ensemble étant appelé le challenge ;

3. Le navigateur demande éventuellement le nom d’utilisateur et le mot de passe à son utilisateur, puis calcule une réponse en fonction du challenge et du mot de passe, il transmettra alors la réponse sous forme d’un digest MD5 ;

4. Le serveur vérifie les données d’authentification envoyées par le client en les comparant avec le hash MD5 qui est en sa possession, puis : 4a. si l’authentification est correcte, il retourne la ressource demandée, 4b. si l’authentification échoue, il renvoie une erreur 401, puis retour à l’étape 2. à retenir La mise en œuvre de ce mode d’authentification avec Apache2 Hashage prendra la forme suivante : Le hashage consiste à Fichier calculer une empreinte AuthType Digest permettant d’identifier AuthName «ma zone privee» une donnée de manière AuthDigestProvider file unique, sans transmettre AuthDigestDomain /prive la donnée elle-même. AuthUserFile /etc/apache2/users Les algorithmes de Require valid-user hashage assurent que deux données différentes n’auront jamais la même Avec cette authentification, les champs utilisés dans l’en-tête empreinte. HTTP WWW-Authenticate sont les suivants : Pour un maximum de → realm est le « royaume » (ou domaine de protection), tel sécurité, le hashage est que défini par AuthName (de la même manière qu’avec « salé » (une autre valeur l’authentification basic) ; y est adjointe), afin de ne pas transmettre → domain permet de spécifier un ou plusieurs URI qui se deux fois la même trouvent dans le même domaine de protection, ce champ étant empreinte. Le serveur défini par la directive AuthDigestDomain ; ayant connaissance de l’empreinte simple et → nonce correspond à un nombre à usage unique à utiliser pour du sel sera capable de le challenge ; cette valeur peut éventuellement être contrôlée valider l’exactitude de par la directive optionnelle AuthDigestNonceLifetime, l’empreinte « salée ». déterminant la durée pendant laquelle elle est valable ; réduire cette durée de vie permet de limiter les risques de rejeu d’un même challenge, la valeur par défaut étant de 5 minutes, une valeur négative imposant une durée illimitée de validité du nonce (dangereux) ;

C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 → opaque est une chaîne de caractères optionnellement fournie au navigateur, qui devra la retourner à l’identique ; → stale est un code de réponse permettant de signaler au navigateur que le nonce utilisé est expiré : si c’est le cas, le navigateur retourne une réponse avec le code d’erreur 401 et la valeur stale à true, forçant ainsi le navigateur à utiliser le nouveau nonce ;

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 49 Installation : authentification 2 → algorithm indique l’algorithme de hashage à utiliser pour le calcul du digest – pour l’heure, seul l’algorithme MD5 est supporté, alors que la norme définit également la possibilité d’utiliser MD5-sess, mais la documentation d’Apache indique que ce dernier est mal implémenté ; → qop (pour quality of protection) permet un choix théorique entre une simple authentification avec auth et une authentification avec contrôle d’intégrité avec auth-int. Lorsque les deux valeurs sont spécifiées, le navigateur peut choisir le niveau de qualité qu’il souhaite utiliser. Cependant, Apache n’implémente pas encore auth-int.

2.3 Form

Cette troisième option n’est pas à proprement parler un type d’authentification HTTP. Il s’agit d’une implémentation, au sein du navigateur, d’une habitude qui a été prise par la plupart des développeurs d’applications web : l’authentification par formulaire. En effet, les fenêtres d’authentification des navigateurs ne sont pas toujours très « sexy », les sites présentent alors des formulaires. Dans ce cas, l’authentification est entièrement déportée dans l’application elle-même, en contournant complètement les mécanismes d’authentification d’Apache. Ce pseudo-type d’authentification permet de conserver cette présentation en formulaire tout en utilisant les mécanismes (back-ends) d’authentification d’Apache. Notons que, dans ce cas, le mot de passe circule en clair sur le réseau, comme dans le cas de l’authentification basic. Pour utiliser cette authentification, les lignes suivantes peuvent par exemple être utilisées dans la configuration d’Apache : Fichier AuthType form AuthFormProvider file AuthUserFile /etc/apache2/users AuthName «ma zone privee» AuthFormLoginRequiredLocation /login.html Session On SessionCookieName session path=/ SessionCryptoPassphrase

Cette option n’est disponible qu’à partir d’Apache 2.4, elle n’est donc pas utilisable sur des serveurs Debian ou Ubuntu actuels...

Les back-ends

C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 3

Maintenant que nous en savons un peu plus sur les types d’authentification possibles, nous pouvons nous pencher sur la partie la plus intéressante : la manière de stocker les informations d’authentification sur notre serveur. Il existe un nombre important de providers différents. Certains peuvent être utilisés indifféremment avec une authentification basic ou digest, d’autres ne fonctionneront qu’avec basic (ou form).

50 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe Installation : authentification

C’est le cas, par exemple, de l’authentification via LDAP, qui n’est pas compatible avec le stockage des hashs car utilisant le système d’authentification du serveur LDAP. Ce module, authnz_ldap, mérite à lui seul un article spécifique tant il y a de choses à dire sur sa mise en œuvre. Nous l’aborderons ultérieurement. Le choix du provider à utiliser se fait grâce à la directive AuthBasicProvider, AuthDigestProvider ou AuthFormProvider.

3.1 File

Le provider file est le plus simple à mettre en œuvre, il est généralement le plus utilisé sur des serveurs « personnels ». Il permet de traiter les données stockées dans de simples fichiers texte, où le nom d’utilisateur et le mot de passe associé sont référencés ligne par ligne. Par défaut, le mot de passe est chiffré par la fonction crypt(), mais il est également possible de choisir un stockage sous forme de hash MD5, voire pour les plus téméraires par un stockage du mot de passe en clair. Sa mise en place est très simple, avec une configuration comme ce que nous avons vu plus haut : Fichier AuthType Basic AuthName «ma zone privee» AuthBasicProvider file AuthUserFile /etc/apache2/users Require valid-user

La seule directive utilisée par ce provider est AuthUserFile, qui doit pointer vers le fichier qui contient les mots de passe.

3.1.1 Gérer le fichier de mots de passe

Le fichier de mots de passe pour ce provider avec une authentification basic peut être géré avec la commande htpasswd. L’utilisation de base de cette commande est la suivante : Fichier htpasswd

Pour une première exécution, cette commande prend l’argument -c (pour create, créer le fichier). Pour créer le fichier /etc/apache2/users avec un utilisateur monlogin, la commande sera donc : Terminal

C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 ~# htpasswd -c /dev/apache2/users monlogin

Pour automatiser cette commande, on peut utiliser l’option -b, qui permet de donner le mot de passe en argument : Terminal ~# htpasswd -b /dev/apache2/users autrelogin sonmotdepasse

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 51 Installation : authentification 2 Mais attention, si vous exécutez cette commande manuellement, il y a de fortes chances que le mot de passe soit stocké en clair... dans l’historique de votre shell !

Les autres options intéressantes sont -m pour utiliser MD5, -s pour forcer SHA, -D pour supprimer un utilisateur...

Lorsque le type d’authentification est digest, l’outil pour gérer le fichier de mots de passe est htdigest. Cette commande n’accepte que l’argument -c, pour créer le fichier de mots de passe. Il n’est pas possible de donner le mot de passe en ligne de commandes, par exemple. De plus, cette commande prend un argument supplémentaire, le domaine de protection (realm) : Fichier htdigest [-c]

Par exemple : Terminal ~# htdigest -c /etc/apache2/users «ma zone privee» monlogin

3.2 DBM

Lorsqu’on gère un nombre de plus en plus important d’utilisateurs, les fichiers texte, non optimisés pour les recherches, arrivent à leurs limites. Il faut donc envisager l’utilisation d’un format de base de données plus adapté à ce genre de manipulations.

La version « light » de cette mise en œuvre prend forme avec le module authn_dbm, permettant de stocker les couples login/mot de passe dans un fichier au format Berkeley DB.

Une configuration d’Apache pour ce provider peut, par exemple, être la suivante : Fichier AuthType Basic AuthName «ma zone privee» AuthBasicProvider dbm AuthDBMUserFile /etc/apache2/users.dbm AuthDBMGroupFile /etc/apache2/users.dbm Require valid-user

3.2.1 Gérer la base DBM

C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 Un tel fichier pourra être créé très facilement pour le type d’authentification basic. Un outil spécialement conçu et livré avec Apache est disponible, sous le nom dbmmanage. Cette commande prend différents arguments :

→ En premier, le nom de fichier sur lequel travailler ;

→ En second, la sous-commande à exécuter ;

→ Enfin, le ou les arguments relatifs à cette sous-commande.

52 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe Installation : authentification

Voici quelques exemples d’utilisation de cette commande... → Ajouter un utilisateur à la base : Terminal ~# dbmmanage /etc/apache2/users.dbm adduser monlogin

→ Ajouter un utilisateur en précisant son groupe : Terminal ~# dbmmanage /etc/apache2/users.dbm adduser autrelogin – autregroupe

→ Modifier le groupe auquel appartient un utilisateur : Terminal ~# dbmmanage /etc/apache2/users.dbm update monlogin . mongroupe

→ Supprimer un utilisateur : Terminal ~# dbmmanage /etc/apache2/users.dbm delete monlogin

→ Lister les utilisateurs de la base (le retour de cette commande précise également le groupe) : Terminal ~# dbmmanage /etc/apache2/users.dbm view

3.2.2 DBM et digest

Si on essaye de changer le type d’authentification de basic à digest, on se rend rapidement compte d’un problème dans les journaux d’Apache : Fichier Digest: user ‘monlogin’ in realm ‘ma zone privee’ not found: /prive/

Le fichier DBM ne contient pas l’information nécessaire à l’authentification digest, car la commande dbmmanage ne dispose d’aucune option adaptée à ce type d’authentification. Il est cependant possible de forcer un peu la main de dbmmanage en faisant nous-mêmes une partie du travail. En regardant les sources du serveur et des modules, on comprend ce qu’Apache s’attend à trouver en lisant les fichiers DBM pour ce type d’authentification. Le nom d’utilisateur stocké, tout d’abord, est composé à la fois du login et du domaine de protection, les deux étant séparés par un double-point. Ceci est relativement facile à régler en ligne de commandes. C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 D’autre part, le mot de passe chiffré dans la base DBM doit être le condensé MD5 de la concaténation du nom d’utilisateur, du domaine de protection et du mot de passe en clair de l’utilisateur, séparés par des double-points. En d’autres termes, il faut stocker le résultat de echo -n "::" | md5sum.

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 53 Installation : authentification 2 On peut donc écrire un court script shell qui servira de wrapper à dbmmanage : Fichier # !/bin/sh FILE=$1 CMD=$2 USER=$3 REALM=$4 PASS=$5 GROUP=$6

HASH=$(echo -n «$USER:$REALM:$PASS» | md5sum | cut -d» « -f1) DBUSER=$(echo -n «$USER:$REALM)

/usr/bin/dbmmanage «$FILE» «$CMD» «$DBUSER» «$HASH» «$GROUP»

Ce n’est là, bien entendu, qu’un premier jet ne demandant qu’à être amélioré et nettoyé. Dans les grandes lignes, on génère, dans la variable $HASH, le condensé (ou hash) MD5 qui servira de mot de passe et le nom d’utilisateur dans $DBUSER. On reprend ensuite les autres éléments de la commande pour composer la syntaxe de dbmmanage. Ce n’est, bien entendu, qu’une solution parmi d’autres, car en y regardant de plus près... Terminal ~# file $(which dbmmanage) /usr/bin/dbmmanage: a /usr/bin/perl script text executable

... dbmmanage est un script Perl, qu’on peut tout à fait modifier pour l’adapter à nos besoins.

3.3 MySQL

Le provider dbm permet de simplifier la gestion des utilisateurs et surtout, d’accélérer les recherches si le « cheptel » est important. Cependant, la manipulation de fichiers DBM, en particulier depuis des interfaces web en PHP, Perl ou Python, n’est pas une partie de plaisir. Il s’agit en effet d’un format de base de données, mais non d’un système complet et adapté à tous les usages. Pour stocker les utilisateurs sous une forme plus facilement gérable, on peut utiliser le module auth_mysql, disponible sous Debian et Ubuntu grâce au paquet libapache2-mod-auth-mysql : Terminal ~# apt-get install libapache2-mod-auth-mysql

Comme le précise la documentation de ce module, les informations strictement nécessaires à placer dans une table MySQL sont le nom d’utilisateur et le mot de

C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 passe. Avec ce provider, la configuration d’Apache peut accepter les directives suivantes (cette liste n’est pas exhaustive, elle ne détaille que les directives les plus intéressantes) : → AuthMySQLHost : hôte de la base de données MySQL ; → AuthMySQLPort : port de la base de données (3306 par défaut) ;

54 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe Installation : authentification

→ AuthMySQLSocket : un socket UNIX est utilisé au lieu d’une connexion réseau si l’hôte est « localhost » (/tmp/mysql.sock par défaut) ;

→ AuthMySQLUser : utilisateur pour se connecter à la base MySQL ;

→ AuthMySQLPassword : mot de passe pour se connecter à la base MySQL ;

→ AuthMySQLDB : nom de la base de données à interroger ;

→ AuthMySQLUserTable

: nom de la table qui contient les noms d’utilisateurs et les mots de passe ;

→ AuthMySQLUserCondition : conditions complémentaires à utiliser lors de l’interrogation de la table des utilisateurs et mots de passe ;

→ AuthMySQLNameField : nom de la colonne contenant les à savoir noms d’utilisateurs ; MySQL, mais → AuthMySQLPasswordField : nom de la colonne contenant encore... les mots de passe ; Nous abordons ici le module → AuthMySQLPwEncryption pour l'authentification avec MySQL, mais il faut [none|crypt|scrambled|md5|aes|sha1] : type de chiffrement des noter que ce n'est pas le mots de passe dans la base de données (crypt par défaut) ; seul serveur de bases de données SQL supporté ! → AuthMySQLGroupTable

: nom de la table qui contient les Debian et Ubuntu proposent informations liées aux groupes (si nécessaire) ; notamment le support de PostgreSQL pour → AuthMySQLGroupCondition : condition complémentaire à utiliser lors l'authentification au travers de l’interrogation de la table des groupes. du paquet libapache2- Nous le voyons avec certaines de ces directives, ce module est très mod-auth-pgsql. flexible, permettant d’utiliser une base de données déjà existante plutôt que d’adapter une base à son fonctionnement. Ainsi, si vous utilisez une application web stockant des comptes et des mots de passe, vous pouvez très facilement restreindre l’accès à une partie du site ou éventuellement à un autre site. Configurer l’accès à un service en ligne maison, où l’utilisateur s’authentifie avec son login et son mot de passe d’un WordPress en production, par exemple, devient un jeu d’enfant. La gestion des comptes s’en trouve ainsi parfaitement automatisée, puisqu’elle est prise en charge directement par le code PHP présumé audité et mature du CMS open source. auth_mysql semble avoir été clairement conçu dans cette optique. Pour s’en convaincre, il suffit de lire les diverses documentations livrées avec le paquet Debian. Seul point à ne pas perdre de vue : la charge induite par les

C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 requêtes incessantes au serveur MySQL ; mais des mécanismes de cache existent et sont relativement efficaces à ce niveau (requêtes identiques sur une plage de temps réduite). Enfin, puisque rien n’est parfait en ce monde, la documentation précise clairement « Stick with Basic, no others work at present ». Nous nous sommes donc abstenus de tirer le diable par la queue et nous en restons à une configuration avec le type basic.

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 55 Installation : authentification 2 3.4 PAM

Installé via le paquet libapache2-mod-auth-pam, le provider auth_pam offre des fonctionnalités très intéressantes. Il permet d’utiliser le système modulaire d’authentification PAM pour authentifier les utilisateurs. La configuration de ce provider est risquée, il faut notamment éviter de stocker les utilisateurs dans le fichier /etc/passwd classique : → Le concept même de réutilisation d’un compte local pour une authentification sur un serveur web est généralement une mauvaise chose : si le secret est compromis, c’est un accès au shell que l’on risque d’offrir à un attaquant ;

→ Pour qu’un utilisateur local puisse s’authentifier, en faisant appel à PAM et à la configuration par défaut avec common-auth, common-account et common-password, il faut que le fichier à retenir /etc/shadow soit lisible par un processus fonctionnant sous l’identité du serveur Apache – soit on rend ce fichier lisible par le Le système PAM (pour groupe www-data (ce qui est impensable), soit on ajoute l’utilisateur Pluggable Authentication Module) est notamment www-data au groupe shadow (ce n’est pas mieux) – un utilisateur utilisé pour authentifier pourrait alors placer un script CGI qui lit le contenu de ce fichier afin les utilisateurs locaux de récupérer l’intégralité des mots de passe chiffrés du serveur, ce du système (qui se qui est peu rassurant ; connectent par SSH par exemple). Il est lui-même → Cette authentification ne fonctionne qu’avec basic (ou form), les mots modulaire et peut être de passe des utilisateurs locaux circulent alors en clair sur le réseau : interconnecté avec de quand il est clairement établi dans la vie d’un administrateur système nombreux systèmes, pour que rlogin est de la préhistoire au bénéfice d’OpenSSH, il y a là de une authentification par quoi hérisser des poils... LDAP, MySQL, Kerberos, Active Directory, etc. 3.5 authnz_external

Voici un provider qui, s’il est mal utilisé, est aussi dangereux (voire plus encore) que le précédent. Mais il peut également être bien plus souple et puissant que tous les providers dont nous avons déjà parlé. En effet, authnz_external permet tout simplement de développer un système d’authentification de zéro. Pour ce faire, à la fois pour l’aspect « authn » que pour l’aspect « authz », il permet l’utilisation d’un programme externe appelé par le module pour vérifier les informations fournies par le navigateur web. Vous comprendrez dès lors que tout repose entièrement sur votre développement, vos algorithmes et votre implémentation. Ce module offre une souplesse inégalée, même s’il ne supporte pas le

C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 type digest. On peut envisager bon nombre de back-ends possibles et, pourquoi pas, réimplémenter façon « maison » ceux existants (comme LDAP ou MySQL). Il n’y a plus de limite ni de dépendance à un paquet ou à une équipe de développement. On peut même envisager une sorte de wrapper qui se chargera de faire reposer l’authentification sur une autre infrastructure, pourquoi pas distante (c’est d’ailleurs un peu cela qui est fait avec la méthode « pwauth » présentée plus bas).

56 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe Installation : authentification

Ne perdons pas de vue, cependant, le caractère récurrent de l’authentification et les ressources qu’une telle méthode d’authentification risque de consommer. La sécurité doit également être gardée à l’esprit de manière constante. Il serait dommage de mettre en péril toute une telle construction pour un strdup() mal placé... Ce module passe le nom d’utilisateur, le mot de passe et le nom de groupe (si cela est configuré) au programme externe via l’une de ces deux méthodes : soit par des variables d’environnement, soit par redirection. Après installation du paquet libapache2-mod-authnz- external (sur Debian ou Ubuntu) et activation de ce module avec a2enmod, son utilisation se fait en deux étapes...

3.5.1 Définition de la méthode

Il faut d’abord définir la méthode d’authentification externe qui sera utilisée. Cela se fait avec deux directives : DefineExternalAuth et DefineExternalGroup. La première permet de définir le programme à utiliser pour l’authentification (vérification du bon mot de passe par rapport au nom d’utilisateur), la seconde indique celui à utiliser pour l’autorisation (appartenance d’un utilisateur à un groupe). La syntaxe est identique pour les deux directives : Fichier

où : → est remplacé par le nom de la directive ;

est un mot-clé identifiant cette méthode d’authentification, réutilisé par la suite ;

est soit pipe pour une redirection sur l’entrée standard du programme, soit environment pour l’utilisation de variables d’environnement ;

est le chemin du programme à utiliser.

On pourra donc avoir, par exemple, les lignes suivantes : Fichier DefineExternalAuth myauth pipe /usr/local/bin/myauth.sh DefineExternalGroup myauthgroup pipe /usr/local/bin/myauthgroup.sh

Ces directives concernent tout le contexte où elles sont placées ;

C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 il n’y a pas de préférence en termes de fichiers où les mettre, il y a cependant des bonnes pratiques. Si elles sont amenées à être utilisées dans plusieurs contextes desservis par le serveur, il est judicieux de les placer dans un fichier supplémentaire du répertoire /etc/apache2/conf.d/. Si elles sont spécifiques à un VirtualHost, elles peuvent être placées dans la définition du VirtualHost.

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 57 Installation : authentification 2 3.5.2 Utilisation de la méthode

Une fois la méthode d’authentification définie et associée à un mot-clé, elle peut être utilisée dans la configuration de l’authentification d’Apache de la manière suivante : Fichier AuthType Basic AuthName «ma zone privee» AuthBasicProvider external AuthExternal myauth Require valid-user

Les commandes appelées par cette méthode reçoivent donc les données de deux manières différentes : → Avec la méthode pipe, Apache passe le nom d’utilisateur sur la première ligne, puis le mot de passe sur la seconde ligne de l’entrée standard du programme exécuté ; → Avec la méthode environment, Apache place le nom d’utilisateur dans la variable d’environnement USER et le mot de passe dans la variable PASS. Le programme doit retourner le code d’erreur 0 en cas d’authentification réussie, un autre code d’erreur en cas d’échec de l’authentification.

3.5.3 Utiliser PAM

Ce provider permet notamment d’utiliser l’authentification des utilisateurs du système avec PAM en évitant de rendre le fichier /etc/shadow lisible par www-data, en l’associant au programme pwauth. Ce programme est disponible dans Debian et Ubuntu au sein du paquet pwauth. Les lignes suivantes permettent de faire cela : Fichier DefineExternalAuth pwauth pipe /usr/sbin/pwauth

AuthType Basic AuthName «ma zone privee» AuthBasicProvider external AuthExternal pwauth Require valid-user

C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 4 Require

L’autorisation post-authentification est contrôlée par la directive Require, que nous avons rencontrée jusqu’ici avec le seul argument valid-user. Dans ce cas, l’autorisation repose sur la simple existence de l’utilisateur et la validité de son authentification ; c’est le cas le plus courant.

58 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe Installation : authentification

Notons que cette directive peut également être utilisée sans authentification, pour autoriser des accès sur la base d’autres éléments qu’un nom d’utilisateur/mot de passe... De base, avec Apache 2.4, la directive Require accepte les valeurs suivantes :

→ Require all granted : accès autorisé sans restriction (sans authentification) ;

→ Require all denied : accès interdit à tous ;

→ Require env : accès autorisé si la variable spécifiée est définie ;

→ Require method : accès autorisé seulement avec la méthode indiquée ;

→ Require expr : accès autorisé seulement si l’expression logique donnée est vraie. à savoir Attention : les valeurs sus-citées ne sont pas disponibles avec Apache 2.2 (donc Require : une indisponibles sur la version actuelle de directive complexe Debian ou d’Ubuntu). Nous le voyons, les possibilités pour Require Les autres valeurs supportées par cette directive dépendent peuvent également directement des modules authz_* qui sont chargés, par exemple : varier selon la méthode d'authentification que → Require user (fourni par mod_authz_ vous utilisez... Il n'est user) : accès autorisé à l’utilisateur ou aux utilisateurs malheureusement pas indiqué(s) ; possible d'approfondir cette directive en → Require ip (fourni par mod_authz_host, quelques pages. N'hésitez uniquement à partir d’Apache 2.4) : accès autorisé seulement à pas à consulter la partir de l’adresse IP indiquée ; documentation du ou des module(s) que vous → Require group (fourni par les souhaitez utiliser, afin de mod_authz* ou mod_authnz_* qui supportent la gestion des connaître la liste complète groupes) : accès autorisé uniquement aux personnes qui font partie des options disponibles ! du groupe indiqué.

Conclusion

C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 Il existe d’autres modules, disponibles sous la forme de paquets ou à compiler, permettant d’offrir des providers supplémentaires ; nous ne pouvons pas tous les traiter ici... Ceux que nous avons abordés permettent toutefois de couvrir une vaste gamme de besoins : nous avons vu les classiques, les risqués et les plus souples. à vous maintenant d’en faire bon usage et de continuer vos explorations, vos configurations et pourquoi pas, vos développements. ▪

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 59 3 C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5

60 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe proGrammer poUr Le web 3 à découvrir dans cette partie... page 62 Sites dynamiques et CGI Plus évolués que les sites statiques, les sites dynamiques savent adapter leur contenu aux demandes des visiteurs. CGI est l'une des techniques – historiquement, la première – pour cet aspect dynamique.

page 66 PHP, le langage du Web dynamique Langage « orienté Web » le plus connu, il est souvent associé au serveur HTTP Apache et au serveur de bases de données MySQL.

page 70 Perl, un classique toujours d'usage Langage de « geek » par excellence, c'est l'un des premiers à avoir été utilisé par les administrateurs système et Web, que ce soit pour des scripts complexes ou pour des pages web dynamiques.

page 74 Les possibilités offertes par Python Langage facile d'accès, mais performant et puissant, celui-ci est utilisé dans de nombreux domaines, le Web étant l'un d'entre eux.

C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 page 78 Ruby, un langage révélé par son framework Langage qui fait figure de « petit jeune », il monte, il monte... Grâce à Ruby on Rails, mais également grâce à son approche de la programmation qui séduit de nombreux développeurs.

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 61 Installation : mon premier Apache 3 proGrammer poUr Le web

sites dyNamiqUes et cGi n site web statique, amoureusement C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 programmé en HTML, c’est bien joli mais ça ne va pas très loin. On veut généralement rapidement proposer des éléments dynamiques Usur un site web, pour améliorer l’expérience utilisateur ou pour simplifier son administration... Les CGI sont une solution à ce problème.

62 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe Programmer pour le web : sites dynamiques et CGI

Un site dynamique n’est pas un site qui bouge beaucoup, qui va faire du sport tous les soirs et les week-ends. Un site dynamique n’est pas non plus un site avec plein d’animations qui font mal aux yeux des visiteurs... Un site dynamique, c’est un site qui s’adapte aux requêtes d’un utilisateur, en desservant des données variables, qui peuvent par exemple provenir d’une base de données comme MySQL. Cet aspect « dynamique » est implémenté « côté serveur » : c’est le serveur HTTP Apache qui doit faire en sorte que le contenu à desservir soit généré dynamiquement. Pour cela, plusieurs approches sont possibles. Dans tous les cas, ce dynamisme est le résultat de développements, qui peuvent se faire dans différents langages et dont le résultat est transmis par Apache au client, un navigateur web généralement.

1 CGI

La première technologie qui a permis cette génération dynamique de page s’appelle CGI (pour ). Elle a été inventée en 1993 sur le serveur httpd du NCSA, Apache en a donc bien sûr directement hérité ; pourtant, la norme décrivant cette technologie est la RFC 3875, publiée en 2004 ; auparavant, cet usage n’était pas normalisé. Le fonctionnement de CGI est simple : le serveur Apache fait appel à un programme lorsqu’un client essaie de visiter une page dynamique, le programme retourne les données à transmettre au client. L’intérêt de cette technologie est que le programme en question peut être programmé en n’importe quel langage : tous les langages supportent les variables d’environnement et savent écrire sur leur sortie standard. Lors de l’exécution du programme, le serveur place certains éléments dans des variables d’environnement, parmi lesquelles on pourra retrouver REQUEST_METHOD (la méthode HTTP utilisée par le client), REMOTE_ADDR (l’adresse IP du client) ou encore QUERY_STRING (la partie de l’URL après le point d’interrogation). Le programme doit alors faire un retour, sur sa sortie standard, sous la forme suivante : Fichier [ligne vide] C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5

Les en-têtes HTTP fournis par le programme sont ensuite complétés par les en-têtes qu’y ajoute le serveur Apache. On retrouvera souvent Content-Type comme seul en-tête fourni par le programme exécuté par CGI, permettant d’indiquer au client quel type de contenu lui est retourné.

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 63 Programmer pour le web : sites dynamiques et CGI 3 Visiteur Apache Script CGI Se connecte et demande Fonctionne en continu Exécuté à la demande

Requête HTTP

Exécution

Initialisation Traitement Mise en forme

Transmission Réponse

Définition Requête avec CGI Le terme socket (signifiant « prise » en anglais) désigne un élément logiciel qui permet à deux 1.1 FastCGI programmes totalement Un gros problème de CGI est la ré-exécution systématique d’un programme complet indépendants de communiquer de manière à chaque requête, ce qui est particulièrement gourmand en ressources (même si ce uniforme. Sous Linux (et n’est qu’un petit script, il faut en charger l’interpréteur). UNIX plus généralement), Pour pallier ce problème, FastCGI a été inventé en 1996 par la société Open Market, ces sockets sont qui l’a implémenté dans son propre serveur web. matérialisés sous forme de fichiers spéciaux. La logique de fonctionnement est globalement la même : l’environnement est donné à un programme, qui renvoie des en-têtes et un contenu. La différence est dans la manière de communiquer entre le serveur HTTP et le programme. Alors qu’avec CGI c’est Apache qui lance le programme, avec FastCGI ce programme est continuellement en fonctionnement (mode daemon) : le serveur HTTP se connecte à un socket UNIX (dans le cas d’un programme local) ou à un port TCP (dans le cas d’un programme distant), transmet les variables d’environnement de cette manière et attend la réponse du programme par le même biais. De cette manière, le « serveur FastCGI » est toujours en fonctionnement, il n’y a pas d’environnement à initialiser encore et encore.

Visiteur Apache Programme FastCGI Se connecte et demande Fonctionne en continu Fonctionne en continu

Requête HTTP

Transmission C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5

Traitement Mise en forme

Transmission Réponse

Requête avec FastCGI

64 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe Programmer pour le web : sites dynamiques et CGI

2 Autres possibilités

En dehors de CGI et de FastCGI, on voit généralement deux approches possibles : → L’intégration au sein d’Apache d’un module capable d’interpréter un langage (c’est ce que l’on fait généralement avec PHP, nous verrons cela plus loin) ; → L’utilisation d’un serveur tiers (à l’instar de FastCGI), auquel on transmettra (c’est généralement le cas des applications développées avec Python, nous verrons également cela plus loin). Précisons tout de même quelques généralités sur ces deux méthodes... Pour l’intégration d’un module au sein d’Apache, ce module doit être compilé précisément pour la version utilisée du serveur HTTP (ce qui n’est pas un problème s’il est disponible sous forme de paquet) et il n’est pas possible d’utiliser deux fois le même module avec des variantes (par exemple, il n’est pas possible d’utiliser deux versions différentes de PHP sur un même serveur Apache). Lors de l’utilisation d’un serveur tiers, il faut s’assurer que la communication passe bien entre les deux éléments ; en général, soit un serveur tiers est démarré (cas de Java avec Tomcat par exemple), soit un programme spécifique est lancé par Apache. Cela consomme donc forcément un peu de ressources supplémentaires (surtout dans le cas de Java). ▪

Visiteur Apache Se connecte et demande Fonctionne en continu, Embarque un interpréteur

Traitement par l'interpréteur Requête HTTP Mise en forme par l'interpréteur

Réponse HHTP

Requête avec un module intégré

Visiteur Apache Serveur tiers Se connecte et demande Fonctionne en continu Fonctionne en continu

Requête HTTP

Requête HTTP Traitement Mise en forme

Réponse HHTP Réponse HHTP

Requête avec un serveur tiers C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5

Ressources Tutoriel sur CGI dans la documentation d’Apache : http://httpd.apache.org/docs/2.4/fr/howto/cgi.html Documentation de FastCGI pour Apache : http://www.fastcgi.com/mod_fastcgi/docs/mod_fastcgi.html

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 65 Programmer pour le web : CGI 3 proGrammer poUr Le web

pHp, Le LaNGaGe dU web dyNamiqUe

HP est un langage développé spécifiquement pour le Web. Il permet de créer des sites dynamiques C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 et propose une syntaxe proche du C, ainsi qu’une collection de bibliothèques simples à utiliser, Ple rendant accessible à grand nombre de développeurs. Ses différentes propriétés lui ont permis de devenir rapidement le langage le plus utilisé pour développer des sites web dynamiques et des applications web.

66 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe Programmer pour le web : PHP, le langage du Web dynamique

1 Histoire

Le langage PHP a été créé en 1994 par Rasmus Lerdorf, basé sur des développements qu’il avait fait spécifiquement pour son site web personnel. Connu d’abord sous le nom PHP/FI (pour Personal Home Page Tools/Form Interpreter), son cœur a été re-développé en 1997 par deux étudiants, Andi Gutmans et Zeev Suraski, qui sont également les auteurs du moteur Zend.

(crédits : Ed, via Wikimedia Commons) Wikimedia via Ed, : (crédits Sa version actuelle est PHP 5, dont la première sous-version Rasmus Lerdorf, l’inventeur est sortie en 2004. Cette version introduit un modèle objet de PHP (jusqu’en 2004, la programmation « orienté objet » était difficile – voire impossible – avec PHP), une gestion des erreurs par exceptions et des fonctionnalités pour les entreprises. PHP 4 n’est plus maintenu depuis 2007, avec la fin du support de sa sécurité en 2008.

Mise en œuvre dans 2 Apache

La méthode la plus classique pour mettre en œuvre le support du langage PHP dans Apache est par le module php d’Apache. Ce module s’installe avec la commande suivante : Terminal ~# apt-get install libapache2-mod-php5

Lorsque l’on exécute cette commande, on se rend compte que le MPM Prefork sera installé, au lieu du MPM Worker qui est installé par défaut avec Apache : Terminal Lecture des listes de paquets... Fait Construction de l’arbre des dépendances Lecture des informations d’état... Fait Les paquets supplémentaires suivants seront installés : apache2-mpm-prefork libonig2 libqdbm14 php5-cli php5-common php5-suhosin Paquets suggérés : php-pear Les paquets suivants seront ENLEVÉS : apache2-mpm-worker Les NOUVEAUX paquets suivants seront installés : apache2-mpm-prefork libapache2-mod-php5 libonig2 libqdbm14 php5-cli php5-common php5-suhosin 0 mis à jour, 7 nouvellement installés, 1 à enlever et 0 non mis à jour. C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 Il est nécessaire de prendre 6 662 ko dans les archives. Après cette opération, 17,3 Mo d’espace disque supplémentaires seront utilisés. Souhaitez-vous continuer [O/n] ?

Normalement, ce module est directement activé dans Apache 2 ; en effet, la commande a2enmod php est automatiquement exécutée par le script de post-installation.

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 67 Programmer pour le web : PHP, le langage du Web dynamique 3 2.1 Configurer Apache pour PHP

En installant le paquet libapache2-mod-php5 sur un système Debian ou Ubuntu, Apache est automatiquement configuré pour utiliser PHP. Cependant, pour pouvoir configurer cela sur un autre système ou juste pour savoir « comment ça marche », voyons les directives de configuration de PHP dans Apache. Tout d’abord, le module doit être chargé ; cela se fait avec la directive LoadModule. Il faut ensuite indiquer à Apache qu’il doit gérer les fichiers .php avec ce module. Pour cela, la directive nécessaire est AddHandler. Enfin, si l’on veut qu’un fichier PHP soit immédiatement chargé lorsque l’on accède à un répertoire (par exemple index.php), il faut ajouter cette mention dans la directive DirectoryIndex. Cela peut donc donner : Fichier LoadModule php5_module /usr/lib/apache2/modules/libphp5.so AddHandler application/x-httpd-php .php DirectoryIndex index.html index.php

Notons que la configuration par défaut du module sur Debian et Ubuntu est quelque peu différente et va plus loin, notamment pour le handler : grâce aux lignes suivantes dans le fichier /etc/apache2/mods-available/php5.conf, ce module est utilisé pour les fichiers portant l’extension .php, .php3 ou .phtml : Fichier SetHandler application/x-httpd-php

Le DirectoryIndex standard de Debian et Ubuntu, quant à lui, est particulièrement complet, dans le fichier /etc/apache2/mods-available/dir.conf : Fichier DirectoryIndex index.html index.cgi index.pl index.php index.xhtml index.htm

3 Utiliser PHP

L’utilisation du langage PHP est très simple : il suffit de mettre en place un fichier avec l’extension .php dans l’arborescence d’un site web pour qu’il soit interprété. Dans un fichier .php, tout le code en PHP doit être inséré dans une balise . Un « Hello world » en PHP serait : Fichier

C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5

68 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe Programmer pour le web : PHP, le langage du Web dynamique

Ce langage permet donc très simplement d’insérer des parties dynamiques dans un code HTML statique existant. C’est sa force : il se « greffe » sur du code HTML existant et peut ainsi facilement et rapidement être utilisé.

4 Configurer PHP

Sur un système Debian ou Ubuntu, la configuration de PHP se situe dans le répertoire /etc/php5. Plus précisément, ce répertoire contient deux sous-répertoires : → /etc/php5/cli pour la configuration de la commande PHP utilisée en ligne de commandes, → /etc/php5/apache2 pour la configuration de PHP lorsqu’il est utilisé par Apache 2. à retenir Le fichier qui nous intéresse le plus est /etc/php5/apache2/php.ini : Raccourci il contient les paramètres globaux du langage, par exemple la limite en taille de Nous avons utilisé dans fichier acceptée lors d’un téléversement, l’espace mémoire maximum qui peut être notre exemple la syntaxe utilisé par un script PHP, la durée maximale d’exécution d’un script, etc. . On se retrouvera souvent à Le répertoire /etc/php5/apache2/conf.d/ contient, quant à lui, des utiliser ce genre de chose fichiers de configuration complémentaires qui sont également chargés. Ce si l'on veut programmer découpage permet de gérer plus proprement les configurations de chaque module proprement. Pour ce faire, de PHP. Car, oui, l’interpréteur PHP est lui-même également modulaire. une syntaxe plus simple Les distributions Debian et Ubuntu proposent différents modules, permettant existe : . L'exemple suivant est propre d’étendre les capacités d’Ubuntu. On retrouvera par exemple : et tout à fait correct : → php5-ldap pour interagir avec une base LDAP ;

    → php5-mysql pour lire ou écrire dans une base MySQL ; → php5-pgsql pour lire ou écrire dans une base PostgreSQL ;
  • → php5-imap pour la gestion des courriers électroniques par IMAP ;
  • → php5-enchant pour la vérification orthographique ;
→ php5-sqlite pour lire ou écrire dans un fichier SQLite... De très nombreux modules sont disponibles pour l’interpréteur PHP, que ce soit sous forme de paquets Debian/Ubuntu ou téléchargeables par ailleurs. A priori, la configuration par défaut de PHP est suffisante pour des usages classiques. Parfois, une application PHP a besoin de plus de ressources que les limites établies par défaut ; dans ce cas, l’application indique généralement cela lors de son installation et demande à modifier la configuration de PHP, pour ensuite continuer la procédure d’installation. Il n’est donc pas indispensable de plonger dans ces paramètres dans un premier temps ! ▪ C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5

Références Site web de PHP : http://php.net/ Documentation de PHP : http://www.php.net/manual/fr/

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 69 Programmer pour le web : CGI 3 proGrammer poUr Le web

perL, UN cLassiqUe toUjoUrs d'UsaGe

erl est un langage de programmation, associé

C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 à l’origine au traitement de fichiers textes. Il propose une syntaxe inspirée de différents langages et outils : le C, les scripts shell, les Pcommandes sed, awk, grep, expr... C’est un langage qui était fait pour remplacer les scripts shell compliqués. Avec l’apparition des CGI, ce langage a commencé à être utilisé pour le Web...

70 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe Programmer pour le web : Perl, un classique toujours d'usage

1 Histoire

Le langage Perl a été créé en 1987, avant l’invention du Web, par Larry Wall. Celui-ci souhaitait un langage optimisé pour le traitement de fichiers textes, données linéaires ou fichiers de configuration. Perl est réputé pour le grand nombre de possibilités de faire la même chose ; l’une de ses devises est « There is more than one way to do it » (« Il y a plus d’une façon de le faire »). Grâce à sa grande flexibilité, il est devenu un langage de référence pour les administrateurs système.

(crédits : Randal Schwartz, via Wikimedia Commons) à retenir Larry Wall, l’inventeur de Perl Le schéma de numérotation de Perl a changé pour la version 5.6 en 2000 : Nom et auparavant, les versions de Perl étaient notées 5.000, 5.001, 5.002... prononciation jusqu’à 5.005. Le processus de développement a changé après la version 5.10, parue en 2007 : le cycle de publication est maintenant Larry Wall souhaitait appeler son langage Pearl, fixe et une nouvelle version stable sort tous les ans. La version 5.16 mais il s’est rendu compte, est sortie en mai 2012, la 5.18 est censée sortir en mai 2013. avant la publication de la Par ailleurs, une évolution majeure est en train d’être développée, sous version 1.0 de son langage, le nom Perl 6. Cette version n’assurera pas de compatibilité inverse, il que ce nom existait déjà : s’agit d’un nouveau langage, qui a les mêmes « ancêtres » que Perl 5, PEARL (Process and Experiment Automation mais une syntaxe différente. Realtime Language), inventé en 1977. Il décida alors de simplement renommer son langage en Dans Apache : « Perl ». 2 Malgré ce changement de les CGI nom, la prononciation ne change pas. En effet, les Historiquement, Perl est le premier langage utilisé lorsqu’il s’agit de mots « pearl » et « perl » faire des CGI. C’est normal : dans les années 90, Perl était le langage se prononcent de la même préféré des administrateurs système, et les webmestres étaient les manière en anglais ; la administrateurs système. Par conséquent, on retrouvera le plus prononciation du nom de souvent des CGI dans ce langage. ce langage n’est donc pas similaire au mot français La configuration d’Apache est donc simple : « perle ». Fichier ScriptAlias /cgi-bin/ /srv/www/cgi-bin/ AllowOverride None Options +ExecCGI -MultiViews C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 Order allow,deny Allow from all

Reprenons le format dans lequel on doit retourner des données dans le cadre d’un script CGI, traduisons cela en Perl... Pour un simple « Hello world », ça donne la chose suivante :

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 71 Programmer pour le web : Perl, un classique toujours d'usage

3 Fichier #!/usr/bin/perl print ‘Content-type: text/html\n\n’; print ‘’; print ‘’; print ‘

Hello world!

’; print ‘’; print ‘’;

2.1 Le module CGI

Parmi les centaines de milliers de modules proposés pour Perl, l’un d’entre eux répond par- à retenir faitement au besoin des scripts CGI : le module CGI. En effet, ce module simplifie la généra- tion du contenu d’une réponse d’un script CGI en automatisant certaines de ses parties. Droits Ce module propose de nombreuses fonctions permettant de générer du code HTML... d’exécution sans taper de code HTML ! Il accepte indifféremment une approche fonctionnelle ou Les scripts Perl, une approche orientée objet. Par exemple, un « Hello world » pourrait ressembler à qu’ils soient ceci en fonctionnel : exécutés comme Fichier script CGI, FastCGI ou avec #!/usr/bin/perl use CGI qw/:standard/; le module print header, mod_perl, start_html, doivent être h1(‘Hello world!’), exécutables end_html; et lisibles par l’utilisateur sous lequel … ou à ceci en orienté objet : fonctionne Fichier Apache. #!/usr/bin/perl N’oubliez donc use CGI; pas d’utiliser $q = CGI->new; chmod a+rx sur print $q->header, vos fichiers ! $q->start_html, $q->h1(‘Hello world!’), $q->end_html;

à vrai dire, le résultat de ces scripts ira même plus loin que l’utilisation simple, sans ce module, décrite plus haut : ils gèrent directement l’en-tête HTML , la localisation, etc.

2.2. FastCGI

Un script Perl peut également être utilisé avec FastCGI. Dans ce cas, un « Hello world » pourrait ressembler à ceci : Fichier #!/usr/bin/perl use FCGI;

C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 while (FCGI::accept >= 0) { print ‘Content-type: text/html\n\n’; print ‘’; print ‘’; print ‘

Hello world!

’; print ‘’; print ‘’; }

72 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe Programmer pour le web : Perl, un classique toujours d'usage

Dans Apache : 3 le module Perl

De la même manière que pour PHP, un module ajoutant directement le support de Perl existe pour Apache. Une première version de ce module est sortie en 1996, la version stable 1.0 est sortie en juillet 1997. Avec ce module, l’interpréteur Perl reste constamment en mémoire (il n’est pas chargé à chaque requête) et chaque fichier n’est compilé qu’à la première utilisation : l’interpréteur n’a plus à relire le script encore et encore. Ce module s’installe avec la commande suivante : Terminal ~# apt-get install libapache2-mod-perl2

Avec Debian et Ubuntu, ce module est directement configuré dans Apache2 ; en effet, la commande a2enmod perl est automatiquement exécutée par le script de post-installation. Il reste juste à redémarrer Apache pour que cela soit pris en compte.

3.1 Configuration d’Apache

Pour activer le support d’Apache, il est nécessaire d’ajouter quelques lignes dans un contexte particulier. Par exemple : Fichier Alias /perl /srv/www/perl SetHandler perl-script PerlResponseHandler ModPerl::Registry PerlOptions +ParseHeaders Options +ExecCGI Order allow,deny Allow from all

3.2 Scripts Perl

Du côté des scripts Perl, ce module attend exactement la même chose qu’un CGI. Il est donc possible de réutiliser des scripts CGI tels quels. Pour des exemples, ce sera donc la même chose que dans le chapitre traitant de CGI vu précédemment. ▪ C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5

Références Site officiel de Perl : http://www.perl.org/ Documentation du module CGI : http://perldoc.perl.org/CGI.html

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 73 Programmer pour le web : Python 3 proGrammer poUr Le web

Les possibiLités offertes par pytHoN

ython est un langage polyvalent de haut niveau, dont la philosophie est de mettre l’emphase sur la lisibilité du code source. Sa syntaxe semble C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 particulière lorsque l’on connaît les autres Plangages courants : pas d’accolades, pas de point-virgule... Il supporte différents paradigmes de programmation (programmation impérative, fonctionnelle, orientée objet) et propose des fonctionnalités avancées : ramasse-miettes, gestion d’exceptions...

74 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe Programmer pour le web : Les possibilités offertes par Python

1 Histoire à savoir

En 1989, Guido Van Rossum a commencé à L’origine du nom développer sur son temps libre un langage Guido Van Rossum a choisi de programmation proche du langage ABC, de nommer son langage Python car il est fan des développé au sein du CWI (Centrum voor Monty Python, une troupe Wiskunde en Informatica), son employeur de d’humoristes anglais, l’époque à Amsterdam. Le langage Python a notamment de leur série rapidement été adopté par son équipe, chargée du The Monty Python’s Flying déploiement du système d’exploitation Amoeba. Circus. On retrouve de En février 1991, la première version publique de nombreuses références à Python, numérotée 0.9.0, est publiée sur Internet. cette troupe, notamment

(crédits : Doc Searls, via Wikimedia Commons) Wikimedia via Searls, Doc : (crédits dans les exemples de code, Guido Van Rossum, Aujourd’hui, la version de Python la plus utilisée où au lieu d’utiliser foo l’inventeur de Python est la 2.7, sortie en 2010. et bar comme noms de variables, on utilise eggs Notons que Python 3 existe depuis 1998 en et spam. version stable, mais c’est une nouvelle version du langage, pas seulement une évolution. Python 3 est incompatible avec les versions précédentes, ce qui nécessite une réécriture du code ; c’est pourquoi beaucoup de code utilise toujours Python 2. Cette nouvelle version du langage apporte de à retenir nombreuses améliorations, qui n’étaient pas possibles en conservant une compatibilité inverse. Extension .wsgi Notons qu’en réalité, même si c’est un fichier Python, l’application pointée sera le plus souvent suffixée .wsgi et ne 2 CGI et Python fera qu’appeler un autre module... Cela rend plus Comme n’importe quel langage polyvalent, Python peut être utilisé dans flexible l’implémentation le cadre de CGI. Notons toutefois que l’utilisation des CGI est déconseillée, de l’application pour le n’offrant de loin pas autant de possibilités que d’autres solutions. développeur Python. La configuration d’Apache est la même que pour Perl : Fichier ScriptAlias /cgi-bin/ /srv/www/cgi-bin/ AllowOverride None Options +ExecCGI -MultiViews Order allow,deny Allow from all

Et, de la même manière qu’avec Perl, un « Hello world » sera très simple : Fichier

C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 #!/usr/bin/env python print ‘’’Content-type: text/html

Hello world!

’’’

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 75 Programmer pour le web : Les possibilités offertes par Python 3 2.1 Le module cgi

Python propose lui aussi un module dédié aux CGI, mais celui-ci ne va pas aussi loin que celui de Perl. En effet, le module cgi de Python se contente de s’occuper de la manière dont les données sont transmises par le serveur au script. Ce module propose notamment une classe qui permet d’accéder facilement aux données entrées dans un formulaire. Cette classe s’utilise de la manière suivante : Fichier import cgi form = cgi.FieldStorage()

L’instance form contient alors les valeurs de l’ensemble des champs. Pour plus de détails, voir la documentation du module... Le module cgi propose également différentes fonctions, par exemple : → cgi.parse_multipart() : parseur pour les champs de type « multipart », notamment les fichiers téléversés ; → cgi.print_environ() : formate l’environnement sous forme de HTML (utile pour le débogage) ; → cgi.escape() : convertit les caractères sensibles (<, > et &) en HTML.

2.2 FastCGI

Python supporte également FastCGI, par le biais de modules externes à la distribution de base de Python. Nous n’allons pas approfondir cet aspect pour deux raisons : → plusieurs modules pour FastCGI sont proposés sur Internet, fonctionnant de manières différentes ; → cette solution n’est quasiment jamais utilisée, au profit de WSGI (voir plus bas).

Le module Python 3 pour Apache

à l’instar de mod_php pour le langage PHP, un module Apache existe pour le langage Python : mod_python. Ce module permet différentes méthodes d’utilisation, l’une d’entre elles étant l’intégration de code Python au sein d’une page HTML, comme avec PHP. Cependant, mod_python est plus puissant et permet de faire des choses plus poussées. Mais ce module a des inconvénients plutôt rédhibitoires. Tout d’abord, il « cache » les pages/scripts qu’il interprète ; cela signifie que le serveur HTTP Apache doit être redémarré (pour réinitialiser ce cache) à chaque changement d’un fichier. De plus, l’utilisation de

C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 ce greffon force Apache à démarrer une instance de Python pour chaque processus qu’il exécute, même si aucun code en Python ne sera exécuté. Si vous souhaitez quand même utiliser ou essayer ce module malgré ces inconvénients, vous pouvez l’installer avec la commande suivante : Terminal ~# apt-get install libapache2-mod-python

76 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe Programmer pour le web : Les possibilités offertes par Python

Références

4 WSGI HowTo « Utiliser Python dans le Web » : La solution à favoriser pour du développement web avec Python est WSGI (Web Server http://docs.python.org/2/ Gateway Interface). Cette interface, dont la première version a été définie en 2003, est howto/webservers.html à Python ce que sont les servlets pour Java : une interface unifiée permettant aux déve- CGI dans la documentation de loppeurs de ne pas se soucier du serveur qui sera utilisé pour desservir leur application. Python : http://docs.python. On pourrait écrire des dizaines de pages sur cette interface, mais gardons une approche org/2/library/cgi.html simple pour le moment (cela veut dire que nous ne verrons ici qu’une possibilité – la plus Site de mod_python : uniforme – parmi toutes celles qui s’offrent à nous). http://www.modpython.org/ Cette approche s’articule autour de deux parties : d’un côté une passerelle, spécifique à PEP définissant WSGI : chaque serveur web, qui permet au serveur de dialoguer avec du code fait pour WSGI, http://www.python.org/dev/ de l’autre côté une application qui dessert les pages web. peps/pep-0333/ Site de mod_wsgi : http://code.google.com/p/ 4.1 Passerelle modwsgi/

La passerelle WSGI pour Apache est le module mod_wsgi. Il est installable avec la commande suivante : Terminal ~# apt-get install libapache2-mod-wsgi

La configuration de ce module propose une trentaine de directives de configuration, permet- tant de paramétrer ses différents aspects. Voyons la configuration la plus simple possible : Fichier WSGIScriptAlias / /srv/www/wsgi

Cette directive indique un alias (comme la directive Alias d’Apache) tout en indiquant que les fichiers dans ce répertoire doivent être gérés comme des applications WSGI. Mais avec une telle configuration, il y a toujours un lien direct entre URL et fichiers. Pour éviter ce lien direct, on peut utiliser cette syntaxe : Fichier WSGIScriptAlias / /srv/www/wsgi/app.py

Avec cette configuration, Apache passera toutes les requêtes au script app.py, à lui ensuite de les différencier selon l’environnement qui lui sera passé.

4.2 Application

Une application WSGI doit contenir un objet exécutable (par exemple une classe ou une fonction) appelé application et qui accepte deux arguments : l’environnement et une fonction à exécuter pour initialiser la réponse. Toujours avec le même exemple de « Hello world », voici une application WSGI simple : C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 Fichier def application(environ, start_response): start_response(‘200 OK’, [(‘Content-type’, ‘text/html’)]) return ‘’’

Hello world!

’’’ ▪

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 77 Programmer pour le web : Python 3 proGrammer poUr Le web

rUby, UN LaNGaGe révéLé par soN

C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 framework

uby est un langage interprété et multi- paradigme, très fortement orienté objet, que l’on peut rapprocher de Python pour cela. Mais Ruby est surtout inspiré de Smalltalk (pour le paradigmeR objet) et d’Eiffel et Ada (pour la syntaxe).

78 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe Programmer pour le web : Ruby, un langage révélé par son framework

1 Histoire

En 1993, Yukihiro Matsumoto débute le développement du langage Ruby, dont il publie une première version (0.95) en 1995. Son objectif premier était de créer un langage de script orienté objet. La version 1.0 de Ruby est publiée un an plus tard, en décembre 1996. Ce langage de programmation est resté peu connu pendant longtemps, jusqu’à la publication d’une documentation en anglais et du framework web Ruby on Rails (également appelé RoR ou Rails) en 2004. La dernière version stable du langage Ruby est la 2.0.0, publiée en février 2013. Cette version reste rétro-compatible avec les séries précédentes.

(crédits : Meanos, via Wikimedia Commons) Ruby suit le principe de moindre surprise : il est conçu de telle sorte Yukihiro Matsumoto, que son comportement soit conforme à ce à quoi on s’attend, sans l’inventeur de Ruby « magie » apparente.

2 CGI

Encore une fois, un script en Ruby peut être utilisé comme script CGI. Mais l’émergence de ce langage étant assez tardive, cette utilisation reste marginale, pour ne pas dire inexistante. En effet, Ruby a vraiment décollé avec un framework web, qui va bien plus loin que de simples scripts CGI. La configuration d’Apache est la même que pour Perl et Python : Fichier ScriptAlias /cgi-bin/ /srv/www/cgi-bin/ AllowOverride None Options +ExecCGI -MultiViews Order allow,deny Allow from all

Et, de la même manière qu’avec ces deux langages, un « Hello world » sera très simple : Fichier #!/usr/bin/ruby puts «Content-type: text/html

Hello world!

» C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5

2.1 La classe CGI

Malgré une faible utilisation sous la forme de scripts CGI, Ruby propose une classe pour gérer les spécificités de l’appel de script par CGI. Plus proche du module Perl que du module Python, elle permet de générer du code HTML sans jamais avoir à en taper.

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 79 Programmer pour le web : Ruby, un langage révélé par son framework

3 Un « Hello world » en utilisant cette classe peut être le suivant : Fichier require «cgi» cgi = CGI.new(«html4») cgi.out() do cgi.html() do cgi.body() do cgi.h1() do «Hello world!» end end end end

2.2 FastCGI

Comme pour Python, plusieurs bibliothèques Ruby externes existent pour le support de FastCGI. Prenons pour exemple la bibliothèque fcgi. Un « Hello world » avec cette bibliothèque serait le suivant : Fichier Définition FCGI.each {|request| Un framework est un out = request.out ensemble logiciel offrant out.print «Content-type: text/html au développeur web un environnement de développement avancé, automatisant notamment

Hello world!

certaines parties du » traitement des requêtes : request.finish patron Module-Vue- } Contrôleur, routage des requêtes vers telle ou telle vue, présentation des données SQL sous forme d’objets auto-gérés, etc. Avec ces outils, un développeur web n’a 3 plus à se soucier de la manière dont les requêtes Tout comme pour les autres langages, un module Ruby existe pour le lui parviennent, ni de la serveur HTTP Apache. Ce module, d’abord connu comme mod_rails, méthode utilisée pour s’appelle Passenger et est développé par la société Phusion. C’est stocker ses données : il d’ailleurs en réalité bien plus qu’un module pour Apache : il s’agit d’un peut se concentrer sur produit fonctionnant aussi bien avec Apache qu’avec Nginx, ou même l’application web elle- tout seul, il sait également desservir des pages web en HTTP. même. Pour installer le module Phusion Passenger pour Apache, la commande est la suivante : Terminal ~# apt-get install libapache2-mod-passenger C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5

Ce module nécessite quelques prérequis, en termes de fichiers et répertoires. Nous allons donc créer une arborescence correspondant à ces prérequis, dans /srv/www/ruby, avec les répertoires suivants : → /srv/www/ruby/helloworld → /srv/www/ruby/helloworld/public → /srv/www/ruby/helloworld/tmp

80 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe Programmer pour le web : Ruby, un langage révélé par son framework

Notre « Hello world » ci-dessous est ensuite placé dans le fichier /srv/www/ruby/helloworld/config.ru : Fichier app = proc do |env| [200, { «Content-Type» => «text/html» }, [«

Hello world!

»]] end run app

La configuration d’Apache pour pouvoir desservir ce « Hello world » est plutôt simple, le module se chargeant de tout : Fichier DocumentRoot /srv/www/ruby/helloworld/public

Choisir l’une de 4 ces solutions

Ruby est un langage récent ; en tout cas, récemment diffusé à large échelle. Bien sûr, il est tout à fait possible d’utiliser ce langage avec des scripts CGI, comme tous les autres langages de programmation : oui, on peut faire des CGI en C, ou même en assembleur si on est courageux ! Cependant, il faut placer les choses dans leur contexte. Nous sommes à une ère où plus aucun développement web sérieux ne se fait sous la forme de scripts CGI. On peut bien sûr retrouver des scripts CGI sur d’anciens serveurs, ceux-ci seront d’ailleurs le plus souvent programmés en Perl. Mais aujourd’hui, tout développement web ambitieux s’appuie sur un framework. Des frameworks, il en existe beaucoup, mais en Ruby le plus connu reste Ruby on Rails (également surnommé Rails) ; rendons à César ce qui est à César : c’est surtout grâce à Rails que Ruby est connu ! Un développeur web ne devrait donc plus se soucier de la manière dont son code est desservi : il va programmer pour un framework particulier, c’est ensuite à l’administrateur système de s’arranger pour desservir correctement ce framework, le plus souvent par l’intermédiaire d’un module comme Passenger, que nous venons d’aborder. Bien sûr, ce raisonnement s’applique à tous les langages. Mais il reste encore plus important avec Ruby, étant donné que la notoriété de ce langage est venue par l’intermédiaire d’un framework... Ruby sera à choisir uniquement si cela se justifie : si vous connaissez parfaitement ce langage, ou si vous utilisez un outil qui est basé dessus – notamment Ruby on Rails, Redmine, etc. En effet, historiquement ce langage est plus discret que les « poids lourds » que sont PHP, Perl et Python. Cela n'en fait pas un sous-langage, loin de là ; mais la réalité du marché fait que ce langage reste fortement lié à Ruby on Rails : aucun autre environnement fortement diffusé ne s'appuie sur ce langage. ▪ C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 Références Site de la communauté Ruby francophone : http://www.ruby-lang.org/fr/ CGI dans la documentation de Ruby : http://www.ruby-doc.org/stdlib-1.9.3/libdoc/cgi/rdoc/CGI.html Bibliothèque fcgi : https://github.com/saks/ruby-fcgi Site de Passenger : https://www.phusionpassenger.com/

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 81 4 C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5

82 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe aLLer pLUs LoiN 4 à découvrir dans cette partie... page 84 Authentification avec LDAP Lorsque l'on met en place une infrastructure d'entreprise, il devient inenvisageable de gérer une base d'authentification pour chaque site ou section à sécuriser. C'est là que LDAP entre en jeu.

page 102 Chiffrement et authentification SSL Les données confidentielles, on ne veut les partager qu'avec des personnes précises, on veut également que personne ne puisse les intercepter lors de leur transmission. SSL est le protocole idéal pour cela ! C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 83 Programmer pour le web : Ruby 4 aLLer pLUs LoiN

aUtHeNtificatioN avec Ldap

pache est presque un standard lorsqu’il s’agit de choisir un serveur HTTP, comme l’est sans doute MySQL pour les bases de données, PHP pour le développement d’applications web C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 ouA encore GNU/Linux pour les serveurs de manière générale. OpenLDAP s’inscrit également dans cette catégorie des incontournables de l’open source. Le couple Apache + OpenLDAP peut former une émulsion intéressante, comme c’est le cas pour LAMP. Petite introduction au sujet et tour d’horizon des bénéfices.

84 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe Aller plus loin : authentification avec LDAP

1 Rappel sur LDAP

LDAP, pour Lightweight Directory Access Protocol, est un protocole d’interrogation et de modification de services d’annuaire. Reposant sur TCP/IP, il est devenu une norme complète et un standard pour les systèmes d’annuaire (modèles de données et de nommage, modèle fonctionnel LDAP, modèle de sécurité, etc.). Un annuaire LDAP est une structure arborescente dont chacun des nœuds est constitué d’attributs associés à des valeurs. L’une des implémentations les plus utilisées de cette norme est OpenLDAP. C’est un logiciel libre diffusé sous sa propre licence, l’OpenLDAP Public License. C’est la base qui nous servira d’expérimentation ici, sur une distribution Debian GNU/Linux. Avec LDAP, un annuaire est présenté sous la forme d’un arbre où chaque composant (racine, branches, feuilles) est destiné à représenter le modèle organisationnel d’une structure.

1.1 Nommage des composants

Chaque composant de l’arbre est identifié par un DN (distinguished name). En faisant l’analogie avec les systèmes de fichiers, le DN est le chemin absolu d’un répertoire ou d’un fichier. On peut également parler de RDN (relative distinguished name), le nom relatif du constituant (relatif à son parent, dans le cas de LDAP). à la racine de l’arbre et aux premières branches, on trouvera des composants de domaine (dc, domain components). Les branches intermédiaires de l’arbre sont des unités organisationnelles (ou, organizational units). Les feuilles, quant à elles, sont les données n’ayant pas d’« enfant » : les ordinateurs, les utilisateurs, etc. ; on les identifie par un cn (common name). En général, les premières branches reproduisent le domaine de l’entreprise concernée, tel que l’on peut le retrouver sur Internet. L’organisation des branches intermédiaires dépend entièrement des besoins de l’entreprise, il n’y a pas de normalisation à ce niveau-là. Par exemple, pour une société qui s’appellerait « Éditions Diamond », un arbre pourrait être décrit par le schéma ci-dessous :

dc=com

dc=ed-diamond

ou=lieux ou=utilisateurs

l=Selestat uid=denis uid=fleur C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5

Exemple d’arbre LDAP

Dans cet exemple, on a 7 composants (objets), dont voici les DN complets : → dn: dc=com, la racine de l’arbre ; → dn: dc=ed-diamond,dc=com, la branche principale de l’entreprise ;

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 85 Aller plus loin : authentification avec LDAP

4 → dn: ou=lieux,dc=ed-diamond,dc=com, la branche contenant les définitions de lieux et adresses ; → dn: ou=utilisateurs,dc=ed-diamond,dc=com, la branche contenant les définitions des utilisateurs ; → dn: l=Selestat,ou=lieux,dc=ed-diamond,dc=com, une adresse ; → dn: uid=denis,ou=utilisateurs,dc=ed-diamond,dc=com, un utilisateur ; → dn: uid=fleur,ou=utilisateurs,dc=ed-diamond,dc=com, une utilisatrice. On remarque que c’est l’assemblage des noms relatifs de l’ensemble des objets, séparés par des virgules, qui constitue les noms complets et uniques de chacun des objets. à retenir Notons également qu’il n’est pas nécessaire d’avoir une racine en dc=com, dc=fr ou autre : la racine peut tout à fait être dc=ed-diamond, c’est Exemple et vie réelle sur cette base-là que l’on partira ci-après. Nous voyons ici un exemple, dont la complexité n’est pas nécessairement utile dans tous les cas. Par 1.2 Schémas et attributs exemple, s’il s’agit juste à chaque objet sont associés des attributs, qui contiennent des d’identifier des utilisateurs données particulières ; il s’agit d’une base de données, mais celle-ci est sans hiérarchie, il n’est pas utile de mettre en place des hiérarchique et non relationnelle. unités organisationnelles, Le nommage des informations contenues dans une base LDAP est on peut très bien ajouter fortement normé. La manière de placer les données dans une base un utilisateur directement LDAP est définie par des schémas, qui régissent les types d’attributs sous la racine. que l’annuaire peut contenir. Un certain nombre de ces schémas sont normalisés et communs à toutes les implémentations de LDAP. Cela permet de disposer d’un format commun, facilitant l’interopérabilité entre les systèmes, les applications et les implémentations de LDAP. On peut également définir de nouveaux schémas en partant de zéro, ou utiliser les schémas existants et les étendre avec ses propres attributs. Cependant, les schémas standards couvrent déjà bon nombre d’usages et des schémas complémentaires ne sont nécessaires que dans certains cas particuliers (pour de l’authentification Samba en base LDAP par exemple). Parmi les attributs d’un objet, on trouvera obligatoirement un ou plusieurs attributs objectClass, ainsi qu’un attribut qui répète le nom relatif. Le contenu d’une base (d’un arbre) LDAP peut être représenté sous forme textuel, dans un format qu’on appelle LDIF. Pour les objets de notre exemple (en prenant dc=ed-diamond comme racine), un LDIF minimal pourrait être le suivant : Fichier

C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 dn: dc=ed-diamond objectClass: dcObject dc: ed-diamond

dn: ou=lieux,dc=ed-diamond objectClass: organizationalUnit ou: lieux

86 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe Aller plus loin : authentification avec LDAP

Fichier dn: ou=utilisateurs,dc=ed-diamond objectClass: organizationalUnit ou: utilisateurs

dn: l=Selestat,ou=lieux,dc=ed-diamond objectClass: locality l: Selestat

dn: uid=denis,ou=utilisateurs,dc=ed-diamond objectClass: inetOrgPerson uid: denis

dn: uid=fleur,ou=utilisateurs,dc=ed-diamond objectClass: inetOrgPerson uid: fleur

Nous verrons plus loin qu’en réalité, ces données ne sont pas suffisantes ; à retenir par exemple, la classe person (dont hérite inetOrgPerson – nous verrons l’héritage ci-après) rend les attributs sn (surname) et cn (common Configuration en name) obligatoire. base Notons qu’un LDIF peut également contenir des instructions afin de Auparavant, la modifier les entrées existantes (modifier, supprimer ou ajouter des configuration d’OpenLDAP objets, en réalité). C’est par l’intermédiaire d’un fichier LDIF qu’on peut se faisait dans le fichier manuellement modifier une base LDAP. /etc/ldap/slapd.conf ; depuis la version 2.4.23-3 d’OpenLDAP, cette configuration a été déplacée dans slapd.d. L’intérêt de ce déplacement est que les modifications à la configuration sont prises 2 OpenLDAP en compte sans avoir besoin de redémarrer le serveur Restons-en là pour les aspects théoriques, il ne s’agit que d’un rappel OpenLDAP. sur LDAP et non d’un article dédié (d’ailleurs, des livres entiers existent Attention : ne modifiez dédiés à LDAP, on ne peut pas prétendre faire plus qu’effleurer le sujet en pas les fichiers dans quelques pages). Il en est d’ailleurs de même dans l’article qui commence /etc/ldap/slapd.d maintenant : on ne va faire qu’effleurer le sujet OpenLDAP, ce protocole manuellement ! et ce logiciel étant des sujets très complets et parfois très complexes, avec lesquels il est possible de réaliser des merveilles (mais aussi des horreurs)...

2.1 Installation

L’installation d’OpenLDAP sous Debian ou Ubuntu est relativement simple, puisqu’elle consiste simplement en l’installation de deux paquets, slapd (le serveur OpenLDAP lui-même) et ldap-utils (les outils en ligne de commandes permettant de manipuler l’annuaire) : Terminal C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 ~# apt-get install slapd ldap-utils

L’installateur du serveur demande le mot de passe de l’administrateur de l’annuaire LDAP ; ce mot de passe peut être différent du mot de passe de l’utilisateur root : il s’agit ici de définir un mot de passe pour sécuriser la base LDAP.

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 87 Aller plus loin : authentification avec LDAP

4 La configuration du serveur OpenLDAP est stockée dans le répertoire /etc/ldap/slapd.d/ sous forme de nombreux fichiers LDIF. Sa manipulation se fait par l’intermédiaire du protocole LDAP, de la même manière qu’une modification du contenu de la base elle-même. On peut voir son contenu avec la commande suivante : Terminal ~# slapcat -b cn=config

La commande slapcat accède directement aux données stockées, sans utiliser le serveur LDAP en place : il est de manière générale plus propre (mais moins simple à taper) d’utiliser la commande ldapsearch : Terminal ~# ldapsearch -Y EXTERNAL -H ldapi:/// -b cn=config

Cette commande est décomposée comme suit : → -Y EXTERNAL précise que SASL doit utiliser la méthode d’authentification « external » (l’identité est validée car on est l’utilisateur root, sans avoir besoin de mot de passe) ; → -H ldapi:// précise que le serveur LDAP doit être joint par un socket Unix et non par le réseau ; → -b cn=config précise que la base à interroger est celle de la configuration.

Notons qu’il n’est pas possible, avec la configuration par défaut, d’interroger ou de modifier cette base à distance, car cette méthode d’authentification n’est faisable que pour des utilisateurs connectés localement. Il est toutefois possible (mais déconseillé, car cela serait une potentielle faille de sécurité !) de créer un utilisateur dont le mot de passe serait connu et qui pourrait interroger la base à distance.

2.2 Communiquer avec OpenLDAP

Comme nous l’avons évoqué plus haut, la manipulation des données dans un annuaire LDAP par un utilisateur passe généralement par le format LDIF (LDAP Data Interchange Format). Ce format permet de représenter les données de l’annuaire comme vu précédemment, mais également les manipulations concernant ces données. La méthode la plus simple pour comprendre le format et son utilisation est de procéder par l’exemple.

2.2.1 Contenu par défaut

Pour l’heure, en dehors de sa configuration, notre annuaire ne contient pas grand- chose. Pour être précis, il contient une seule arborescence dont la racine est dc=nodomain, avec un seul utilisateur « admin » : Terminal ~# ldapsearch -D cn=admin,dc=nodomain -b dc=nodomain -W -LLL Enter LDAP Password: C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 dn: dc=nodomain objectClass: top objectClass: dcObject objectClass: organization o: nodomain dc: nodomain

88 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe Aller plus loin : authentification avec LDAP

Terminal dn: cn=admin,dc=nodomain objectClass: simpleSecurityObject objectClass: organizationalRole cn: admin description: LDAP administrator userPassword:: e4DTSEF9SjVTVGRpcLs4bzJTRCtTTU9pTG54REpKNFNVdTdVaZU=

Ici, les arguments de la commande ldapsearch sont les suivants : → -D cn=admin,dc=nodomain : cet argument précise l’identifiant à utiliser pour se connecter (on parle de « bind DN ») ; → -b dc=nodomain : cet argument indique l’arborescence à interroger ; → -W : cet argument force ldapsearch à demander le mot de passe de l’utilisateur ; → -LLL : cet argument permet de réduire la verbosité de la sortie de la commande.

Ces deux éléments (objets) ont été créés par le processus d’installation du paquet Debian. Nous avons d’une part le nœud identifié par le DN dc=nodomain, qui est la racine de l’arbre, la base de l’annuaire. Nous avons d’autre part l’utilisateur identifié par le DN cn=admin,dc=nodomain. Chacun de ces éléments comprend des attributs provenant des classes d’objets qui le définissent. à l’instar de la programmation orientée objet, LDAP utilise des classes regroupant des attributs pour instancier des objets. Si vous souhaitez des attributs à une entrée de l’annuaire, vous ajoutez donc une classe à l’objet. Notre utilisateur « admin » possède des attributs provenant des classes simpleSecurityObject et organizationalRole. Certains des attributs sont d’ores et déjà initialisés avec des valeurs comme la description de l’utilisateur (description) ou son mot de passe chiffré (userPassword). Par ailleurs, nous retrouvons la définition de cette base de données dans la configuration d’OpenLDAP : Terminal ~# ldapsearch -Y EXTERNAL -H ldapi:/// -b cn=config -LLL ‘(&(objectClass= olcDatabaseConfig)(olcSuffix=dc=nodomain))’ SASL/EXTERNAL authentication started SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth SASL SSF: 0 dn: olcDatabase={1}hdb,cn=config objectClass: olcDatabaseConfig objectClass: olcHdbConfig olcDatabase: {1}hdb olcDbDirectory: /var/lib/ldap olcSuffix: dc=nodomain olcAccess: {0}to attrs=userPassword,shadowLastChange by self write by anonymou s auth by dn=»cn=admin,dc=nodomain» write by * none olcAccess: {1}to dn.base=»» by * read olcAccess: {2}to * by self write by dn=»cn=admin,dc=nodomain» write by * read olcLastMod: TRUE olcRootDN: cn=admin,dc=nodomain C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 olcRootPW: {SSHA}M2STdrqk8o4Pd+NMOiLnyDJKXSUuYNie olcDbCheckpoint: 512 30 olcDbConfig: {0}set_cachesize 0 2097152 0 olcDbConfig: {1}set_lk_max_objects 1500 olcDbConfig: {2}set_lk_max_locks 1500 olcDbConfig: {3}set_lk_max_lockers 1500 olcDbIndex: objectClass eq

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 89 Aller plus loin : authentification avec LDAP 4 Cette fois-ci, en plus des arguments que l’on a vus plus haut, on ajoute à la commande ldapsearch un filtre, qui précise que nous ne recherchons que des objets ayant la classe olcDatabaseClass et dont l’attribut olcSuffix est égal à dc=nodomain.

2.2.2 Créer une base

En nous inspirant de la base existante, nous allons créer un fichier LDIF définissant une nouvelle base de données : Fichier dn: olcDatabase={2}hdb,cn=config objectClass: olcDatabaseConfig objectClass: olcHdbConfig olcDatabase: {2}hdb olcDbDirectory: /srv/ldap/ed-diamond olcSuffix: dc=ed-diamond olcAccess: {0}to attrs=userPassword,shadowLastChange by self write by anonymous auth by dn=»cn=admin,dc=ed-diamond» write by * none olcAccess: {1}to dn.base=»» by * read olcAccess: {2}to * by self write by dn=»cn=admin,dc=ed-diamond» write by * read olcRootDN: cn=admin,dc=ed-diamond olcRootPW: {SSHA}M2STdrqk8o4Pd+NMOiLnyDJKXSUuYNie

Cette base est ensuite créée avec la commande ldapadd : Terminal ~# mkdir -p /srv/ldap/ed-diamond ~# chown openldap.openldap /srv/ldap/ed-diamond ~# ldapadd -Y EXTERNAL -H ldapi:/// -b cn=config -f /tmp/base-eddiamond.ldif

Une fois la base créée, il lui faut un contenu. Commençons par créer la racine, avec le fichier LDIF suivant : Fichier dn: dc=ed-diamond objectClass: top objectClass: dcObject objectClass: organization o: ed-diamond dc: ed-diamond

Pour insérer ces données dans la base, utilisons encore une fois ldapadd, mais cette fois-ci en pointant sur notre nouvelle base et non la configuration d’OpenLDAP : Terminal ~# ldapadd -D cn=admin,dc=ed-diamond -W -f /tmp/eddiamond-root.ldif C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5

On notera que la commande ldapadd n’accepte pas l’argument -b dc=ed-diamond : elle déduit la base à laquelle se connecter du contenu du fichier LDIF. Si l’on interroge cette base, on constatera qu’en effet, la racine est créée :

90 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe Aller plus loin : authentification avec LDAP

Terminal ~# ldapsearch -D cn=admin,dc=ed-diamond -b dc=ed-diamond -W -LLL Enter LDAP Password: dn: dc=ed-diamond objectClass: top objectClass: dcObject objectClass: organization o: Editions Diamond dc: ed-diamond

2.2.3 Création d’entrées

Nous allons ensuite créer les deux unités organisationnelles, les deux PC et les deux utilisateurs, conformément à notre exemple... Fichier dn: ou=lieux,dc=ed-diamond objectClass: organizationalUnit ou: lieu

dn: ou=utilisateurs,dc=ed-diamond objectClass: organizationalUnit ou: utilisateurs

dn: l=Selestat,ou=lieux,dc=ed-diamond objectClass: locality l: Selestat

dn: uid=denis,ou=utilisateurs,dc=ed-diamond objectClass: inetOrgPerson uid: denis cn: Denis Bodor givenName: Denis sn: Bodor

Fichier dn: uid=fleur,ou=utilisateurs,dc=ed-diamond objectClass: inetOrgPerson uid: fleur cn: Fleur Brosseau givenName: Fleur sn: Brosseau

Une fois ce fichier LDIF ajouté avec ldapadd de la même manière que pour la racine de l’arbre, la base de données est bien conforme à ce que l’on attend : Terminal ~# ldapsearch -D cn=admin,dc=ed-diamond -b dc=ed-diamond -W -LLL

C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 Enter LDAP Password: dn: dc=ed-diamond objectClass: top objectClass: dcObject objectClass: organization dc: ed-diamond o: Editions Diamond

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 91 Aller plus loin : authentification avec LDAP

4 Terminal dn: ou=utilisateurs,dc=ed-diamond objectClass: organizationalUnit ou: utilisateurs

dn: ou=lieux,dc=ed-diamond objectClass: organizationalUnit ou: lieux

dn: l=Selestat,ou=lieux,dc=ed-diamond objectClass: locality l: Selestat

dn: uid=denis,ou=utilisateurs,dc=ed-diamond objectClass: inetOrgPerson uid: denis cn: Denis Bodor givenName: Denis sn: Bodor

dn: uid=fleur,ou=utilisateurs,dc=ed-diamond objectClass: inetOrgPerson uid: fleur cn: Fleur Brosseau givenName: Fleur sn: Brosseau

En mettant en regard les données que l’on a insérées dans l’annuaire et les schémas installés, nous constatons que les attributs de la classe inetOrgPerson dépendent de ses parents successifs, organizationalPerson, person et top. Nous n’avons précisé que la classe la plus « complète », mais il est généralement recommandé d’indiquer toutes les classes. En effet, bien que le serveur OpenLDAP soit en mesure de recomposer la hiérarchie et de vérifier l’existence des classes dans les schémas à sa disposition, il est préférable de lui éviter ce travail pour des raisons de performance, mais également de compatibilité. OpenLDAP procède à ce parcours hiérarchique, mais ce n’est pas le cas de tous les serveurs LDAP du marché ! De ce fait, comme l’exportation LDIF de l’annuaire produira un fichier similaire à celui que nous avons utilisé, son importation dans un autre serveur LDAP nécessitera le support de ce parcours hiérarchique. Cela n’est plus un problème si toutes les classes en jeu sont spécifiées. Notons également qu’on aurait pu choisir d’autres attributs pour le DN. On aurait par exemple pu avoir dn: sn=Bodor,ou=utilisateurs, dc=ed-diamond. Mais cela pourrait poser problème, car dans ce cas, le nom de famille doit être unique parmi l’ensemble des utilisateurs... C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 2.2.4 Modification d’entrées

Nous allons donc corriger cette maladresse et, par la même occasion, découvrir comment apporter des modifications à notre annuaire. Commençons par créer un fichier LDIF pour ajouter les classes que nous n’avons pas incluses jusqu’ici :

92 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe Aller plus loin : authentification avec LDAP

Fichier dn: uid=denis,ou=utilisateurs,dc=ed-diamond add: objectClass objectClass: organizationalPerson - add: objectClass objectClass: person - add: objectClass objectClass: top

dn: uid=fleur,ou=utilisateurs,dc=ed-diamond add: objectClass objectClass: organizationalPerson - add: objectClass objectClass: person - add: objectClass objectClass: top

Pour prendre en compte ce fichier LDIF, il faut utiliser la commande ldapmodify ; celle-ci prend des arguments similaires à ceux de ldapadd : Terminal ~# ldapmodify -D cn=admin,dc=ed-diamond -W -f /tmp/eddiamond-modify.ldif

En plus de l’instruction add, nous pouvons utiliser replace pour changer une valeur ou delete pour effacer un attribut. On notera également qu’une ligne ne contenant qu’un simple tiret - doit être insérée entre deux instructions de modification – s’il n’y a qu’une seule instruction de modification pour un élément, ce tiret est inutile. Si nous voulions supprimer l’utilisateur denis par exemple, c’est la commande ldapdelete qu’il faudrait utiliser : Terminal ~# ldapdelete -D cn=admin,dc=ed-diamond -W uid=denis,ou=utilisateurs,dc=ed-diamond

2.2.5 Mots de passe

Mais nous avons oublié de définir des mots de passe ! Notre base va servir à authentifier des utilisateurs, il leur faut donc des mots de passe... Ajoutons donc l’attribut userPassword : Fichier

C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 dn: uid=denis,ou=utilisateurs,dc=ed-diamond add: userPassword userPassword: coucou

dn: uid=fleur,ou=utilisateurs,dc=ed-diamond add: userPassword userPassword: hibou

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 93 Aller plus loin : authentification avec LDAP

4 Après avoir exécuté ldapmodify sur ce nouveau fichier LDIF, la base contient bien les mots de passe : Terminal ~# ldapsearch -D cn=admin,dc=ed-diamond -b dc=ed-diamond -W -LLL objectClass=inetOrgPerson Enter LDAP Password: dn: uid=denis,ou=utilisateurs,dc=ed-diamond objectClass: inetOrgPerson objectClass: organizationalPerson objectClass: person objectClass: top uid: denis cn: Denis Bodor givenName: Denis sn: Bodor userPassword:: Y291Y291

dn: uid=fleur,ou=utilisateurs,dc=ed-diamond objectClass: inetOrgPerson objectClass: organizationalPerson objectClass: person objectClass: top uid: fleur cn: Fleur Brosseau givenName: Fleur sn: Brosseau userPassword:: aGlib3U=

La suite de deux « double-points » indique que la valeur est codée en Base64. C’est automatiquement le cas pour des mots de passe, c’est également le cas quand un nom contient un accent, par exemple.

Par contre, il ne s’agit là bien que de codage en Base64, les mots de passe ne sont pas chiffrés. La preuve : Terminal ~# python -c «import base64; print base64. decodestring(‘Y291Y291’), base64.decodestring(‘aGlib3U=’)» coucou hibou

Un principe de base en sécurité étant qu’un mot de passe ne doit pas être stocké en clair, nous allons devoir chiffrer ce mot de passe. Pour ce faire, inspirons-nous du champ olcRootPW que l’on retrouve dans la configuration : il contient un hashé SHA1 du mot de passe de l’administrateur et non un texte en clair. Le format est le suivant :

→ En premier, on place le nom de l’algorithme de hashage entre accolades,

→ ensuite, le digest codé en Base64.

Le one-liner Python suivant permet de générer une telle ligne : C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 Fichier import base64, hashlib; sha = hashlib.sha1(); sha.update(‘’); print ‘{SHA}%s’ % base64.encodestring(sha.digest())

Les commandes suivantes permettent donc d’obtenir ces mots de passe hashés :

94 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe Aller plus loin : authentification avec LDAP

Terminal ~# python -c «import base64, hashlib; sha = hashlib.sha1(); sha. update(‘coucou’); print ‘{SHA}%s’ % base64.encodestring(sha.digest())» {SHA}XtJa97HtI/sAEi4T1/dMTYJirNg=

~# python -c «import base64, hashlib; sha = hashlib.sha1(); sha.update(‘hibou’); print ‘{SHA}%s’ % base64. encodestring(sha.digest())» {SHA}oyKmotvlPy766Byd4V+dWwJlVwo=

On peut donc maintenant modifier les lignes des mots de passe, afin de ne pas les stocker en clair : Fichier dn: uid=denis,ou=utilisateurs,dc=ed-diamond replace: userPassword userPassword: {SHA}XtJa97HtI/sAEi4T1/dMTYJirNg=

dn: uid=fleur,ou=utilisateurs,dc=ed-diamond replace: userPassword userPassword: {SHA}oyKmotvlPy766Byd4V+dWwJlVwo=

La vérification du bon fonctionnement est assez simple : en effet, lors de la définition de la base dans la configuration, nous avons mis en place une possibilité de consultation de la part de tous les utilisateurs définis dans la base. Il suffit donc de se connecter avec l’un de ces utilisateurs : Terminal ~# ldapsearch -D uid=denis,ou=utilisateurs,dc=ed-diamond -b dc=ed-diamond -W -LLL objectClass=inetOrgPerson Enter LDAP Password: dn: uid=denis,ou=utilisateurs,dc=ed-diamond objectClass: inetOrgPerson objectClass: organizationalPerson objectClass: person objectClass: top uid: denis cn: Denis Bodor givenName: Denis sn: Bodor userPassword:: e1NIQX1YdEphOTdIdEkvc0FFaTRUMS9kTVRZSmlyTmc9 dn: uid=fleur,ou=utilisateurs,dc=ed-diamond objectClass: inetOrgPerson objectClass: organizationalPerson objectClass: person objectClass: top uid: fleur cn: Fleur Brosseau givenName: Fleur sn: Brosseau C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 Avec le mot de passe coucou, cette commande fonctionne ! On remarque deux choses : → On s’est connecté en donnant le DN de l’utilisateur denis comme bind DN ; → Un utilisateur normal n’a pas le droit de voir l’attribut userPassword des autres utilisateurs – c’est également une chose que l’on a définie lors de la création de la base de données.

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 95 Aller plus loin : authentification avec LDAP 4 2.2.6 Connexion distante

Jusqu’ici, nous nous sommes connectés au serveur OpenLDAP local, mais il est tout à fait possible de se connecter à distance, car OpenLDAP « écoute » sur le port stan- dard LDAP, TCP 389.

Luma, en mode d’édition de base

Luma, en mode de visualisation des schémas

Les commandes ldapsearch, ldapadd, ldapmodify et ldapdelete C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 acceptent l’argument -H qui permet de définir l’hôte sur lequel se connecter, sous la forme ldap://:, où la mention du port est optionnelle. Terminal ~# ldapsearch -D uid=denis,ou=utilisateurs, dc=ed-diamond -b dc=ed-diamond -W -LLL -H ldap://glmf-hs-66 objectClass=inetOrgPerson

96 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe Aller plus loin : authentification avec LDAP

Il existe également des interfaces graphiques permettant de gérer des bases LDAP. L’une des plus simples, disponible dans les dépôts de Debian et Ubuntu, est Luma : Terminal ~# apt-get install luma

2.2.7 Utilité réelle

Nous l’avons dit plus haut, LDAP est un annuaire. En cela, il permet de stocker presque n’importe quelles informations, celles-ci pouvant être organisées sous la forme d’une arborescence hiérarchisée. Les comptes utilisateurs entrent parfaitement dans cette catégorie et les à retenir avantages de cette solution sont nombreux. Imaginez un instant votre infrastructure sous un angle nouveau, avec une centralisation complète Utilisateur de des informations sur les utilisateurs : les comptes e-mails, les comptes connexion FTP, les accès aux services web, les permissions sur les partages Samba, Dans notre exemple, nous etc. Ajouter un utilisateur dans une vaste collection de services devient allons voir comment configurer Apache pour l’affaire d’un simple fichier LDIF (voire du remplissage d’un formulaire en lire le contenu de la base ligne) ; idem pour la suppression, la modification ou les changements de LDAP avec l’utilisateur droits et de permissions sur une ressource. administrateur. Cela est Un gros investissement en temps pour un gain remarquable et une bien sûr déconseillé dans la garantie de pérennité car c’est un standard, voilà ce qu’est LDAP ! vie réelle ! Il est préférable de créer un utilisateur spécifique pour les connexions depuis Apache et de limiter ses droits. Rappelons-nous également que tout utilisateur présent dans la base LDAP 3 LDAP et Apache pourra lire le contenu de la base LDAP. Autrement Pourquoi ne pas commencer cette centralisation par l’authentification dit, tout utilisateur ayant accès à notre application HTTP d’Apache en lieu et place de la simple méthode reposant sur un web par Apache pourra fichier « plat » ? lire le contenu de la base Traditionnellement, les données d’authentification sont stockées dans les LDAP. Cette approche attributs uid (pour le nom d’utilisateur) et userPasswd (pour le mot de reste nécessaire pour l’authentification avec passe) : bizarrement, nous les avons tous deux déjà définis :-) ! En réalité, Apache, mais il serait on peut utiliser l’attribut que l’on veut pour identifier un utilisateur, c’est judicieux de filtrer les la configuration d’Apache qu’on adaptera pour correspondre à ce qu’on connexions à la base LDAP... aura choisi... Mais uid est là pour ça, utilisons-le. L’authentification LDAP du serveur HTTP Apache passe par un module qui est installé par défaut avec le paquet standard d’Apache pour Debian et Ubuntu, c’est mod_authnz_ldap. Pour le mettre en œuvre, il suffit

C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 de l’activer et de redémarrer le serveur : Terminal ~# a2enmod authnz_ldap ~# /etc/init.d/apache2 restart

Tout se passe ensuite dans la configuration de l’hôte virtuel sur lequel mettre en place une authentification.

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 97 Aller plus loin : authentification avec LDAP 4 Le processus d’authentification est dit search/bind, car il opère en deux temps. Le module va tout d’abord se connecter avec un DN particulier pour procéder à une recherche sur la base du nom d’utilisateur fourni dans la requête du client web. Si la recherche retourne une entrée unique, une tentative de connexion à l’annuaire est faite avec le DN correspondant et le mot de passe fourni par l’utilisateur distant.

Deux éléments sont importants dans ce mécanisme. Premièrement, il faut que la phase de recherche ne retourne qu’une seule entrée ; en cas de réponse multiple, l’authentification échoue ; si par exemple l’authentification se fait sur le champ givenName, deux personnes ayant le même prénom conduiront à une réponse double, le système ne saura pas auquel il a affaire et fait échouer la connexion. Deuxièmement, ce n’est pas le nom d’utilisateur qui est utilisé pour se connecter à l’annuaire, mais le DN remonté par la première phase de recherche.

Voilà à quoi peut ressembler un bloc permettant de contrôler l’accès au répertoire /prive d’un site qui serait dans l’arborescence /srv/www/ mon_joli_site : Fichier AuthType basic AuthName «Zone privee» AuthBasicProvider ldap AuthLDAPBindDN «cn=admin,dc=ed-diamond» AuthLDAPBindPassword «mot_de_passe» AuthLDAPUrl «ldap://127.0.0.1/dc=ed-diamond?uid» Require valid-user

On retrouve les directives que nous avons déjà rencontrées précédemment : AuthType pour le type d’authentification côté HTTP, AuthName pour le nom de la zone protégée (royaume), AuthBasicProvider pour définir le module d’authentification à utiliser côté back-end et Require pour définir les autorisations.

Comme notre annuaire n’est pas consultable de manière anonyme, nous précisons avec AuthLDAPBindDN et AuthLDAPBindPassword un DN de connexion pour consultation de la base et le mot de passe associé. Notons que cet utilisateur n’a pas besoin de lire les attributs userPassword ; il a uniquement besoin d’accéder au DN de chacun des utilisateurs et à l’attribut qui correspond à l’authentification (uid généralement).

La directive AuthLDAPUrl permet de définir la cible des requêtes. L’argument à cette directive prend la forme suivante : Fichier

C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 ldap://:/???

où :

est remplacé par l’adresse ou le nom d’hôte du serveur LDAP ;

, facultatif, indique le port auquel se connecter (par défaut, 389) ;

98 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe Aller plus loin : authentification avec LDAP

indique le DN de la racine de la base à interroger ; → , facultatif, indique l’attribut à interroger (par défaut, uid – cela signifie que, dans notre exemple, nous aurions pu nous en passer) ; → , facultatif, est la portée de la recherche : one pour rechercher à un seul niveau (pas de recherche dans toute l’arborescence), sub (par défaut) pour rechercher de manière récursive ; → , facultatif, indique un filtre permettant de limiter les à retenir éléments correspondant à la recherche (par défaut, (objectClass: *)). La connexion LDAP peut elle-même être chiffrée Une fois cette configuration en place, il nous suffit de pointer un avec SSL, auquel cas il navigateur web vers le chemin /prive du site web pour voir apparaître faut remplacer la fenêtre d’authentification classique du navigateur. ldap:// par ldaps://.

3.1 Déroulement d’une authentification

Comme nous l’avons évoqué, l’authentification d’un utilisateur se déroule en deux phases. La première phase permet d’identifier son DN. Pour cela, le module LDAP pour Apache se connecte avec l’identifiant (DN) et le mot de passe indiqués par AuthLDAPBindDN et AuthLDAPBindPassword au serveur LDAP, puis l’interroge avec le filtre suivant : Fichier (&()(=))

Cela peut par exemple être : Fichier (&(objectclass=*)(uid=fleur))

à cette requête, le serveur LDAP répond en indiquant notamment le DN de toutes les entrées qui y correspondent. Dans notre cas, il y a une seule utilisatrice avec cet uid. Par conséquent, le module LDAP pour Apache reçoit le DN suivant : Fichier uid=fleur,ou=utilisateurs,dc=ed-diamond

Une fois ce DN obtenu, le module LDAP d’Apache se connecte au serveur

C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 LDAP en l’associant avec le mot de passe fourni lors de la requête HTTP. Le serveur LDAP verra donc une connexion de la part de ce DN, qui sera soit réussie (si le mot de passe est bon), soit en échec (si le mot de passe est mauvais). Lorsque la connexion est réussie, le module n’exécute aucune requête : il se déconnecte immédiatement. C’est la réussite de cette connexion qui validera l’authentification de l’utilisateur.

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 99 Aller plus loin : authentification avec LDAP 4 3.2 Autorisations

Nous l’avons vu précédemment, les autorisations (c’est-à-dire la validation que tel utilisateur a le droit d’accéder à telle ressource) se font avec la directive Require. L’utilisation du module LDAP pour Apache ajoute les options suivantes pour cette directive...

Require ldap-user permet de préciser un ou plusieurs nom(s) d’utilisateur(s) valide(s). Comprenez par « nom d’utilisateur » celui fourni par le client HTTP. Avec cette à retenir directive, seuls les utilisateurs listés seront autorisés. Par exemple, la syntaxe suivante permettra d’autoriser les Presque pas de utilisateurs « denis » et « fleur », mais aucun autre susceptible configuration... d’exister dans cette base : Require ldap-user denis En réalité, dès que le module fleur. mod_ldap est activé, il offre ses Require ldap-group permet de filtrer selon l’appartenance fonctionnalités aux autres modules à des groupes des utilisateurs de la base LDAP. En effet, il l'utilisant ; la seule configuration nécessaire pour en profiter est donc est possible d’associer un objet LDAP à un groupe, qui est simplement de l'activer, si ce n'est pas défini dans la base LDAP avec la classe groupOfNames ou déjà fait. groupOfUniqueNames ; ces groupes peuvent avoir des attributs member (une occurrence de l’attribut pour chaque De plus, dans la plupart des cas, il n'est pas nécessaire de paramétrer ses utilisateur), qui pointent vers les DN qui en font partie. Le différentes directives : les valeurs par module LDAP pour Apache vérifie alors l’appartenance défaut sont adaptées à un site de taille d’un utilisateur au groupe renseigné en argument de la moyenne. directive Require ; par exemple Require ldap-group cn=gentils.

Require ldap-dn permet d’autoriser un et un seul DN particulier à se connecter ; par exemple Require ldap-dn uid=fleur,ou=utilisateurs,dc=ed-diamond.

Require ldap-attribute permet de préciser une valeur pour un attribut spécifique ; seuls les utilisateurs ayant l’attribut en question avec la valeur indiquée seront autorisés. Ainsi, nous pouvons préciser par exemple Require ldap-attribute "ou=redaction". Il est possible de spécifier plusieurs valeurs sur une même ligne, mais elles seront traitées comme un OU logique : il suffit d’avoir l’une des correspondances pour être autorisé.

Require ldap-filter est sans doute la plus puissante des directives de contrôle. Elle permet de préciser un filtre sur les attributs afin d’autoriser les accès. Nous pouvons utiliser n’importe quel attribut et n’importe quelle valeur avec une syntaxe LDAP. Si l’entrée retournée par la recherche de la

C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 première phase et la connexion fonctionnent (grâce au mot de passe), on ajoute alors une troisième condition, tout aussi précise. Par exemple, nous pouvons ajouter un attribut mobile (fourni par la classe inetOrgPerson) à certains utilisateurs et utiliser Require ldap-filter &(mobile=*) (ou=redaction) pour n’autoriser que les utilisateurs faisant partie de la rédaction et équipés d’un téléphone mobile...

100 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe Aller plus loin : authentification avec LDAP

3.3 Performances

Lorsqu’il s’agit d’authentification sur un serveur HTTP, arrive immanquablement le moment où la question des performances se pose. En effet, le mécanisme d’authentification est répété pour chaque requête et non pour la durée d’une session. Les méthodes classiques, comme celle proposée par mod_authn_file, sont relativement légères et tellement anciennes qu’elles sont largement optimisées. Supporter un grand nombre de connexions/requêtes en peu de temps n’est alors pas un problème. Il n’en va pas de même pour l’authentification LDAP. Vous imaginerez sans peine le nombre de connexions (bind) et de déconnexions (unbind) nécessaires sur un site moyennement chargé : c’est au moins le double du nombre de requêtes HTTP ! Pour contourner le problème, un module spécifique a été développé : mod_ldap. Celui-ci est intégré à la distribution par défaut et ne nécessite presque pas de configuration. Il fournit un cache, ainsi qu’un pool de connexions utilisable par tous les modules opérant des connexions LDAP. Ce module est d’ailleurs automatiquement activé lorsque l’on active mod_authnz_ldap. Le fichier de configuration du module, /etc/apache2/mods-available/ldap.conf, met en place une interface de contrôle sur une page spécifique générée automatiquement, permettant de connaître l’état du pool de connexions et du cache. Cette page n’est accessible, par défaut, qu’à partir de l’hôte local. Ce gestionnaire ldap-status prend en charge toutes les requêtes à destination du chemin en question. Ainsi, en pointant un navigateur web sur http://127.0.0.1/ldap-status, on pourra prendre connaissance de toutes les informations utiles. Ce module mod_ldap permet d’ajouter les paramètres liés à ces aspects, offrant la possibilité d’optimiser la configuration et de l’adapter au besoin. Les directives concernées sont les suivantes :

→ LDAPSharedCacheSize : taille du cache en octets ;

→ LDAPCacheEntries : nombre d’entrées LDAP (résultats search/bind) à conserver en cache ;

→ LDAPCacheTTL : durée de vie des données en cache ;

→ LDAPOpCacheEntries : nombre d’entrées LDAP (opérations de comparaison) à conserver en cache ;

→ LDAPOpCacheTTL : durée de vie des opérations de comparaison en cache ;

→ LDAPSharedCacheFile : chemin absolu vers le fichier de cache (en l’absence de cette directive, le cache est conservé en RAM).

Ces valeurs sont bien sûr à régler en fonction des besoins, notamment en fonction du nombre de connexions simultanées, de la quantité totale d’utilisateurs et de la durée habituelle d’une session, sans oublier de prendre en compte les ressources (mémoire notamment) à disposition. ▪ C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5

Références Documentation d’OpenLDAP : http://www.openldap.org/doc/admin24/ Le module LDAP pour Apache : http://httpd.apache.org/docs/2.4/mod/mod_authnz_ldap.html

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 101 Aller plus loin : Authentification avec LDAP 4 aLLer pLUs LoiN

cHiffremeNt et aUtHeNtificatioN ssL

ous le voyons tous les jours sur le Web, de très nombreuses informations privées ou sensibles s’échangent avec une cadence infernale entre les navigateurs et les serveurs web. Dans bien C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 Ndes cas, ces données circulent en clair, il devient alors possible pour un attaquant d’écouter très simplement les communications pour découvrir les petits secrets de tout le monde : mots de passe, e-mails, commentaires, coordonnées postales, informations bancaires, contenu de paniers d’achat, etc.

102 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe Aller plus loin : chiffrement et authentification SSL

Pour protéger ces informations, il n’y a qu’une seule solution, à laquelle on revient systématiquement : le chiffrement.

En ce qui concerne le protocole HTTP, une couche de chiffrement, d’authentification et de contrôle d’intégrité existe depuis bien longtemps : c’est HTTPS ou HTTP over SSL. Le protocole SSL (qui à retenir s’appelle en réalité TLS depuis 2001) est la couche cryptographique qui se glisse alors entre TCP et HTTP pour sécuriser les communications. Le protocole SSL (pour Secure Sockets Layer) a été Notons que le protocole SSL n’est pas lié à HTTP, il peut être utilisé avec développé à l’origine par de nombreux autres protocoles, par exemple IMAP, SMTP ou FTP. Netscape. La version 1.0 de ce protocole n’a jamais été publiée, la version 2.0 est sortie en 1995, mais a été rapidement remplacée par SSL 3.0 en 1996. 1 Certification SSL Ce protocole étant de plus en plus utilisé sur Internet, il est passé sous SSL repose sur une vérification hiérarchique, où des tiers de confiance garantissent la responsabilité de l’IETF, l’identité d’un tiers. De cette manière, lorsque l’on se connecte à un site web ou à un autre qui l’a renommé TLS (pour service, on est assuré de son identité et qu’il n’y a pas de piratage. Transport Layer Security) Le principe de cette infrastructure de confiance est le suivant : afin d’éviter d’éventuels problèmes légaux. TLS 1.0 Une autorité de certification (AC) est garante de la correspondance entre un certificat est sorti en 1999, suivi des (construit autour d’une clé publique) et une entité (personne, entreprise, site web, versions 1.1 en 2006 et 1.2 adresse e-mail...). Le fonctionnement complet du système repose sur le sérieux et le en 2008. professionnalisme des autorités de certification. Ceci est garanti par un protocole de Aujourd’hui, c’est TLS 1.0 vérification de l’identité des entités demandant un certificat. qui est la version la plus utilisée de ce protocole sur Une entité souhaitant obtenir un certificat produit une demande ou requête de le Web, car les navigateurs certification. Il s’agit là de créer une paire de clés : une clé privée (gardée secrète) ne supportent pas permettant de chiffrer des informations et une clé publique (connue de tous) permettant forcément les versions plus de déchiffrer un tel message. La clé publique est intégrée dans la demande de certificat, récentes. en compagnie d’informations complémentaires. Les deux clés sont stockées, après génération, dans des fichiers généralement au format PEM. D’autres formats sont disponibles, mais PEM est le plus courant. La demande de certification est alors envoyée à l’autorité de certification par le demandeur.

L’autorité de certification va alors lire les informations de la demande et vérifier l’identité du demandeur ainsi que la cohérence des informations. On distingue plusieurs niveaux de vérification (la vérification peut être une confirmation d’une réponse à un e-mail sur une adresse particulière, l’obtention d’informations par voie téléphonique, la véracité d’un extrait K-bis par courrier pour les sociétés, voire une rencontre physique). Plus l’AC vérifie d’informations, plus le certificat aura de valeur et mettra en confiance les personnes qui l’utiliseront par la suite. Bien entendu, plus la classe du certificat est importante, plus cette procédure coûte cher. Une fois les informations dûment vérifiées, l’AC signe la demande de certificat et produit un certificat pleinement valide et vérifié, qu’elle renvoie au demandeur.

Le couple certificat/clé privée est alors complètement fonctionnel et utilisable par l’entité. C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 Les tiers souhaitant vérifier l’identité d’une entité lui demandent son certificat et vérifie la signature de l’AC. Comme c’est un tiers de confiance (dont la signature est connue par le client, dans notre cas le navigateur web), si la signature est bonne cela signifie que l’entité est bien celle qu’elle prétend être.

Bien entendu, dans la pratique, les AC racines ne font pas tout le travail. Elles peuvent délivrer des certificats intermédiaires. Ainsi, une autorité de certification peut déléguer

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 103 Aller plus loin : chiffrement et authentification SSL 4 son expertise à une AC tierce qui signe effectivement les demandes. Pour vérifier, on remonte alors simplement la chaîne de confiance, chaque maillon validant l’authenticité du précédent. On vérifie la signature du certificat par l’AC tiers, puis le certificat de l’AC tierce avec la signature de l’AC racine. La chaîne de confiance peut être composée d’une quantité importante d’AC tierces.

1.1 Certificat client ou serveur

Les certificats se divisent en deux catégories, en fonction de leur utilisation. D’une part, nous avons les certificats clients, destinés à l’authentification des utilisateurs. Il s’agit, par exemple, du certificat délivré par l’administration française pour la télédéclaration des impôts (bien que la procédure se soit assouplie depuis la mise en place de cette technologie, il n’est maintenant plus nécessaire d’avoir un certificat pour télédéclarer). L’autorité de certification est alors la direction du Ministère de l’économie et des finances, elle a vérifié votre identité en vous demandant des informations que seul vous êtes censé(e) détenir (revenus de référence, numéro fiscal...). Ce type de certificats permet également la signature des e-mails, l’authentification auprès de services comme des VPN, etc. D’autre part, nous avons les certificats serveurs, qui, comme leur nom l’indique, sont destinés aux serveurs. Ils permettent d’assurer aux clients que l’identité annoncée par le serveur est bien réelle : la confiance que le client aura envers le serveur sera alors proportionnelle au niveau de validation de la part de l’AC.

1.2 Obtenir un certificat

Comme nous l’avons vu, l’obtention d’un certificat vérifié est payante. On dispose alors de plusieurs solutions pour avoir un certificat SSL, vérifié ou non : → Payer un certificat auprès d’une AC reconnue et listée dans les navigateurs – il est important que l’autorité de certification soit reconnue par les navigateurs, sinon notre certificat ne sera pas considéré comme valide – auquel cas un certain nombre de démarches sont nécessaires, qui découlent généralement de l’intégration du certificat racine et des certificats intermédiaires dans la majorité des navigateurs pré-installés ou téléchargeables ; → Opter pour l’acquisition d’un certificat à peu de frais, voire gratuit, sur Internet – certaines autorités de certification (ou intermédiaires) proposent ce type de services avec une vérification minimale des informations du demandeur : celles-ci se limitent généralement à une procédure automatisée de confirmation de l’adresse e-mail et de l’accès administrateur au serveur HTTP ; → Devenir une autorité de certification et signer ses propres demandes de certificat – dans ce cas, aucune vérification ne sera possible de la part des utilisateurs, puisque le certificat racine n’est pas présent dans leurs navigateurs – les visiteurs du site doivent alors faire confiance aux informations proposées et passer outre l’avertissement qui s’affichera dans le navigateur web lors de la validation du certificat, voire intégrer votre certificat racine dans la configuration de leur navigateur ; → Acquérir un certificat intermédiaire pour devenir en partie une AC dont le pouvoir ne s’étend que sur un domaine réduit – ce type de certificat demande davantage de vérifications avant d’être délivré et a un coût bien plus important – dans ce cas, il sera possible de signer des demandes pour ses propres services et sous-domaines sans avoir à payer.

C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 Le choix de la méthode d’obtention d’un ou plusieurs certificat(s) dépendra du type de site HTTPS à mettre en place. L’AC personnelle est utile pour la maîtrise complète d’un ensemble de serveurs privés, que ce soit à but didactique ou dans le cadre d’une informatique interne d’entreprise importante. Les certificats de classe 1, peu onéreux, voire gratuits, permettent le chiffrement HTTPS en évitant l’alerte habituelle (nous l’avons tous rencontrée, cette alerte qui dit qu’un certificat est invalide ou expiré) pour des sites publics simples.

104 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe Aller plus loin : chiffrement et authentification SSL

Les classes supérieures de certificats apportent un niveau de confiance supplémentaire pour vos utilisateurs : elles sont généralement mises en œuvre lorsqu’il est question de sites commerçants ou de gestion d’éléments financiers (gestion de comptes bancaires, de portefeuilles boursiers, etc.). Enfin, la délégation d’AC permettant de produire des certificats pour des sous-domaines sera choisie lorsque l’on a un ensemble de serveurs à sécuriser. à chacun d’évaluer son besoin...

Client SSL Serveur SSL

Salutation client Je veux une connexion SSL. Je supporte telle version SSL et tels chiffrements

Salutation serveur ok pour SSL avec telle version SSL et tel chiffrement

Certificat serveur (optionnel)

Échange de clef serveur Je n'ai pas de certificat, voici ma clef (optionnel)

Demande certificat client Je veux vous authentifier. Donnez-moi votre certificat signé per tell CA ( optionnel)

Fin de salutation Attente de la réponse du client

Certificat client Voici mon certificat (optionnel)

Échange de clef client Voici ma clef publique, je vais envoyer d'autres données signées avec votre clef publique

Vérification de certificat (optionnel) TEMPS Je vais signer des informations avec la clef privée de mon certificat, pour prouver que j'en suis le propriétaire

Signalement de chiffrement Mon prochain message sera chiffré

Fin de négociation Message chiffré Signalement de chiffrement Mon prochain message sera chiffré

Fin de négociation C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 Message chiffré

Données de l'application Données de l'application Messages chiffrés Messages chiffrés

Négociation et établissement d’une communication avec SSL

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 105 Aller plus loin : chiffrement et authentification SSL 4 Génération et manipulation 2 des certificats

La technique décrite ici consiste à devenir notre propre autorité de certification. Ceci n’est généralement pas recommandé car, si le site est ouvert au public, les utilisateurs risquent d’être très sceptiques quant à votre identité étant donné que leur navigateur web affichera une erreur leur indiquant que votre certificat n’est pas valide. Cette méthode est toutefois intéressante à titre didactique, pour bien comprendre le fonctionnement de l’ensemble ; elle est également adaptable, en sautant quelques étapes, à l’utilisation d’une AC tierce, comme Gandi, StartSSL, TBS ou VeriSign...

2.1 Création d’une autorité de certification

Commençons donc par créer notre autorité de certification. Pour cela, nous devons nous créer une clé privée, une demande de certification et signer cette demande. Toutes ces opérations se font avec la commande openssl, proposée par le paquet du même nom, qui est certainement déjà installé sur un serveur Debian ou Ubuntu.

2.1.1 Répertoires de travail

La première étape consiste à créer la clé privée, mais avant cela, nous devons construire une arborescence qui permettra le bon fonctionnement de nos commandes. Nous créons donc un ensemble de répertoires pour accueillir nos clés privées (private), nos certificats (certs) et les listes de révocation pour les certificats qui n’ont plus lieu d’être (crl).

On initialise également les fichiers maintenus par openssl, et on place tout cela dans le répertoire /srv/ssl : Terminal ~# mkdir -p /srv/ssl cd /srv/ssl mkdir certs crl newcerts private echo 01 > serial touch index.txt cp /usr/lib/ssl/openssl.cnf .

2.1.2 Configuration

Éditons le fichier openssl.cnf pour l’adapter à nos besoins et préférences. Tout d’abord, il faut adapter la valeur dir pour qu’elle corresponde à notre répertoire de travail : Fichier C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 dir = /srv/ssl

Il est également possible de configurer certaines valeurs par défaut, notamment dans la section [ req_distinguished_name ] : le code pays dans la directive countryName_default, le nom de la société dans 0.organizationName_default, etc.

106 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe Aller plus loin : chiffrement et authentification SSL

openssl n’est pas qu’un simple outil de génération de certificats, c’est également une base pour une gestion de PKI. En configurant proprement et judicieusement ce fichier, nous serions à même de gérer plusieurs autorités de certification locales, ainsi que les certificats produits. Voilà pourquoi cette commande demande une configuration préalable.

2.1.3 Clé privée

La clé privée de l’autorité de certification est générée avec la commande suivante : Terminal /srv/ssl# openssl genrsa -des3 -out private/cakey.pem 4096 Generating RSA private key, 4096 bit long modulus ...... ++ ...... ++ e is 65537 (0x10001) Enter pass phrase for private/cakey.pem: Verifying - Enter pass phrase for private/cakey.pem:

Après avoir saisi deux fois le mot de passe qui protégera la clé, on obtient un fichier cakey.pem.

2.1.4 Certificat et signature

Dès lors, on peut créer un certificat directement auto-signé avec la commande suivante : Terminal /srv/ssl# openssl req -config openssl.cnf -new -x509 -nodes -sha1 -days 1825 -key private/cakey.pem -out cacert.pem Enter pass phrase for private/cakey.pem: You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter ‘.’, the field will be left blank. ----- Country Name (2 letter code) [FR]: State or Province Name (full name) [Some-State]:Alsace Locality Name (eg, city) []:Selestat Organization Name (eg, company) [Ma petite entreprise]: Organizational Unit Name (eg, section) []: Common Name (eg, YOUR name) []:Mon petit CA Email Address []:[email protected]

Nous spécifions ici que nous voulons produire une demande de certificat (req) ; avec l’option -x509, nous précisons que cette demande doit être signée. La durée de validité du certificat sera de 5 ans (1825 jours) et nous indiquons à la commande où lire la clé privée pour produire le fichier cacert.pem. openssl demande tout d’abord le mot de passe pour débloquer la clé privée. Viennent ensuite des demandes d’identité dont les réponses seront intégrées dans le certificat. Ces informations permettront aux personnes récupérant le certificat (et donc la clé publique) d’en savoir plus sur notre identité en tant qu’autorité de certification.

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 107 C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 Aller plus loin : chiffrement et authentification SSL 4 2.1.5 Diffusion

Ce certificat peut d’ores et déjà être diffusé auprès des futurs visiteurs de notre futur site web sécurisé. Pour cela, il suffit de le déposer sur le site web (non sécurisé) : les dernières versions des différents navigateurs permettent de demander à l’utilisateur s’il souhaite ou non ajouter une autorité de certification avec un simple lien.

Ceci ne fonctionnera que si le serveur associe bien les fichiers avec le type MIME application/x-x509-ca-cert. La configuration par défaut du serveur HTTP Apache mise en place par Debian ou Ubuntu lors de l’activation du module mod_ssl associe ce type MIME aux fichiers ayant l’extension .crt. Il suffit alors de renommer notre fichier de certificat ou bien d’ajouter la ligne suivante dans la configuration d’Apache (par exemple, dans /etc/apache2/conf.d/mon_petit_ca.conf) : Fichier AddType application/x-x509-ca-cert .pem

Nous reviendrons sur la configuration d’Apache plus loin.

2.2 Génération d’un certificat

Maintenant que nous sommes – techniquement – une autorité de certification, nous pouvons générer des demandes de certificat. Le point important dans cette génération est le common name, ou CN, qui doit être le nom du serveur pleinement qualifié (FQDN). Prenons, pour notre exemple, www.ma-petite-entrepri.se...

2.2.1 Création d’une clé et demande d’un certificat

Notons que les commandes décrites dans cette étape sont précisément celles dont on ferait usage en travaillant avec une vraie autorité de certification... Ici, nous sommes à la fois administrateur du serveur et autorité de certification, il est donc normal que nous ayons accès à toutes les clés privées. Il n’en va pas de même pour les demandes de certificat faites à des autorités de certification tierces ; certaines proposent de générer la demande de certificat et la clé privée de leur côté, d’autres utilisent les fonctionnalités de génération du navigateur, mais tous les prestataires sérieux proposent également le téléversement d’une demande de certificat via un formulaire ou via un copier-coller.

Tout d’abord, générons une clé privée : Terminal

C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 /srv/ssl# openssl genrsa -des3 -out mapetiteentreprise.key.pem 4096 Generating RSA private key, 4096 bit long modulus ...... ++ ...... ++ e is 65537 (0x10001) Enter pass phrase for mapetiteentreprise.key.pem: Verifying - Enter pass phrase for mapetiteentreprise.key.pem:

108 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe Aller plus loin : chiffrement et authentification SSL

Passons ensuite à la génération de la demande de certificat : Terminal /srv/ssl# openssl req -config openssl.cnf -new -key mapetiteentreprise.key.pem -out mapetiteentreprise.csr.pem Enter pass phrase for mapetiteentreprise.key.pem: You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter ‘.’, the field will be left blank. ----- Country Name (2 letter code) [FR]: State or Province Name (full name) [Some-State]:Alsace Locality Name (eg, city) []:Selestat Organization Name (eg, company) [Ma petite entreprise]: Organizational Unit Name (eg, section) []: Common Name (eg, YOUR name) []:www.ma-petite-entrepri.se Email Address []:[email protected]

Please enter the following ‘extra’ attributes to be sent with your certificate request A challenge password []: An optional company name []:

Dans le cas d’une autorité de certification classique sur Internet, c’est le fichier mapetiteentreprise.csr.pem qu’il faut transmettre... Le format utilisé est PEM, car les fichiers sont alors constitués uniquement de caractères lisibles. On peut d’ailleurs le constater en utilisant la commande cat sur l’un de ces fichiers. On voit alors par exemple un bloc précédé d’un en-tête -----BEGIN CERTIFICATE REQUEST----- pour la demande.

2.2.2 Signature de la demande

Nous pouvons maintenant, en tant qu’autorité de certification, procéder à la signature de la demande et à la production du certificat final, avec la commande suivante : Terminal /srv/ssl# openssl ca -config openssl.cnf -policy policy_anything -out mapetiteentreprise.cert.pem -infiles mapetiteentreprise.csr.pem Using configuration from openssl.cnf Enter pass phrase for /srv/ssl/private/cakey.pem: Check that the request matches the signature Signature ok Certificate Details: Serial Number: 1 (0x1) Validity

C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 Not Before: Mar 15 14:28:32 2013 GMT Not After : Mar 15 14:28:32 2014 GMT Subject: countryName = FR stateOrProvinceName = Alsace localityName = Selestat organizationName = Ma petite entreprise

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 109 Aller plus loin : chiffrement et authentification SSL 4 Terminal commonName = www.ma-petite-entrepri.se emailAddress = [email protected] X509v3 extensions: X509v3 Basic Constraints: CA:FALSE Netscape Comment: OpenSSL Generated Certificate X509v3 Subject Key Identifier: B8:00:97:15:B9:5D:CE:AB:4C:20:2B:CD:91:08:A7:6C:2A:CD:27:21 X509v3 Authority Key Identifier: keyid:21:EC:F7:F3:C6:F1:6D:19:56:1B:F3:1C:A3:C8:11:9C:5 F:C8:25:30

Certificate is to be certified until Mar 15 14:28:32 2014 GMT (365 days) Sign the certificate? [y/n]:y

1 out of 1 certificate requests certified, commit? [y/n]y Write out database with 1 new entries Data Base Updated

Les diverses informations renseignées lors de la création de la demande sont affichées et il est demandé de confirmer la signature. Là, il faut faire jouer notre côté schizophrène en faisant preuve d’une double personnalité, d’un côté administrateur système et de l’autre côté autorité de certification.

Nous allons donc (en tant qu’autorité de certification) vérifier les données affichées, valider qu’il s’agit bien d’une demande provenant de nous (en tant qu’administrateur système) et que les données affichées sont cohérentes ; on valide la signature en répondant « y » à la question « Sign the certificate? » et on confirme finalement le commit de cette certification. Cette commande retourne alors un fichier mapetiteentreprise.cert.pem, qui est prêt à être utilisé par l’administrateur système (nous).

Côté gestion des certificats, on peut constater que le contenu du fichier serial est passé à 02 : c’est le numéro de série du prochain certificat qui sera produit. Le numéro précédent est précisé dans celui qui vient d’être généré, on peut le voir avec la commande openssl x509 -in mapetiteentreprise.cert.pem -text | grep Serial.

La commande openssl a également mis à jour le fichier index.txt qui contient la liste des certificats déjà produits. Des fichiers .old sont également créés pour y stocker le précédent contenu de ces fichiers.

2.3 Certificats multi-domaines

La RFC 2812 (HTTP Over TLS) précise que l’utilisation du CN (common name) comme identité d’un serveur est une pratique courante, mais qu’il ne s’agit pas du comportement par défaut. Un champ subjectAltName est disponible dans les extensions v3 ; ce champ C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 permet de préciser un ou plusieurs dNSName, dont les FQDN de différents serveurs ou sites. Ce n’est qu’en l’absence de cette donnée que le navigateur web doit se référer au champ CN.

Les autorités de certification sont encouragées à faire usage de cette extension. Ceci permet de régler un problème assez courant : l’utilisation d’hôtes virtuels basés sur les noms avec un seul et même certificat. Auparavant, l’activation de SSL nécessitait obligatoirement autant de certificats que d’hôtes virtuels.

110 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe Aller plus loin : chiffrement et authentification SSL

Configuration 3 d’Apache

Notre fichier de clé privée est protégé par un mot de passe. Ceci serait utile s’il était accessible d’une manière ou d’une autre. Il sera sans doute nécessaire de retirer cette protection avant la mise en place du service HTTPS. En effet, comme la clé est protégée par un mot de passe, celui-ci est automatiquement demandé lorsque le serveur HTTP Apache est lancé ou relancé. Ceci ne posera pas de problème en phase d’essai, car nous avons pleinement la main sur le serveur. En revanche, en production sur une machine dédiée, bloquer le redémarrage du serveur web n’est pas une bonne chose. En cas de problème, cela risque de rendre le service indisponible.

Pour retirer la protection par mot de passe triple DES, on utilise la commande suivante : Terminal /srv/ssl# openssl rsa -in mapetiteentreprise.key.pem -out mapetiteentreprise.key.nopass.pem Enter pass phrase for mapetiteentreprise.key.pem: writing RSA key

Le mot de passe demandé est celui de la clé privée protégée ; cette commande ne demandera pas de mot de passe pour le nouveau fichier.

Par mesure de simplicité, déplaçons tous les fichiers liés à notre site (mapetiteentreprise.*) dans un répertoire indépendant, par exemple /srv/ssl/mapetiteentreprise. De cette manière, la configuration d’Apache fera référence à des fichiers bien ordonnés.

Passons donc à la configuration d’Apache proprement dite. Ajoutons tout d’abord la ligne suivante au fichier /etc/apache2/ports.conf : Fichier NameVirtualHost *:443

Normalement, la directive Listen 443 s’y trouve déjà...

Si ce n’est déjà fait, activons le module SSL : Terminal ~# a2enmod ssl Enabling module ssl. See /usr/share/doc/apache2.2-common/README.Debian.gz on how to configure SSL and create self-signed certificates.

C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 Run ‘/etc/init.d/apache2 restart’ to activate new configuration!

Ajoutons maintenant un fichier de configuration pour ce site protégé ; pour notre exemple, disons que ce site est dans le répertoire /srv/www/mapetiteentreprise et que le fichier de configuration est /etc/apache2/sites-available/ mapetiteentreprise-ssl :

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 111 Aller plus loin : chiffrement et authentification SSL 4 Fichier ServerName www.ma-petite-entrepri.se DocumentRoot /srv/www/mapetiteentreprise SSLEngine On SSLCertificateFile /srv/ssl/mapetiteentreprise/ mapetiteentreprise.cert.pem SSLCertificateKeyFile /srv/ssl/mapetiteentreprise/ mapetiteentreprise.key.nopass.pem SSLProtocol all -SSLv2

Ce fichier de configuration est activé avec les commandes suivantes : Terminal ~# a2ensite mapetiteentreprise-ssl ~# /etc/init.d/apache2 reload

Les directives SSLEngine, SSLCertificateFile et SSLCertificateKeyFile sont plutôt parlantes : activation du SSL, fichier du certificat, fichier de la clé ; on n’approfondira pas plus ces points.

Détaillons par contre la directive SSLProtocol ; celle-ci permet de préciser quel(s) protocole(s) SSL est/sont autorisé(s). Les protocoles supportés par Apache sont SSLv2 (jusqu’à Apache 2.2, inclus dans Debian et Ubuntu actuellement), SSLv3, TLSv1, TLSv1.1, TLSv1.2.

SSLv2 offre une protection trop faible, c’est pourquoi la ligne incluse dans la configuration active le support de tous les protocoles sauf celui-ci. En utilisant Apache 2.4, cette ligne n’est plus utile, car le protocole SSLv2 n’est plus supporté du tout. De plus, les protocoles TLSv1.1 et TLSv1.2 ne sont supportés qu’avec la bibliothèque OpenSSL en version 1.0.1 ou supérieure.

Une fois la configuration en place et suite au rechargement du serveur, il suffit de pointer un navigateur vers le nom d’hôte virtuel défini, en précisant bien le protocole https:// pour se connecter à ce site sécurisé.

3.1 SSL et hôtes virtuels

Jusqu’à il y a quelques années, il n’était pas possible d’héberger plusieurs hôtes virtuels en SSL sur une même adresse IP. En effet, l’adresse demandée par le navigateur étant chiffrée, le serveur ne pouvait pas deviner vers quel site il fallait pointer. On a aujourd’hui deux solutions à ce problème...

3.1.1 SNI

L’extension SNI, dont le développement a commencé en 2004, permet au client d’indiquer C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 au serveur l’adresse qu’il souhaite joindre avant de chiffrer la communication ; de cette manière, le serveur est capable de fournir le certificat correspondant au site demandé.

Pour les serveurs web sous Linux, cette extension a tout d’abord été implémentée dans la bibliothèque GNU TLS. Ce support a ensuite été ajouté à la bibliothèque OpenSSL, optionnelle en version 0.9.8f et compilée par défaut depuis la version 0.9.8j. Dans Debian Squeeze par exemple, cette bibliothèque est disponible en version 0.9.8o. De plus, Apache

112 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe Aller plus loin : chiffrement et authentification SSL

ne supporte cette fonctionnalité qu’à partir de la version 2.2.12, sortie en juillet 2009. De nombreux autres serveurs web supportent cette fonctionnalité, qui a été implémentée plus ou moins tôt dans chacun d’entre eux. Mais il faut également que cette fonctionnalité soit supportée par le navigateur web. Au début de l’année 2013, le seul navigateur web « courant » ne supportant pas cette fonctionnalité est Internet Explorer 8 sur Windows XP. Notons que cette fonctionnalité est supportée sur Windows Vista (et versions supérieures) dès Internet Explorer 7... Les autres navigateurs supportent cette fonctionnalité depuis longtemps : Chrome 6, Firefox 3.0, Opera 8.0... Attention toutefois aux navigateurs mobiles, qui peuvent être un peu à la traîne... Grâce à cette extension, il n’y a aucune action supplémentaire à effectuer pour supporter de multiples hôtes virtuels sur un même serveur et une même adresse IP : c’est le protocole qui se charge de tout. Par contre, tout navigateur ne supportant pas cette extension recevra le certificat correspondant au site SSL principal, c’est-à-dire au premier de la liste.

3.1.2 subjectAltName

Comme nous l’avons abordé plus haut, le champ CN ne devrait plus contenir le FQDN d’un serveur. Cette information devrait être lue depuis le champ subjectAltName de l’extension SSLv3 et plus particulièrement sous la forme d’un dNSName (DNS:). Ce n’est que si cette information est absente que le CN doit être utilisé (par compatibilité avec les anciennes versions des bibliothèques et logiciels). De cette manière, il est possible de définir plusieurs noms d’hôtes pour un même certificat, résolvant par là même le problème de conflit avec l’adresse IP. Le certificat que nous avons généré, bien que parfaitement viable, ne respecte donc pas cette directive à la lettre (notons toutefois que cette méthode est encore largement utilisée par les autorités de certification). Nous allons donc produire un nouveau certificat, plus en conformité avec le standard. Malheureusement, openssl n’offre pas autant de finesse et d’ergonomie avec cette option (qui n’en est plus une) qu’avec les autres informations d’un certificat ou d’une demande de certificat. Nous penserons en particulier à la politique (policy) et le fait de filtrer les extensions v3 acceptées ou non. Quoi qu’il en soit, il est parfaitement possible de produire de tels certificats. Nous n’allons pas tout reprendre depuis le début, mais uniquement générer une nouvelle demande de certificat et la signer avec notre AC. Nous devons cependant changer quelques éléments dans notre configuration, /srv/ssl/openssl.cnf : → Tout d’abord, décommentons la ligne req_extensions = v3_req qui référence les extensions à ajouter à une demande de certificat ; → Ensuite, dans la section [ v3_req ] (qui regroupe toutes ces extensions), ajoutons la ligne suivante : Fichier subjectAltName = @alt_names

C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 → Enfin, ajoutons plus bas une section pour définir l’adresse à préciser et profitons-en pour ajouter une autre adresse à ce certificat : Fichier [ alt_names ] DNS.1 = www.ma-petite-entrepri.se DNS.2 = prive.ma-petite-entrepri.se

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 113 Aller plus loin : chiffrement et authentification SSL 4 La commande openssl ne permettant pas d’ajouter ces informations de manière dynamique, nous voyons ici que ces données doivent être indiquées dans le fichier de configuration. Il sera donc nécessaire de dupliquer ce fichier de configuration autant de fois qu’il y aura de certificats multi-domaines à créer (notons toutefois que les autorités de certification offrent parfois la possibilité de définir ces données par l’intermédiaire d’une interface web, plus simple à utiliser). Créons donc maintenant une demande de certificat avec cette clé : Terminal /srv/ssl/mapetiteentreprise# openssl req -config ../openssl.cnf -new -key mapetiteentreprise.key.pem -out mapetiteentreprise.csr.pem Enter pass phrase for mapetiteentreprise.key.pem: You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter ‘.’, the field will be left blank. ----- Country Name (2 letter code) [FR]: State or Province Name (full name) [Some-State]:Alsace Locality Name (eg, city) []:Selestat Organization Name (eg, company) [Ma petite entreprise]: Organizational Unit Name (eg, section) []: Common Name (eg, YOUR name) []:Ma petite entreprise Email Address []:[email protected]

Please enter the following ‘extra’ attributes to be sent with your certificate request A challenge password []: An optional company name []:

Nous avons ici délibérément utilisé un CN qui n’est pas un nom de machine, car c’est bien le champ subjectAltName qui sera utilisé, le CN n’a plus de signification technique. Pour nous assurer que notre subjectAltName est bien pris en compte, nous pouvons afficher la demande sous une forme lisible : Terminal /srv/ssl/mapetiteentreprise# openssl req -text -noout -in mapetiteentreprise.csr.pem | grep -A 1 «X509v3 Subject Alternative Name» X509v3 Subject Alternative Name: DNS:www.ma-petite-entrepri.se, DNS:prive.ma-petite- entrepri.se

C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 Il ne nous reste plus qu’à signer cette demande en tant qu’autorité de certification, mais là encore, il faut faire une petite modification dans la configuration d’OpenSSL. Dans la section [ CA_default ], la ligne suivante est à décommenter : Fichier copy_extensions = copy

114 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe Aller plus loin : chiffrement et authentification SSL

Elle permet d’activer la copie des extensions fournies dans une demande vers le certificat signé. Comme le précise le commentaire juste au-dessus de cette ligne, c’est une option à utiliser avec précaution. L’une des extensions dangereuses est affichée dans notre demande : CA:FALSE. Ici, il n’y a pas de problème. Cette extension permet de transformer un certificat en certificat capable d’agir comme une AC intermédiaire. Historiquement, des AC ont déjà fourni des certificats avec CA:TRUE, permettant aux utilisateurs de signer des demandes de certificats sur des domaines ne leur appartenant pas. Pire encore, les anciennes versions des navigateurs ne cherchaient pas à s’assurer de la validité de la chaîne de confiance et ce champ n’était alors tout simplement pas vérifié. Tout cela est du passé, heureusement. Notre modification apportée à la configuration, nous pouvons signer la demande comme précédemment : Terminal /srv/ssl/mapetiteentreprise# openssl ca -config ../openssl.cnf -policy policy_ anything -out mapetiteentreprise.cert.pem -infiles mapetiteentreprise.csr.pem Using configuration from ../openssl.cnf Enter pass phrase for /srv/ssl/private/cakey.pem: Check that the request matches the signature Signature ok Certificate Details: Serial Number: 2 (0x2) Validity Not Before: Mar 18 09:12:43 2013 GMT Not After : Mar 18 09:12:43 2014 GMT Subject: countryName = FR stateOrProvinceName = Alsace localityName = Selestat organizationName = Ma petite entreprise commonName = Ma petite entreprise emailAddress = [email protected] X509v3 extensions: X509v3 Basic Constraints: CA:FALSE Netscape Comment: OpenSSL Generated Certificate X509v3 Subject Key Identifier: B8:00:97:15:B9:5D:CE:AB:4C:20:2B:CD:91:08:A7:6C:2A:CD:27:21 X509v3 Authority Key Identifier: keyid:21:EC:F7:F3:C6:F1:6D:19:56:1B:F3:1C:A3:C8:11:9C:5F:C8:25:30

X509v3 Key Usage: Digital Signature, Non Repudiation, Key Encipherment X509v3 Subject Alternative Name: DNS:www.ma-petite-entrepri.se, DNS:prive.ma-petite-entrepri.se

C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 Certificate is to be certified until Mar 18 09:12:43 2014 GMT (365 days) Sign the certificate? [y/n]:y

1 out of 1 certificate requests certified, commit? [y/n]y Write out database with 1 new entries Data Base Updated

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 115 Aller plus loin : chiffrement et authentification SSL 4

Détails de notre certificat

Nous voyons là clairement que l’extension X509v3 Subject Alternative Name est bien prise en compte. Nous constatons également que, comme prévu auparavant, le numéro de série de ce certificat est 02. Du côté d’Apache, vu qu’on a créé ces fichiers au même endroit, il n’y a pas d’autre modification à effectuer. On peut toutefois créer le second hôte virtuel, pour valider la possibilité d’utiliser le même certificat sur les deux sites sans erreur : Fichier ServerName www.ma-petite-entrepri.se DocumentRoot /srv/www/mapetiteentreprise SSLEngine On SSLCertificateFile /srv/ssl/mapetiteentreprise/ mapetiteentreprise.cert.pem SSLCertificateKeyFile /srv/ssl/mapetiteentreprise/ mapetiteentreprise.key.nopass.pem SSLProtocol all -SSLv2 C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 ServerName prive.ma-petite-enrepri.se DocumentRoot /srv/www/prive.mapetiteentreprise SSLEngine On SSLCertificateFile /srv/ssl/mapetiteentreprise/ mapetiteentreprise.cert.pem

116 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe Aller plus loin : chiffrement et authentification SSL

Fichier SSLCertificateKeyFile /srv/ssl/ mapetiteentreprise/mapetiteentreprise. key.nopass.pem SSLProtocol all -SSLv2

Pour peu que l’autorité de certification ait été enregistrée au préalable dans le navigateur, aucun message d’avertissement ne sera affiché lors de l’accès Astuce à l’un ou l’autre des sites. Conflits de numéros Si l’on affiche les détails du certificat dans le de série navigateur web, on constate bien que les informations Si vous faites de nombreux essais sont dans le champ « Nom alternatif du sujet du avec votre autorité de certification certificat ». Cela est la plus grosse faille de cette (réinitialisation des certificats, technique : toute personne ayant accès à un site des index...), il est possible qu’à un protégé par un tel certificat aura connaissance de moment ou à un autre un même l’existence de tous les autres sites qu’il couvre, même si numéro de série soit attribué à deux certificats différents. Ceci sera ces sites sont censés rester privés... détecté par votre navigateur, qui bloquera complètement le site, car un tel conflit de numéros de série est anormal. Pour passer outre, une seule Certificats solution : aller dans les préférences 4 clients du navigateur, afficher les certificats (avec Firefox, c’est dans l’écran SSL/TLS offre le chiffrement des communications Avancé > Chiffrement > Afficher les certificats) et supprimer le et l’authentification des serveurs... Mais qu’en est-il certificat serveur qui pose problème. des clients ? On peut toujours implémenter une Vous pouvez faire de même avec authentification classique sur une connexion protégée par le certificat de l’AC. Pour que ces SSL, mais pour avoir quelque chose d’encore plus solide, changements soient pris en compte, on peut générer ces certificats clients : ce mécanisme il peut être nécessaire de fermer et fonctionne dans les deux sens. relancer le navigateur. Contrairement à ce que l’on peut Le serveur prouve son identité via la présentation d’un trouver comme conseil sur Internet, certificat signé par une AC reconnue. De la même manière, supprimer le fichier cert8.db de le serveur peut demander aux clients de présenter un votre profil Firefox n’est pas une certificat signé par une AC spécifique. Là, il n’est plus bonne idée ; ce fichier contient bien nécessaire d’utiliser un tiers de confiance : on crée une plus que les informations sur les AC et on signe les demandes qui nous sont faites. Dès numéros de série des certificats ! lors, nous pouvons trier les visiteurs et limiter l’accès à certaines parties de nos pages en exigeant un certificat signé par notre AC.

La mise en œuvre de ce système s’inscrit naturellement

C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 dans la continuité de nos expérimentations. Nous allons donc créer deux nouvelles clés privées et deux demandes de certificat. Ceci sera fait exactement comme pour les certificats serveurs. Le champ CN devra simplement correspondre au nom de l’utilisateur à identifier.

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 117 Aller plus loin : chiffrement et authentification SSL 4 4.1 Clés privées

Utilisons la commande habituelle pour générer des clés privées : Terminal /srv/ssl/mapetiteentreprise# openssl genrsa -des3 -out alice. mapetiteentreprise.key.pem 4096 /srv/ssl/mapetiteentreprise# openssl genrsa -des3 -out bob. mapetiteentreprise.key.pem 4096

Et voilà, rien de plus : une clé SSL est juste une clé SSL, après tout.

4.2 Demande de certificat

Créons maintenant nos demandes de certificat (n’oublions cependant pas de supprimer les modifications que nous avions effectuées pour le certificat serveur, avec le champ subjetAltName ; comme dit, il est préférable de créer un nouveau fichier pour celui-ci afin d’éviter de tels conflits) : Terminal /srv/ssl/mapetiteentreprise# openssl req -config ../openssl. cnf -new -key alice.mapetiteentreprise.key.pem -out alice. mapetiteentreprise.csr.pem Enter pass phrase for alice.mapetiteentreprise.key.pem: You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter ‘.’, the field will be left blank. ----- Country Name (2 letter code) [FR]: State or Province Name (full name) [Some-State]:Alsace Locality Name (eg, city) []:Selestat Organization Name (eg, company) [Ma petite entreprise]: Organizational Unit Name (eg, section) []: Common Name (eg, YOUR name) []:alice Email Address []:[email protected]

Please enter the following ‘extra’ attributes

C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 to be sent with your certificate request A challenge password []: An optional company name []:

La même commande sera utilisée en remplaçant « alice » par « bob » pour le second utilisateur.

118 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe Aller plus loin : chiffrement et authentification SSL

4.3 Signature des certificats

Les demandes de certificat créées, il faut maintenant que notre AC les signe : Terminal /srv/ssl/mapetiteentreprise# openssl ca -config ../openssl.cnf -policy policy_anything -out alice.mapetiteentreprise.cert.pem -infiles alice.mapetiteentreprise.csr.pem /srv/ssl/mapetiteentreprise# openssl ca -config ../openssl.cnf -policy policy_anything -out bob.mapetiteentreprise.cert.pem -infiles bob.mapetiteentreprise.csr.pem

4.4 Importation dans le navigateur

Ces certificats devront être présentés par le navigateur web au serveur. Pour cela, il faut les importer dans le navigateur. Bien que Firefox soit capable de traiter des fichiers PEM pour ajouter de nouvelles AC, il n’en va pas de même pour les certificats clients, qui doivent également comprendre la clé secrète indispensable à leur utilisation. Concaténer les fichiers PEM ne nous avancera pas davantage, Firefox ne sachant pas lire ces fichiers concaténés. Le seul format reconnu par Firefox pour cela est PKCS#12 (.p12). Nous devons donc convertir nos fichiers : Terminal /srv/ssl/mapetiteentreprise# openssl pkcs12 -export -inkey alice. mapetiteentreprise.key.pem -in alice.mapetiteentreprise.cert.pem -out alice.mapetiteentreprise.cert.p12 -name «Alice» Enter pass phrase for alice.mapetiteentreprise.key.pem: Enter Export Password: Verifying - Enter Export Password: /srv/ssl/mapetiteentreprise# openssl pkcs12 -export -inkey bob. mapetiteentreprise.key.pem -in bob.mapetiteentreprise.cert.pem -out bob.mapetiteentreprise.cert.p12 -name «Bob» Enter pass phrase for bob.mapetiteentreprise.key.pem: Enter Export Password: Verifying - Enter Export Password: C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 Notons l’utilisation de l’option -name permettant de nommer le certificat, afin qu’il n’apparaisse pas dans le navigateur avec la simple mention « Certificat importé » suivie du numéro de série. Dans la vraie vie, la procédure voudrait que le client transmette sa demande de certificat, que l’on vérifiera, signera, puis qu’on lui renverra. à sa charge de faire la conversion et à lui de gérer et

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 119 Aller plus loin : chiffrement et authentification SSL 4 sécuriser sa clé privée. Deux mots de passe sont demandés : celui qui protège le fichier PEM à ouvrir et celui qui protégera le fichier PKCS#12 créé.

De retour sur le navigateur, il faut passer encore une fois par ses préférences (dans l’onglet « Vos certificats ») pour importer le ou les certificat(s) au format PKCS#12. Le mot de passe de protection est alors demandé afin de pouvoir le lire.

4.5 Configuration du serveur

Configurons maintenant notre serveur HTTP Apache pour qu’il demande un certificat SSL client. Dans notre exemple, protégeons le répertoire www. ma-petite-entrepri.se/prive ainsi que le site complet prive.ma- petite-entrepri.se : Fichier ServerName www.ma-petite-entrepri.se DocumentRoot /srv/www/mapetiteentreprise

SSLEngine On SSLCertificateFile /srv/ssl/mapetiteentreprise/ mapetiteentreprise.cert.pem SSLCertificateKeyFile /srv/ssl/mapetiteentreprise/ mapetiteentreprise.key.nopass.pem SSLProtocol all -SSLv2 SSLCACertificateFile /srv/ssl/cacert.pem

SSLVerifyClient require SSLVerifyDepth 1 AllowOverride none Order allow,deny Allow from all

ServerName prive.ma-petite-enrepri.se DocumentRoot /srv/www/prive.mapetiteentreprise

SSLEngine On SSLCertificateFile /srv/ssl/mapetiteentreprise/ mapetiteentreprise.cert.pem SSLCertificateKeyFile /srv/ssl/mapetiteentreprise/ mapetiteentreprise.key.nopass.pem C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 SSLProtocol all -SSLv2 SSLCACertificateFile /srv/ssl/cacert.pem

SSLVerifyClient require SSLVerifyDepth 1

120 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe Aller plus loin : chiffrement et authentification SSL

Nous ajoutons ici trois directives : → SSLCACertificateFile indique au serveur quelle est l’autorité de certification sur laquelle se baser pour vérifier les certificats ;

→ SSLVerifyClient require permet de n’autoriser que les clients qui présentent un certificat correctement signé ;

→ SSLVerifyDepth permet de limiter la longueur de la chaîne de confiance, c’est utile notamment dans le cas d’autorités de certification intermédiaires.

4.6 Accès

à partir de maintenant, lorsque l’on essaie d’accéder à l’une de ces adresses protégées avec le navigateur web, il propose de choisir un certificat à utiliser.

Choix du certificat à utiliser C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5

Nous remarquons que Firerfox ne demande pas le mot de passe du certificat : ce mot de passe a été demandé lors de son importation, il n’est donc plus nécessaire. Raison de plus pour compartimenter les sessions utilisateurs au sein d’une même famille : si vous laissez d’autres personnes utiliser votre navigateur, ils pourront utiliser ces certificats sans en connaître le mot de passe !

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 121 Aller plus loin : chiffrement et authentification SSL 4 4.7 Affiner le filtrage

Il est possible d’affiner encore plus le filtrage des certificats clients, par deux méthodes :

→ Les authentifications « basic » que l’on connaît déjà ;

→ Le filtrage sur les données du certificat.

4.7.1 Authentification Basic

Ajoutons les lignes suivantes dans la configuration d’Apache : Fichier SSLOptions +FakeBasicAuth AuthName «Snake Oil Authentication» AuthType Basic AuthBasicProvider file AuthUserFile /srv/www/users.mapetiteentreprise

L’option FakeBasicAuth permet à Apache de transformer le DN du certificat en nom d’utilisateur HTTP Basic. Ainsi, il devient possible d’utiliser les providers à disposition, que ce soit « file », « ldap » ou un autre.

Dans la base à vérifier (fichier ou base LDAP), le nom vérifié sera donc le DN complet du certificat et le mot de passe sera obligatoirement la chaîne xxj31ZMTZzkVA, qui est la version chiffrée DES du mot password. Une entrée du fichier /srv/www/users.mapetiteentreprise pourra donc être : Fichier /C=FR/ST=Alsace/L=Selestat/O=Ma petite entreprise/ CN=alice:xxj31ZMTZzkVA

Avec cette simple ligne, Alice peut se connecter au répertoire en question (/prive par exemple), mais pas Bob, absent de ce fichier. Vous comprendrez tout l’intérêt de cette approche en la mixant avec une authentification LDAP ou MySQL, qui permettent de faire des vérifications plus poussées par rapport à des données stockées dans la base.

4.7.2. Filtrage sur le certificat

Il est également possible d’obtenir un fonctionnement de tri C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 presque équivalent en filtrant les utilisateurs sur la base d’une partie de leur DN. Par exemple, la ligne suivante : Fichier SSLRequire ${SSL_CLIENT_S_DN_L} in {«Selestat», «Paris», «Bourg- en-Bresse»}

122 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe Aller plus loin : chiffrement et authentification SSL

permettra de n’autoriser que les utilisateurs qui sont localisés à Sélestat, à Paris ou à Bourg-en-Bresse ; un utilisateur identifié comme provenant de Pau (cas d’une société ayant de nombreuses agences par exemple) ne pourra pas avoir accès à cette partie du site. C’est là une forme plus simple de sélection, basée sur la politique de production des certificats, qui peut être très intéressante dans le cadre d’une entreprise. Le champ OU (unité organisationnelle) permettrait ainsi de restreindre les accès à tout ou partie d’un site en fonction du service auquel appartient le visiteur. Notons cependant que cette approche a un inconvénient de taille : si jamais une personne change de service ou de localisation géographique, il lui faut un nouveau certificat client ; avec une identification basée sur une base LDAP ou MySQL par exemple, l’utilisateur peut conserver le même certificat, son changement de statut étant intégré directement dans la base centralisée. Comme on peut le voir, le serveur HTTP Apache offre une grande souplesse quant à l’authentification cliente en mettant en place des mécanismes simples et relativement faciles à configurer. Tout ce qu’il faut, c’est une bonne politique de gestion de certificats et un peu d’ordre...

Conclusion Finalement, ce qui semble à première vue un simple chiffrement de communications (permettant d’éviter le vol de mots de passe ou la transmission en clair de données) forme un vaste domaine. Nous avons traité ici d’une partie relativement basique du support de SSL. Nous n’avons pas couvert tous les aspects de ce protocole et des logiciels qui gravitent autour ; nous n’avons par exemple pas abordé la gestion en ligne des identités, la révocation des certificats (point très important), la déconnexion, etc. Ce dernier point est d’ailleurs un cauchemar pour qui expérimente les systèmes d’authentification avec Firefox ou d’autres navigateurs. En effet, celui-ci n’offre pas beaucoup de fonctionnalités pour « oublier » un mot de passe ou l’association entre un site et un certificat. Bon nombre de fois, il faut quitter complètement le navigateur et le relancer pour que les modifications prennent effet. Quoi qu’il en soit, voici une voie toute tracée pour offrir un niveau de sécurité respectable pour votre ou vos site(s). N’hésitez pas à explorer davantage le sujet ! ▪ C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 Références Module SSL d’Apache : http://httpd.apache.org/docs/2.4/mod/mod_ssl.html Les certificats dans Firefox : http://support.mozilla.org/fr/kb/parametres-avances#w_certificats

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 123 35 C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5

124 GNU/LiNUxGN U/Li N Ux maGaziNe Hors-série N°66 : apacHe tUtorieLs 5 à découvrir dans cette partie... page 126 Installer LAMP sur Ubuntu Ubuntu : la distribution Linux la plus populaire de nos jours. LAMP : Linux, Apache, MySQL, PHP, l'association la plus courante. Comment les mixer ?

page 130 Déménagement et redirection Lorsque votre site web change, il est plus agréable pour les visiteurs de ne pas être perdus dans les méandres du nouveau site. Avec la redirection, indiquez aux visiteurs la nouvelle adresse de la page qu'ils cherchent.

page 132 phpMyAdmin sur Ubuntu Les données dans une base c'est bien joli, mais comment y accéder manuellement ? phpMyAdmin est une interface graphique qui aide bon nombre de développeurs web. page 134 Protection contre les DoS avec « mod_evasive » L'une des attaques les plus courantes sur Internet est le déni de service. Il s'agit de surcharger un serveur de requêtes, afin de l'empêcher de répondre aux « vrais » visiteurs. « mod_evasive » offre une protection contre cette attaque.

page 136 Le framework Django sur Ubuntu Dans le développement web, il n'y a pas que PHP. Django est l'un des frameworks les plus connus, il permet de développer des sites et applications web flexibles très facilement... Installons-le ! C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 page 140 Statistiques avec AWStats Lorsque l'on a un site web, il peut être intéressant de savoir combien de visiteurs on accueille, quelles pages ils visitent, d'où ils viennent... AWStats s'appuie sur les logs d'Apache pour donner ces détails.

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 125 Tutoriel : installer LAMP sur Ubuntu 5 tUtorieLs installer Lamp sur Ubuntu AMP est l’acronyme de Linux, Apache, MySQL, PHP : c’est l’ensemble de technologies le plus couramment utilisé pour un site web dynamique. Ubuntu, c’est la distribution Linux la plus diffusée aujourd’hui parmi les personnes qui débutent, ou qui aiment les distributions faciles à utiliser. Normalement, avec tous les articles Lque nous venons de voir, vous êtes capable d’installer votre propre serveur LAMP... Mais vu qu’on est gentils, voici un récapitulatif de l’installation d’un tel serveur.

Système Accès SSH d’exploitation Parce qu’il est plus agréable de travailler de son bureau et sur son PC habituel que Partons sur un système d’exploitation Ubuntu debout dans une salle serveur, accédons au serveur par 1LTS Server, supporté pendant 5 ans après sa parution : 2 SSH à partir d’un poste de travail. on a le temps de voir venir ! On peut trouver la dernière version d’Ubuntu Server à l’adresse http://www.ubuntu. Sous Linux (Ubuntu ou autre), ouvrir un terminal et com/download/server. taper : Terminal Nous n’entrerons pas dans le détail à propos de la procédure d’installation d’Ubuntu : cette installation reste ~$ ssh @ tout à fait classique – si vous n’avez jamais installé Ubuntu en mode texte (ou Debian – l’interface est similaire), gardez où est à remplacer par le nom C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 simplement à l’esprit que tout se fait au clavier, qu’on d’utilisateur et par l’adresse IP du serveur. passe d’un champ à l’autre avec la touche [Tabulation] et Sous Windows, utiliser Putty et renseigner l’adresse IP qu’on coche les cases avec la touche [Espace]. du serveur. Dans ce tutoriel, nous évoquons un serveur Ubuntu Une confirmation sera demandée afin d’accepter le 12.04 installé en langue française. à l’étape « Sélection « fingerprint » du serveur, puis le mot de passe sera de logiciels », on choisit uniquement le serveur OpenSSH. demandé (ainsi que le nom d’utilisateur avec Putty).

126 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe Tutoriels : installer LAMP sur Ubuntu

On se retrouve alors face au prompt standard d’Ubuntu : Terminal @:~$

Installation des logiciels Une fois connecté sur le serveur, la première chose à faire est d’installer les logiciels que nous souhaitons : le serveur web Apache, le serveur de 3bases de données MySQL, le langage de programmation PHP, le module PHP pour Apache, le module MySQL pour PHP. Cela se fait avec la commande suivante : Terminal ~$ sudo apt-get install apache2 mysql-server-5.5 libapache2- mod-php5 php5-mysql

En retour de cette commande, le système indique l’ensemble des paquets qui vont être installés (ceux que l’on demande, ainsi que leurs dépendances), il demande de confirmer cette installation : Terminal 0 mis à jour, 26 nouvellement installés, 0 à enlever et 18 non mis à jour. Il est nécessaire de prendre 35,8 Mo dans les archives. Après cette opération, 121 Mo d’espace disque supplémentaires seront utilisés. Souhaitez-vous continuer [O/n] ?

On confirme alors en appuyant sur la touche [Entrée]. Pendant la procédure d’installation, le mot de passe pour le compte d’administration de MySQL est demandé (dans un écran nommé « Configuration de mysql-server-5.5 ») ; il est conseillé de ne pas utiliser le même mot de passe que celui de la session utilisateur. Un second écran demande de confirmer ce mot de passe. Grâce au travail des mainteneurs des paquets Ubuntu, la procédure d’installation met automatiquement en place l’ensemble des éléments nécessaires, configuration d’Apache pour utiliser le module PHP comprise : à partir de là, l’ensemble LAMP est installé ! Par précaution, relançons Apache : Terminal ~$ sudo service apache2 restart C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 Page de test PHP Pour valider le bon fonctionnement de ce serveur, mettons en place une page simple de test en PHP... Pour cela, nous allons utiliser les commandes 4suivantes, afin de créer le fichier /var/www/test.php :

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 127 Tutoriels : installer LAMP sur Ubuntu

5 Terminal ~$ cat << EOF > /tmp/test.php


EOF sudo cp /tmp/test.php /var/www/

Une fois ce fichier créé, nous pouvons y accéder par l’adresse http:///test.php à partir d’un navigateur web. Une page de confirmation doit alors s’afficher, contenant un titre « Bonjour ! », ainsi que les détails sur l’instance de PHP en fonctionnement (retour La page test.php s’affiche avec succès. de la commande phpinfo()).

Base SQL Pour toute application dynamique basée sur LAMP, il faut une base de données. Créons donc une telle base au sein de MySQL, avec les 5commandes suivantes : Terminal ~$ mysqladmin -u root -p create base_test

Cette commande demande alors le mot de passe de l’administrateur de MySQL afin de créer une base s’appelant base_test. Elle ne retourne rien si cela réussit. On peut confirmer la création de cette base avec la commande suivante : Terminal ~$ mysql -u root -p -e «SHOW DATABASES»

Son retour doit être : Terminal +------+ | Database | +------+ | information_schema | | base_test | | mysql | | performance_schema | | test | +------+

Notre nouvelle base est bien dans la liste. C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 Utilisateur SQL Créons ensuite un utilisateur pour accéder à cette base ; pour cela, utilisons la commande suivante : 6 Terminal ~$ mysql -u root -p -e «GRANT ALL PRIVILEGES ON base_test.* TO user_test IDENTIFIED BY ‘testpass’»

128 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe Tutoriels : installer LAMP sur Ubuntu

Encore une fois, cette commande ne retourne rien et c’est normal. Le mot de passe testpass est bien sûr trop peu fiable ! Sur un serveur en production, vous utiliserez un mot de passe solide. Pour valider que l’utilisateur est bien créé, passons par lui pour ajouter une table dans la base : Terminal ~$ mysql -u user_test -p -e «CREATE TABLE t (c CHAR(20))» base_test

Enfin, vérifions l’existence de cette table : Terminal ~$ mysql -u user_test -p -e «SHOW TABLES» base_test

Cette commande devrait retourner : Terminal +------+ | Tables_in_base_test | +------+ | t | +------+

PHP et MySQL Il nous reste à valider que PHP peut bien accéder à la base MySQL... Créons donc un petit script qui va compter le nombre de lignes dans cette table de test : 7 Terminal ~$ cat >> EOF < /tmp/testsql.php query(‘SELECT COUNT(*) FROM t’); $count = $result->fetch_row(); $result->close(); $mysqli->close(); ?>

J’ai compté entrées dans la table.

EOF sudo cp /tmp/testsql.php /var/www/

Si on accède à l’adresse http:///testsql.php avec un navigateur, on obtiendra donc une page nous indiquant : J’ai compté 0 entrées dans la table. C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 Ajoutons deux entrées dans la table avec la commande suivante : Terminal ~$ mysql -u user_test -p -e «INSERT INTO t SET c=’un’; INSERT INTO t SET c=’deux’» base_test

Puis rechargeons la page, qui nous indiquera alors : J’ai compté 2 entrées dans la table. ▪

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 129 Tutoriel : installer LAMP sur Ubuntu 5 tUtorieLs déménagement et redirection omme dans la « vraie vie », lorsque l’on déménage ou réorganise un serveur, il vaut mieux prévenir ses visiteurs. Le code d’erreur HTTP 301 (Moved Permanently) est là pour ça. Voyons comment l’utiliser avec C Apache.

▶ soit on change l’arborescence, que ce soit en Activation du conservant la même adresse ou en la changeant. module Dans le premier cas, c’est simple : il faudra rediriger Nous allons utiliser la directive les visiteurs vers la nouvelle adresse, c’est tout. Dans le Redirect dans ce but, cette direc- second cas, il est nécessaire de faire la liste exhaustive tive1 étant proposée par le module mod_alias. Ce des adresses concernées. On peut très bien cumuler module est activé par défaut dans Ubuntu (et a for- les deux, avoir une sous-arborescence qui ne change tiori Debian), il ne devrait pas y avoir à l’activer ; mais pas alors que le reste change, par exemple... faisons-le tout de même, par acquit de conscience : Sur un petit site, une telle liste pourrait par exemple Terminal être la suivante : ~$ sudo a2enmod alias ▶ /Accueil → / ▶ /Accueil/A_Propos → /a-propos Il y a de fortes chances que cette commande réponde : ▶ /Informations → /a-propos Terminal ▶ /Nos_Offres → /offres Module alias already enabled ▶ /Nous_Contacter → /nous-contacter ▶ /Blog → /news ▶ /Blog/* → /news/* (dans ce dernier cas, Identification imaginons que les adresses relatives des articles des de ce blog ne changent pas) redirections Pour les exemples suivants, nous imaginerons que l’adresse du site passe de public.ma-petite- Dans le cadre d’une réorganisation ou 2 entrepri.se www.ma-petite-entrepri.se à .

C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 d’un « déménagement » d’un site web, une redirection consiste à faire pointer une ancienne adresse vers une nouvelle adresse. Il faut donc d’abord consciencieuse- Configuration ment faire la liste de ces adresses et correspondances. à modifier On peut en réalité rencontrer deux cas de figure : Bien sûr, pour que ces redirections ▶ soit on déménage tout bonnement le site sur une 3 fonctionnent, il faut que l’« ancien site » autre adresse, mais en conservant l’arborescence soit toujours desservi. Sauf qu’au lieu de desservir du site, des pages, il ne desservira que des redirections.

130 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe Tutoriels : déménagement et redirection

Encore une fois, on retrouve deux cas de figure : Redirections ▶ soit il s’agit d’une réorganisation au sein du même site, auquel cas il suffit d’ajouter les directives que avec regexp nous verrons plus bas dans la configuration de On peut également définir des redirections l’hôte virtuel concerné, avec des expressions rationnelles, afin de prendre5 en compte, en une seule règle, plusieurs adresses. ▶ soit il s’agit d’un changement d’adresse complet, Une telle redirection prend la forme suivante : auquel cas il faut desservir l’ancien site, par Fichier exemple en tant qu’hôte virtuel sur le même serveur que le nouveau site. RedirectMatch permanent Quoi qu’il en soit, il s’agit bien d’une configuration liée à l’« ancien » site et non d’une configuration L’expression rationnelle doit être relative à la racine du site, du « nouveau » site. Dans notre exemple, il s’agirait comme pour la directive Redirect. Le nouveau chemin donc de configurer le serveur HTTP du site public. peut faire appel à la variable $1, qui contiendra la section ma-petite-entrepri.se. mise entre parenthèses dans l’expression rationnelle. Rien de mieux qu’un exemple pour comprendre cela : Redirections Fichier simples RedirectMatch permanent /Blog/(.*)$ http://www.ma-petite-entrepri.se/news/$1 Maintenant que l’on a identifié la liste des4 redirections à prendre en compte, on peut les mettre en place. Une redirection simple (une page pointe sur une page) se définit de la manière suivante : Redirections Fichier temporaires Redirect permanent Terminons ce tutoriel sur une autre possibilité intéressante : les redirections temporaires.6 Chacun pourra imaginer une situation dans Le chemin original doit obligatoirement être relatif à laquelle il aurait besoin d’une redirection temporaire la racine du site : il ne doit pas contenir le nom DNS. (site ou page « en travaux » par exemple) : dans ce Le nouveau chemin peut être soit une URL complète cas, il suffit de remplacer la mention permanent par (notamment dans le cas d’un changement de l’adresse temp, voire de l’enlever totalement (sa valeur par défaut du site), soit un relatif à la racine du site (cas où on est temp). On pourra par exemple retrouver la ligne reste sur la même URL de base).Ces directives sont à suivante : mettre en place dans la configuration de l’hôte virtuel Fichier du site d’origine. Dans notre exemple, la configuration RedirectMatch /news/.* /news-en-travaux de ces redirections simples serait la suivante : Fichier ServerName public.ma-petite-entrepri.se Effet sur les [...] clients web Redirect permanent /Accueil De cette manière, un visiteur de l’ancien http://www.ma-petite-entrepri.se/ site sera immédiatement et correctement Redirect permanent /Accueil/A_Propos redirigé7 vers le nouveau site, et la nouvelle adresse http://www.ma-petite-entrepri.se/a-propos apparaîtra bien dans sa barre d’adresse. Le code d’erreur Redirect permanent /Informations 301 permet également aux robots web (celui du moteur http://www.ma-petite-entrepri.se/a-propos

C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 de recherche de Google par exemple) de prendre note Redirect permanent /Nos_Offres de ce changement et de le prendre en compte dans le http://www.ma-petite-entrepri.se/offres Redirect permanent /Nous_Contacter référencement. Si l’on utilise le code 302 (redirection http://www.ma-petite-entrepri.se/ temporaire), alors la redirection n’est pas prise en compte nous-contacter dans ce cadre. On pourrait même imaginer un navigateur Redirect permanent /Blog http://www. web qui mettrait les favoris à jour lorsque l’on rencontre ma-petite-entrepri.se/news une telle erreur 301... Mais ce n’est pas le cas aujourd’hui, probablement pour ne pas faire de tels changements « dans le dos de l’utilisateur ». ▪

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 131 Tutoriel : installer LAMP sur Ubuntu 5 tUtorieLs phpmyadmin sur Ubuntu eut-être voudrez-vous pouvoir administrer votre base de données SQL à partir d’une interface web ? Ça peut être bien plus pratique ! L’outil le plus utilisé dans ce cadre, surtout avec un serveur LAMP, c’est phpMyAdmin. Et, encore une P fois, un paquet est directement disponible dans Ubuntu.

Accès à Installation l’interface Grâce au paquet proposé par Ubuntu (dans nos exemples, en version 12.04 LTS), l’installation de phpMyAdmin sera Et voilà, phpMyAdmin est ultra-simple1 : 2 installé ! Nous pouvons y accéder avec un navigateur web, Terminal à l’adresse http://

C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 L’installeur demande également de définir un mot de passe de connexion pour phpmyadmin. Dans la mesure où nous n’avons pas besoin de connaître ce mot de passe, laissons ce champ vide pour forcer le système à générer un mot de passe aléatoire. En effet, ce mot de passe correspond à la base qui stocke les données propres à phpMyAdmin et non aux informations Écran de connexion de nécessaires pour se connecter par après. phpMyAdmin

132 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe Tutoriels : phpMyAdmin sur Ubuntu

Accès à la base souhaitée Une fois connecté sur un compte MySQL avec phpMyAdmin, un écran3 global est affiché, permettant de manipuler le serveur MySQL (dans la limite des droits donnés à l’utilisateur avec lequel nous nous sommes connectés). Cet écran présente, sur sa gauche, la liste des bases auxquelles on peut accéder ; dans notre exemple, cette liste contient notamment la base Vue sur une base base_test. Cliquons sur ce lien pour accéder à la base...

Modification des données Pour modifier les données d’une table (insérer, modifier ou supprimer4 des entrées), il suffit de cliquer sur son nom dans la liste Structure. La liste des entrées de la table est alors présentée dans un onglet Afficher : dans cette liste, les liens Modifier, Éditer en place et Effacer permettent d’agir sur les enregistrements existants. L’onglet Insérer, quant à lui, permet de créer de nouvelles entrées. Vue sur une table ; à gauche de la page, on retrouve la liste des tables, permettant un accès direct.

Utilité de phpMyAdmin Demandons-nous toutefois si cet outil est vraiment utile. Sur un serveur de développement, lorsque l’on code directement en précisant les commandes SQL et en définissant soi-même la structure5 de la base, son utilité est indéniable. Si on utilise des technologies récentes pour développer, notamment un outil d’ORM (Object-Relational Mapping – comme Doctrine 2 avec PHP, ou SQLAlchemy avec Python), il n’y a plus nécessairement besoin de contrôler finement la base de données. Et sur un serveur de production, on n’est pas censé C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 « tripoter » la base de données, phpMyAdmin devient alors totalement inutile, voire dangereux. Sur un serveur de production, il est donc conseillé de supprimer cet outil : Terminal ~$ sudo apt-get purge phpmyadmin ▪

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 133 Tutoriel : installer LAMP sur Ubuntu 5 tUtorieLs protection contre les dos avec « mod_evasive » armi les nombreuses attaques qui peuvent exister sur Internet, les DoS (Denial of Service, déni de service) sont les plus courantes. Il s’agit pour l’attaquant d’envoyer tellement de requêtes que le serveur n’est plus capable de toutes les desservir, les « vraies » requêtes étant alors noyées au milieu de dizaines ou centaines de milliers Pde requêtes diverses. Le module « mod_evasive » permet de limiter ces attaques.

Installer mod_evasive Sur Debian et Ubuntu, l’installation de mod_evasive est très simple : 1 Terminal ~$ sudo apt-get install libapache2-mod-evasive

Pour une fois, le paquet ne met pas en place de configuration particulière : il se contente d’activer le module. Il faut donc le configurer.

C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 Préparer le système Nous allons stocker les informations relatives aux attaques dans le répertoire /var/log/apache2/mod_evasive, il faut donc le créer : 2 Terminal ~$ sudo mkdir /var/log/apache2/mod_evasive ~$ sudo chown www-data.www-data /var/log/apache2/mod_evasive

134 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe Tutoriels : protection contre les DoS avec « mod_evasive »

Terminal Configurer ~$ sudo apt-get install fail2ban Apache Voici un exemple de configuration Ce logiciel est un démon, qui se lance d’Apache3 pour ce module, à mettre en place par automatiquement dès son installation. exemple dans le fichier /etc/apache2/ conf.d/evasive (à créer) : Fichier Filtre DOSHashTableSize 3097 # Pas plus de 5 pages toutes les 2 « mod_evasive » secondes DOSPageCount 5 pour Fail2ban DOSPageInterval 2 6 Créons le fichier /etc/fail2ban/filter.d/ # Pas plus de 100 requêtes par seconde apache-modevasive.conf : (images, CSS...) DOSSiteCount 100 Fichier DOSSiteInterval 1 [Definition] # Bloquer le client pendant 10 secondes failregex = ^\[[^\]]*\]\ DOSBlockingPeriod 10 s+\[error\]\s+\[client # Dossier contenant les IP blacklistées \] client denied by DOSLogDir «/var/log/apache2/mod_ server configuration:\s evasive» ignoreregex =

On recharge ensuite la configuration... Ce fichier servira à identifier les lignes indiquant Terminal qu’un client a été bloqué. ~$ sudo service apache2 reload Ajoutons ensuite les lignes suivantes au fichier /etc/fail2ban/jail.local (créons ce Et voilà ! mod_evasive est prêt à fonctionner ! fichier si nécessaire) : Fichier Interaction [apache-dosevasive] enabled = true avec Fail2ban filter = apache-dosevasive Fail2ban est un logiciel plus général, action = iptables- ayant pour objectif de bloquer, via allports[name=apache- 4 dosevasive] une règle de pare-feu, les tentatives de connexion en erreur répétées, quel que soit le service logpath = /var/log/ apache2/*/error.log concerné. On peut l’utiliser conjointement avec bantime = 60 mod_evasive pour bloquer les adresses IP bantime = 3600 « agressives » en amont. L’approche utilisée consiste maxretry = 10 à surveiller les logs d’Apache et, lorsqu’une ligne de log relative à mod_evasive est trouvée, bloquer l’adresse IP correspondante dans le pare-feu. Avec cette configuration, Fail2ban bloquera pendant une heure au niveau du pare-feu tout Cela n’est pas obligatoire, mais cela allège la charge client qui aura été bloqué au niveau du serveur du serveur : cet aspect est à ne pas négliger ! Apache (avec une erreur 403) plus de 10 fois en

C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 une minute. Installation de Avec ces deux outils, nous voilà prêts à « encaisser » des attaques de type DoS ! L’étape Fail2ban supérieure serait de placer un tel filtrage en 5 Comme tous les logiciels que l’on a vus amont, sur un reverse proxy par exemple, pour jusqu’ici, Fail2ban s’installe aisément à partir des que ces requêtes n’arrivent même pas sur le ou paquets Debian ou Ubuntu : les serveur(s) ! ▪

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 135 Tutoriel : installer LAMP sur Ubuntu 5 tUtorieLs Le framework django sur Ubuntu e nombreux frameworks web sont proposés aujourd’hui, basés sur la plupart des langages de programmation. Parmi eux, on retrouve Django, programmé en Python ; son slogan est « le framework web pour les perfectionnistes sous pression ». Ce framework (ou plateforme de développement) web offre de nombreusesD fonctionnalités de haut niveau : représentation des données sous forme d’objets, interface d’administration automatiquement créée, système de templates, système de cache, internationalisation... Utilisé par de nombreux sites d’envergure, il a séduit beaucoup de développeurs.

On peut vérifier que Django est bien installé et Installation fonctionnel avec la commande suivante : Django n’est pas en PHP, il ne repose Terminal donc pas sur une plateforme LAMP ~$ python -c «import django; 1 classique ; nous ne commencerons print django.get_version()» donc pas à la fin du tutoriel « Installer LAMP sur Ubuntu », mais estimerons que le système Sur Ubuntu 12.04, celle-ci doit retourner : d’exploitation Ubuntu 12.04 est installé. Terminal Ubuntu 12.04 propose Django en version 1.3 : un peu vieillissante, mais éprouvée... Comme 1.3.1 tout produit proposé dans une version LTS d’Ubuntu, ou dans n’importe quelle version de Debian. Et, pour changer, nous allons le faire interagir avec le serveur de bases de données Commencer PostgreSQL. un projet C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 Installons donc tous ces outils : Django Terminal 2La première étape est de créer un projet. Pour cela, ~$ sudo apt-get install plaçons-nous d’abord dans un répertoire approprié, apache2 libapache2-mod-wsgi python-django postgresql qu’il faut avant tout créer ; profitons-en également python-psycopg2 pour nous donner les droits dessus « en tant qu’utilisateur » :

136 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe Tutoriels : le framework Django sur Ubuntu

Terminal Fichier ~$ sudo mkdir /srv/django ADMINS = ( ~$ sudo chown $(whoami).$(whoami) (‘Moi-meme’, ‘webmaster@ma-petite- /srv/django entrepri.se’), cd /srv/django ) DATABASES = { ‘default’: { Ensuite, créons notre premier projet avec ‘ENGINE’: ‘django.db.backends. Django : postgresql_psycopg2’, ‘NAME’: ‘django_base’, Terminal ‘USER’: ‘django_test’, ~$ django-admin startproject ‘PASSWORD’: ‘mot_de_passe’, projet_test ‘HOST’: ‘127.0.0.1’, ‘PORT’: ‘’, } Le répertoire projet_test est alors créé, avec les } fichiers de base d’un projet Django. TIME_ZONE = ‘Europe/Paris’ LANGUAGE_CODE = ‘fr-fr’ STATIC_ROOT = ‘/srv/django/projet_ test/static’

Base de Créons également un répertoire pour les futurs données fichiers statiques à desservir : Créons ensuite une base de données Terminal 3 PostgreSQL pour Django : ~$ mkdir /srv/django/ Terminal projet_test/static ~$ sudo su - postgres ~$ createuser -D -R -S -P django_test ~$ createdb -O django_test Créer une django_base application exit Un projet Django peut être composé d’une ou plusieurs application(s). Par La seule interactivité dans ces commandes 5 exemple, vous pouvez avoir une application pour est au niveau de la commande createuser, gérer des utilisateurs et une autre application pour qui demande le mot de passe pour l’utilisateur publier des articles, tout ça dans un seul projet. « django_test ». Créons donc une première application : Terminal ~$ cd /srv/django/projet_test Configurer le ~$ python manage.py startapp projet app_test Il est également nécessaire de Un répertoire app_test est ainsi créé, contenant configurer notre projet Django. Cette 4 les fichiers de base pour une application Django. configuration s’effectue dans le fichier settings. Cette application doit également être activée, en py du répertoire projet_test. Il faut définir : ajoutant son nom à la variable INSTALLED_APPS le nom et l’adresse e-mail de l’administrateur, la du fichier settings.py du projet :

C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 méthode d’accès à la base de données, le fuseau Fichier horaire, le code langue par défaut, le chemin des fichiers statiques. INSTALLED_APPS = ( ‘django.contrib.auth’, Il y a de nombreux autres paramètres dans ce [...] fichier, mais contentons-nous de ceux-là au début. ‘app_test’ Avec notre exemple, ce sont les lignes suivantes ) qu’il faut adapter : Tutoriels : le framework Django sur Ubuntu 5 Définir les Terminal données ~$ python manage.py syncdb Les données à stocker dans la base sont Dans le fichier url.py (qui centralise les 6 définies dans le fichier models.py de « chemins » des différentes URL vers les fonctions l’application. Créons une simple classe : des applications), décommenter les lignes relatives à l’administration ; le fichier doit alors ressembler Fichier à cela (hors commentaires) : from django.db import models Fichier class Article(models.Model): from django.conf.urls.defaults titre = models.CharField(max_ import patterns, include, url length=200) contenu = models.TextField() from django.contrib import admin admin.autodiscover() urlpatterns = patterns(‘’, On crée ensuite réellement les données grâce à la [...] commande suivante : url(r’^admin/’, include(admin. Terminal site.urls)), ) ~$ python manage.py syncdb

Pour que l’interface d’administration sache Celle-ci pose les questions suivantes, cet exemple qu’elle doit permettre de modifier les données de indique des réponses possibles : l’application app_test, il faut créer le fichier Terminal app_test/admin.py : Would you like to create Fichier one now? (yes/no): yes Username (Leave blank to from app_test.models import use ‘glmf’): admin Article E-mail address: webmaster@ from django.contrib import admin ma-petite-entrepri.se Password: admin.site.register(Article) Password (again): Les fichiers statiques de cette application doivent Ces informations sont demandées, car l’application également être collectés, grâce à la commande django.contrib.auth est activée, aux côtés suivante : d’app_test. Si on n’a pas besoin de gestion Terminal d’utilisateurs, on peut simplement désactiver cette ~$ python manage.py collectstatic application en supprimant la ligne idoine du fichier settings.py. Lorsque cette commande rend la main, les données sont créées dans la base. Configuration Interface d’Apache d’administration Notre projet Django, bien que très Pour activer l’interface d’administration limité8 (nous n’avons notamment défini aucune page à part l’interface d’administration), peut d’ores et C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 automatique,7 différentes opérations sont nécessaires. déjà être desservi. Tout d’abord, décommenter la ligne ‘django. contrib.admin’ dans la section INSTALLED_APPS Pour qu’Apache puisse le desservir, les lignes pour activer cette application (l’interface d’administration suivantes doivent être ajoutées à l’hôte virtuel est une application comme une autre). Ensuite, (nous utiliserons pour cet exemple simplement ré-exécuter la commande suivante pour créer les tables l’hôte virtuel par défaut, à vous de définir un hôte nécessaires à cette application : virtuel adapté à vos besoins) :

138 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe Tutoriels : le framework Django sur Ubuntu

Fichier mot de passe. Sans surprise, si on renseigne le nom donné lors de l’initialisation (admin dans notre WSGIScriptAlias / /srv/django/ projet_test/wsgi.py exemple) et son mot de passe, on accède à l’interface Alias /static/ /srv/django/projet_ d’administration de Django. test/static/

La ligne suivante doit être mis en place en dehors de l’hôte virtuel (par exemple dans /etc/apache2/conf.d/wsgi) : Fichier WSGIPythonPath /srv/django Connexion à l’interface d’administration Le fichier /srv/django/projet_test/ wsgi.py doit également être créé (il est On peut alors constater qu’on a déjà accès à la automatiquement créé à partir de Django 1.4, configuration de différentes applications, dont celle avec un contenu légèrement différent) : d’authentification et notre application de test. On peut d’ores et déjà entrer des données pour Fichier notre site ! import os import sys path = ‘/srv/django’ if path not in sys.path: sys.path.append(path) os.environ.setdefault(«DJANGO_ SETTINGS_MODULE», «projet_test. settings») import django.core.handlers.wsgi application = django.core.handlers. wsgi.WSGIHandler() Interface d’administration de Django

Accès Le contenu On peut maintenant accéder à notre du site projet Django ! Si on essaie d’atteindre Ce tutoriel avait pour but la racine du serveur, une erreur 404 10 de mettre en place un est9 obtenue : comme l’indique le message, nous serveur web basé sur le framework Django, c’est n’avons pas précisé de chemin à desservir pour la chose faite, il est fonctionnel. Il faut maintenant racine dans urls.py. approfondir l’utilisation de ce framework ; des livres entiers traitent de ce sujet, imaginez bien que nous ne pouvons pas en faire de même dans un simple tutoriel. Mais si ce framework vous plaît, vous êtes invité à suivre la documentation officielle de Django, notamment son tutoriel, bien

C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 plus complet (et plus long) que celui-ci : https://docs.djangoproject.com/en/1.3/

Erreur 404 : aucune page n’est définie à la racine. intro/tutorial01/. Vous pouvez également consulter le document Nous pouvons alors accéder à l’interface « Django raconté à un ami », qui présente le grand d’administration, par le chemin /admin. On est avantage d’être écrit en français : http://django- alors invité à entrer un nom d’utilisateur et un story.readthedocs.org/fr/latest/. ▪

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 139 Tutoriel : le framework Django sur Ubuntu 5 tUtorieLs statistiques avec awstats e nos jours, l’outil le plus populaire pour faire des statistiques sur le Web est probablement Google Analytics ; mais cet outil (et tous ceux qui sont basés sur le même principe) présente deux gros inconvénients : les données sont stockées « dans les nuages » – on ne maîtrise pas leur stockage – et si JavaScriptD est désactivé chez un visiteur, il ne sera pas comptabilisé. AWStats s’appuie sur les logs du serveur web, auxquels aucun visiteur ne peut échapper, pour donner des statistiques détaillées...

Format des logs AWStats est capable de comprendre et d’analyser de nombreux formats de fichiers de logs différents. Nous allons simplement utiliser le format combined, qui est configuré par défaut dans le paquet Apache d’Ubuntu et Debian ; c’est également 1celui que nous avons abordé dans notre article « Configuration basique ». Par défaut, on rencontrera donc la directive suivante : Fichier CustomLog ${APACHE_LOG_DIR}/access.log combined

Chemin des logs Lorsque l’on dessert plusieurs sites web, il est préférable de stocker les fichiers de logs de chaque site séparément. Mais même avec un seul site web, on peut C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 aussi « au cas où » placer ses logs dans un répertoire particulier : si jamais on ajoute2 d’autres sites par la suite, l’adaptation de la configuration sera plus simple. Créons donc un sous-répertoire dans le répertoire des logs d’Apache : Terminal ~$ mkdir /var/log/apache2/http-www.ma-petite-entrepri.se

140 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe Tutoriels : statistiques avec AWStats

Puis, définissons les directives de logs pour utiliser nombreuses directives : 173 directives différentes ce répertoire : activées dans la configuration par défaut. Fichier Concentrons-nous sur les directives les plus ErrorLog ${APACHE_LOG_DIR}/ importantes : http-www.ma-petite-entrepri. ▶ LogFile indique le fichier à analyser ; se/error.log ▶ LogType indique le type de fichier de logs à LogLevel warn CustomLog ${APACHE_LOG_DIR}/ analyser (W pour les logs d’un serveur web) ; http-www.ma-petite-entrepri. ▶ LogFormat indique le format des logs (le code se/access.log combined 4 correspond aux logs standards d’Apache) ; ▶ SiteDomain contient l’adresse du site ; ▶ DNSLookup permet de faire une résolution DNS sur les adresses des visiteurs, afin Installation d’afficher mieux qu’une adresse IP (cela ralentit AWStats est proposé comme paquet énormément le processus, il faut donc limiter son dans Debian et Ubuntu, son installation usage pour des « gros » sites). sera donc simple ; profitons-en pour Toutes les directives proposées par AWStats sont installer3 des dépendances intéressantes, notamment expliquées de manière très détaillée au sein même GeoIP : du fichier de configuration par défaut, n’hésitez pas Terminal à lire ces détails ! ~$ sudo apt-get install Dans notre exemple, il faut donc s’assurer que les awstats libgeo-ipfree-perl directives suivantes sont correctement configurées ou les adapter : Par défaut, le paquet Debian/Ubuntu d’AWStats Fichier est configuré afin de faire des statistiques sur le fichier de logs par défaut d’Apache (/var/log/ LogFile=»/var/log/apache2/http-www. apache2/access.log), toutes les dix minutes. ma-petite-entrepri.se/access.log» LogType=W LogFormat=4 Configuration SiteDomain=»www.ma-petite-entrepri.se» d’AWStats La configuration par défaut d’AWStats Exécution 4 se situe dans le fichier /etc/awstats/ awstats.conf. En réalité, awstats accepte régulière n’importe quel fichier de configuration de type Le paquet Debian/Ubuntu d’AWStats /etc/awstats/awstats.*.conf. Cela permet met en place l’exécution régulière d’AWStats5 dans le fichier /etc/cron.d/awstats, de créer un fichier de configuration pour chaque site à prendre en compte. Copions donc, puis désactivons contenant notamment la ligne suivante : la configuration par défaut : Fichier Terminal */10 * * * * www-data [ -x /usr/ ~$ sudo cp /etc/awstats/ share/awstats/tools/update.sh ] && awstats.conf /etc/awstats/ /usr/share/awstats/tools/update.sh awstats.http-www.ma-petite- entrepri.se.conf Si l’on veut changer la périodicité de cette C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 ~$ sudo mv /etc/awstats/ exécution, il suffit de modifier les 5 premiers awstats.conf /etc/awstats/ champs, par exemple : awstats.conf.disabled ▶ 0 * * * * : toutes les heures ; Éditons ensuite ce fichier /etc/awstats/ ▶ */30 * * * * : toutes les demi-heures ; awstats.http-www.ma-petite-entrepri. ▶ 0 2 * * * : tous les jours, à deux heures du se.conf ; on peut remarquer qu’il contient de matin.

GNU/LiNUx maGaziNe Hors-série N°66 : apacHe 141 Tutoriels : statistiques avec AWStats

5 Vous trouverez plus de détails sur cette syntaxe Activons le module rewrite et rechargeons la dans la page de manuel idoine : configuration : Terminal Terminal ~$ man 5 crontab ~$ sudo a2enmod rewrite ~$ sudo service apache2 reload

On peut maintenant accéder aux statistiques avec Desservir l’adresse suivante : http://stats.ma-petite-entrepri. AWStats se/http-www.ma-petite-entrepri.se. Le programme principal awstats. pl est installé dans le répertoire /usr/ Directives 6lib/cgi-bin : il s’exécute sous forme de script CGI. partagées Ce script prend comme argument le nom du site tel Si vous mettez en place des statistiques que défini dans le nom de fichier, dans une variable sur plusieurs hôtes virtuels, il est possible config. Lorsqu’un site est configuré pour desservir que7 vous ayez besoin de mettre en place certaines les CGI provenant de ce répertoire, il suffit donc d’y directives communes à tous les hôtes (LogFormat accéder par l’adresse habituelle des scripts CGI. par exemple). Dans ce cas, plutôt que de les répéter Pour notre exemple, l’adresse complète pourrait être : encore et encore, vous pouvez les supprimer des http://www.ma-petite-entrepri.se/cgi-bin/awstats. fichiers awstats.*.conf et les mettre dans le pl?config=http-www.ma-petite-entrepri.se. fichier awstats.conf.local : ce fichier est réuti- Mais faisons propre : créons un hôte virtuel lisé par tous les autres – voyez les dernières lignes de spécial pour AWStats, que nous appellerons ces fichiers pour en comprendre le fonctionnement. stats.ma-petite-entrepri.se dans notre Avec ce fonctionnement, vous pouvez aller jusqu’à exemple. Profitons-en pour simplifier l’accès aux réduire les fichiers de configuration à leur plus statistiques grâce à une règle de réécriture : simple expression : LogFile et SiteDomain. Fichier Vous en voulez ServerName stats.ma-petite-entrepri.se ServerAdmin webmaster@ma-petite- encore ? entrepri.se Ce tutoriel est fini : on a appris comment mettre en place des statistiques de base DocumentRoot /usr/lib/cgi-bin avec8 AWStats. Mais cet outil peut aller beaucoup plus SetHandler cgi-script Options +ExecCGI -MultiViews loin, libre à vous d’approfondir ! Il permet de : ▶ faire des statistiques à partir des logs de serveurs ErrorLog ${APACHE_LOG_DIR}/http-stats. de messagerie et de serveurs FTP ; ma-petite-entrepri.se/error.log CustomLog ${APACHE_LOG_DIR}/http- ▶ faire des statistiques à partir des logs de stats.ma-petite-entrepri.se/access.log Lotus Notes, Microsoft IIS ; combined ▶ affiner les statistiques à générer ; Alias /awstats-icon/ «/usr/share/ ▶ ignorer certaines requêtes (provenant de notre awstats/icon/» propre adresse notamment) ; Options Indexes MultiViews ▶ etc. ▪ FollowSymLinks AllowOverride None Order allow,deny

C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 Allow from all

RewriteEngine On RewriteRule ^/http(.*)$ /awstats. pl?config=http$1 [PT]

Exemple de rapport d’AWStats

142 GNU/LiNUx maGaziNe Hors-série N°66 : apacHe Ce documntslapriéxvj-g(@h.)26013à:5 Historique Introduction Fondation Tout ce qu’il faut savoir sur les Web origines d’Apache et Protocole HTTP sur ses principales fonctionnalités Fonctionnalités

Architecture Premiers pas Installation et de base con guration Installer son premier serveur et choisir Hôtes Les modules le mécanisme virtuels d’Apache d’authenti cation le plus adapté Back-ends

Web dynamique Programmer Scripts CGI pour le Web Con guration PHP, Python, Perl et Ruby : quelques bases pour Modules Solutions bien programmer avec les langages du Web

Annuaire Aller plus loin OpenLDAP Des éléments de Autorisations con guration avancée pour des besoins plus spéci ques Certi cats (LDAP, chiff rement, ...) SSL Filtrage

C e d o c u m n t s l a p r i é x v j - g ( @ h . ) 2 6 0 1 3 à : 5 LAMP/Ubuntu Tutoriels Redirections phpMyAdmin Des pas-à-pas pour passer rapidement à framework Django la pratique

Déni de service ���������������������������������� � EDITI NS

AWStats LES DIAMOND ���� www.ed-diamond.com