formations/cesi/hebergement_web/02-http.md

14 KiB

% Introduction au HTTP % Sylvain Eliade — S.C.O.P. Cadoles % Mai 2019

Introduction au HTTP

  • HyperText Transport Protocol
  • Protocole texte
  • Client-serveur
  • En général sur TCP, port 80
  • Stateless, aucun état n'est conservé entre les requêtes
  • Très simple
  • Requêtes toujours initiées par le client

À quoi ça ressemble ?

Un simple telnet permet de faire des requêtes HTTP !

% telnet sylvain.eliade.net 80
Trying 91.121.181.110...
Connected to eliade.net.
Escape character is '^]'.
GET /resume/ HTTP/1.1
Host: sylvain.eliade.net


Le serveur nous répond :

HTTP/1.1 200 OK
Date: Mon, 13 May 2019 10:02:02 GMT
Server: Apache
Last-Modified: Fri, 19 Apr 2019 07:36:32 GMT
ETag: "2abb-586dd2d7c21de"
Accept-Ranges: bytes
Content-Length: 10939
Vary: Accept-Encoding
Content-Type: text/html
Connection: close

<!DOCTYPE html>
<html>
…

Un outil plus pratique est quand même curl !

% curl -v http://sylvain.eliade.net/resume/

Structure d'une requête

Première ligne : MÉTHODE RESSOURCE PROTOCOLE

  • Méthode (ou verbe) HTTP = action que l'on souhaite utiliser (GET, DELETE, POST, etc.)
  • Ressource sur laquelle on souhaite effectuer l'action
  • Version du protocole : HTTP/1.0 ou HTTP/1.1 (il existe encore des clients HTTP/0.9 mais bon…)

Lignes suivantes : les entêtes. Puis : une ligne vide.

Puis éventuellement (méthodes POST, PUT, PATCH, etc.) : corps (contenu) de la requête.


Méthodes HTTP

  • GET : la plus courante, renvoie la ressource demandée (exemple : visualiser une page web)
  • POST : envoyer des données liées à la ressource (exemple : envoyer un formulaire web)

Les méthodes suivantes sont rarements utilisées par les navigateurs mais souvent dans les API :

  • HEAD : obtenir des infos sur la ressource. En pratique c'est souvent pareil que GET, mais ça ne renvoie que les entêtes et pas le corps.
  • PUT : ajouter / remplacer une ressource
  • OPTIONS : savoir quelles sont les méthodes supportées par le serveur pour une ressource

Structure d'une réponse

Première ligne : PROTOCOLE CODE MESSAGE

  • Code = code de réponse du serveur (200 = OK, 404 = Not Found, etc.)
  • Message = message de réponse associé au code

Lignes suivantes : les entêtes de réponse.

Puis : une ligne vide.

Puis éventuellement (tout le temps sauf avec requête HEAD) : corps de la réponse.


Codes de réponses HTTP

Le premier chiffre indique le type de code :

  • 1xx = requête reçue mais son exécution n'est pas terminée
  • 2xx = succès
  • 3xx = redirection
  • 4xx = erreur du client
  • 5xx = erreur du serveur

Codes courants

  • 200 OK = la plus courante
  • 301 Moved Permanently = ressource déplacée définitivement (voir l'entête Location pour la nouvelle adresse)
  • 302 Found = ressource déplacée temporairement
  • 400 Bad Request = erreur dans la requête du client
  • 401 Unauthorized = le client n'a pas accès, il lui faut s'authentifier
  • 403 Forbidden = accès refusé (par exemple mauvais login/mot de passe)
  • 404 Not Found = ressource non trouvée
  • 500 Internal Server Error
  • 503 Service Unavailable = serveur surchargé

Entêtes

Host: sylvain.eliade.net
User-Agent: telnet/1.0

Chaque entête est une clé (en général avec une majuscule au début de chaque mot, les mots étant séparés par des tirets), suivi de deux points :, d'un espace et de la valeur de l'entête.

Liste des entêtes : https://en.wikipedia.org/wiki/List_of_HTTP_header_fields


Entêtes courants pour les requêtes

  • Host : pour indiquer le nom de domaine que l'on essaye d'atteindre (car le serveur HTTP ne sais pas quelle requête DNS on a fait pour le contacter)
  • Accept-Language : indique les langues préférées du client (fr-BE, fr, en-AU, en)
  • Accept : les formats de fichier gérés par le client (text/html, image/jpeg…)
  • Connection : pour garder la connexion TCP ouverte pour faire plusieurs requêtes de suite
  • User-Agent : nom du client utilisé
  • Cookie : contenu d'un cookie
  • Authorization : identifiants de connexion HTTP (accès par mot de passe)

Entêtes courants pour les réponses

  • Connection : état de la connexion TCP
  • Date : date de réponse
  • Content-Type : type du contenu (text/html; charset=utf-8)
  • Location : nouvelle adresse du contenu quand il a changé d'adresse
  • Server : nom du serveur
  • Set-Cookie : le client doit enregistrer ce cookie
  • WWW-Authenticate : demande d'authentification

Aparté : les URLs

Uniform Resource Locator (interchangeable avec URI, Uniform Resource Identifier)

protocol://[user[:password]@]host[:port]path[?query][#fragment]

Entre crochets les parties facultatives.


  • protocol : http ou https
  • user[:password] : nom d'utilisateur (et éventuellement mot de passe), pour l'authentification HTTP
  • host : nom de domaine (ou adresse IP, pour une IPv6 elle doit être entre crochets, exemple : http://[::1]/page)
  • port : numéro de port optionnel
  • path : chemin de la ressource
  • query (ou query string) : liste de clés et valeurs, séparées par des &
  • fragment : identifiant d'une sous-ressource à l'intérieur de la ressource (en pratique, utilisé pour se rendre à une point particulier de la page web, ou en javascript)

https://catalogue.cesi.fr/recherche/?domaine=informatique&niveau=bac4#type

  • protocol: https
  • host: catalogue.cesi.fr
  • path: /recherche/
  • query: domaine=informatique&niveau=bac4
  • fragment: type

Les serveurs HTTP les plus courants

  • Apache (29% des serveurs)
  • nginx (29%) : plus rapide qu'Apache sur les fichiers statiques, même performance sur le contenu dynamique (PHP)
  • Microsoft IIS (19%)

Apache est le plus courant, historiquement le plus utilisé, mais on trouve de plus en plus du nginx aussi. La configuration de nginx est un peu plus lisible que celle d'Apache.


Apache et ses MPM

Apache possède plusieurs MPM (multi-processing module) qui ont des comportements différents :

  • prefork : moins performant (sans threads), chaque processus ne peut traiter qu'une seule requête à la fois
  • worker ou event : plus performant, chaque processus a plusieurs threads, et peut donc traiter plusieurs requêtes à la fois

Quel MPM choisir ? En production on utilisera worker ou event, car plus rapides, mais pour tester des trucs rapidement avec PHP on peut utiliser prefork qui est plus simple à metter en place.


Un mot sur l'utilisateur www-data

Par défaut Apache est lancé avec l'utilisateur www-data. Ça va si on n'a qu'un seul site hébergé sur la machine.

Si on veut héberger plusieurs sites, il vaut mieux pouvoir avoir un utilisateur par site, pour pas qu'un site puisse aller modifier les fichiers d'un autre site.

Pour cela une version de prefork appelée ITK (apt install libapache2-mpm-itk) permet d'avoir des processus Apache qui se lancent avec les droits d'utilisateurs différents.


Installation Apache sous Debian

  • Installer le serveur : apt install apache2
  • Statut du serveur : apache2ctl status (permet de voir les requêtes traitées en ce moment, le nombre de workers etc.)
  • Tester si la config n'a pas d'erreur : apache2ctl configtest
  • Recharger la configuration après modification : apache2ctl graceful

Gérer les modules Apache sous Debian

  • Activer un module : a2enmod NOM_DU_MODULE (exemple : a2enmod rewrite)
  • L'outil préviendra s'il y a un conflit entre deux modules incompatibles :)
  • Désactiver : a2dismod NOM_DU_MODULE
  • Même chose pour les MPM : a2dismod mpm_prefork puis a2enmod mpm_worker

Astuce : lancer a2enmod sans argument liste les modules disponibles.

La configuration du module est dans le fichier /etc/apache2/mods-available/NOM_DU_MODULE.conf


Configuration Apache

Syntaxe simple. Ce n'est pas du XML !

Listen 80
KeepAlive Off # Ne pas autoriser les connexions persistantes

<Directory /var/www/monsite>
	Require all granted
	Options -Indexes
</Directory>

VirtualHost

Apache permet d'héberger plusieurs sites sur le même serveur avec des hôtes virtuels. L'hôte est reconnu avec l'entête "Host". Pour cela on utilise des hôtes virtuels.

<VirtualHost *:80>
	ServerName cadoles.com
	DocumentRoot /var/www/monsite
</VirtualHost>

<VirtualHost *:80>
	ServerName mail.cadoles.com
	DocumentRoot /var/www/roundcube
</VirtualHost>

Le premier vhost de la liste sera utilisé comme vhost "par défaut" si aucun vhost n'est trouvé pour l'hôte demandé.


VirtualHost dans Debian/Ubuntu

Les vhost disponibles sont séparés par fichiers dans /etc/apache2/sites-available, triés par ordre alpha-numérique.

Ensuite : a2ensite nomduvhost pour activer, ou a2dissite nomduvhost pour désactiver.

Ne pas oublier de tester la config et recharger ensuite !

Astuce : lancer a2ensite ou a2dissite sans argument liste les sites disponibles.


Fichiers .htaccess

Apache permet de configurer des options pour un répertoire donné à l'aide d'un fichier .htaccess (en UNIX, les fichiers avec un point au début sont des fichiers "cachés").

C'est pratique, mais attention, cela veut dire qu'Apache sera beaucoup plus lent, car il va chercher ce fichier dans tous les sous-répertoires à chaque requête !

Donc il est recommandé de désactiver ce comportement par défaut, et de ne l'activer que pour les sites qui en ont besoin. Tant que possible il vaut mieux mettre toute la configuration dans les fichiers de configuration Apache du vhost.


<Directory />
	AllowOverride None
</Directory>

<Directory /var/www/wordpress>
	AllowOverride All
</Directory>

AllowOverride permet de configurer le type de directive autorisée dans le fichier .htaccess.

None = aucune directive autorisée = Apache ne va même pas lire les fichier .htaccess


Restriction d'accès

Un exemple courant de .htaccess est la restriction d'accès par mot de passe. Pour cela il faut dire à Apache de n'autoriser que les utilisateurs connectés avec Require valid-user :

Require valid-user
AuthType basic
AuthName "Accès restreint"
AuthUserFile /var/www/monsite/secret/.htpasswd

Fichier htpasswd

Pour créer le fichier .htpasswd qui contiendra la liste de nos utilisateurs autorisés et leurs mots de passe nous devons utiliser l'outil htpasswd.

A installer avec apt install apache2-utils.


  • Créer le fichier avec htpasswd -c /var/www/monsite/secret/.htpasswd NOM_UTILISATEUR (-c comme Création du fichier)
  • L'outil demande de taper, puis re-taper le mot de passe
  • Pour ajouter un utilisateur ou modifier son mot de passe, simplement : htpasswd /var/www/monsite/secret/.htpasswd NOM_UTILISATEUR (sans le -c donc)
sylvain:$apr1$vfxnPOnt$gI7MkAizYirxT/CrUfCqU0

Exercice 1

Faire une requête avec curl sur http://www.cesi.fr/. Quel est le code HTTP retourné ? Quel est le serveur web utilisé ?


Exercice 2

Installation de Apache2. Faire une requête sur http://localhost/ pour voir si ça fonctionne.

Puis essayer d'accéder à l'IP de la VM depuis un navigateur de la machine hôte pour voir si ça fonctionne bien.

(Pour obtenir l'IP : ip addr depuis la console)


Exercice 3

Prérequis : créer un répertoire /var/www/cesi.test et un fichier /var/www/cesi.test/index.html avec :

mkdir /var/www/cesi.test
echo "Hello monde !" > /var/www/cesi.test/index.html

Exercice : Mettre en place un VirtualHost cesi.test proprement, l'activer.

Pour vérifier son fonctionnement, ajouter la ligne suivante dans /etc/hosts : 127.0.0.1 cesi.test. Puis faire curl http://cesi.test/, le message "Hello monde" devrait apparaître.


Exercice 4

Prérequis : créer un répertoire /var/www/cesi.test/secret : mkdir /var/www/cesi.test/secret

Désactiver les vhosts existants, sauf celui de cesi.test. Recharger apache.

Mettre en place une protection par mot de passe du répertoire /var/www/cesi.test/secret avec un fichier .htaccess.

Vérifier que ça marche correctement en utilisant le navigateur de la machine hôte sur l'IP de la VM.


Exercice 5 (facultatif)

Tester la charge du serveur avec ApacheBench :

  • installer ab : apt install apache2-utils
  • dans une première console, lancer watch -d -n 0.1 sudo apache2ctl status
  • lancer dans une seconde console ab -n 5000 -c 100 http://localhost/ (va lancer 5000 requêtes, par vagues de 100 en même temps)
  • observer l'évolution du nombre de workers, et de la charger serveur (Server load)

Exercice 6 (facultatif)

Changer de MPM, passer de prefork (celui utilisé par défaut normalement) à event.

Répéter le test de l'exercice 5 et observer les différences.


Exercice 7 (facultatif)

On nous demande de faire de la réécriture d'adresse.

Faire en sorte que http://cesi.test/etu redirige vers http://localhost/infos-etudiant en utilisant la directive Redirect dans le vhost créé précédemment (voir la documentation de Redirect pour un exemple).

Pour cela il faudra activer le module alias.

Il est courant d'utiliser RewriteRule pour faire cela (module rewrite), mais il est plus lent et complexe (Documentation), mais permet plus de possibilités.


Exercice 8 (facultatif)

Installer nginx et créer un virtualhost cesi.test.

Un exemple de configuration de virtualhost est dispo dans /etc/nginx/sites-available/default.

Pour créer le vhost, créer un fichier /etc/nginx/sites-available/cesi.test.

Pour l'activer exécuter ln -s /etc/nginx/sites-available/cesi.test /etc/nginx/sites-enabled/cesi.test, cela va créer un lien symbolique (pas de commande comme avec Apache type a2ensite).

Puis nginx -t pour vérifier la configuration et service nginx reload pour recharger.