Travaux pratiques

protocole HTTP et navigation alternative

Durée :
3h
Objectif :
bien appréhender le principe client/serveur à l’aide d’outils spécialisés et d’outils plus génériques à travers l'utilisation du protocole HTTP
Système d’exploitation :
Linux/Solaris
Outils utilisés :
navigateur internet, aspirateur web, telnet, base64, openssl, Vim
Fichiers à voir :
L’Internet Engineering Task Force (IETF) centralise tous les RFC (Request for comments) qui décrivent les protocoles utilisés dans l’Internet sur la page suivante : http://www.ietf.org/download/rfc-index.txt

Navigateur Internet

  1. Recherchez, à l’aide de votre navigateur Internet (Firefox par exemple), le dernier RFC qui décrit le protocole HTTP 1.0 et notez son numéro.
  2. De la même manière, recherchez le dernier RFC qui correspond à la définition du protocole HTTP 1.1 et notez également son numéro.

Il y a souvent plusieurs RFC qui décrivent un protocole, mais c’est toujours le dernier qui prévaut, puisqu’il est le plus récent.

Outil en ligne de commande

Naviguer sur Internet peut se faire de nombreuses manières et nous allons voir ici l’utilisation d’un client en ligne de commande. Ce programme va être capable de faire des requêtes HTTP à un serveur HTTP (autrement dit, un serveur web) pour qu’il lui envoie un ensemble de fichiers et qu’il puisse les enregistrer sur l’ordinateur sur lequel il est exécuté.

Pour avoir de l’aider sur comment utiliser wget(1) vous pouvez soit vous rapporter à sa page de manuel (man wget), soit lui passer l’option help (wget –help). Cependant, les quelques explications données ici devraient suffire pour l'utilisation que nous allons en faire.

Pour pouvoir télécharger ces fichiers avec wget vous devez lui dire de vous authentifier auprès du proxy. Pour cela, vous devez créer une fichier dans votre répertoire personnel qui a pour nom .wgetrc et qui contient les lignes suivantes :

proxy-user=votre_identifiant
proxy-password=votre_mot_de_passe

Pour assurer un maximum de confidentialité à vos identifiants et mots de passe, voici la succession d'étapes à effectuer pour créer un tel fichier :

  1. Créez le fichier avec la commande
    #> touch $HOME/.wgetrc
    
  2. Changez les droits de ce fichier (qui est vide pour l'instant) avec la commande
    #> chmod 600 $HOME/.wgetrc
    
  3. Ouvrez ce fichier avec un éditeur de texte (vim par exemple) et entrez les informations voulues.

Enfin, vous devez avoir défini la variable d'environnement http_proxy avec un contenu désignant le proxy à utiliser.

Vous pouvez soit l'inscrire dans le fichier de configuration de votre shell (bash) qui se trouve dans votre répertoire personnel sous le nom .bashrc, soit le taper directement dans le terminal (auquel cas, il faudra le faire à chaque fois que vous ouvrez un nouveau terminal). Dans les deux cas, la ligne exacte est la suivante :

export http_proxy="http://proxyens.emse.fr:8080/"

Exercice :

  1. Créez le fichier .wgetrc mentionné ci-dessus et exportez la variable d'environnement http_proxy ;
  2. En utilisant la commande wget, téléchargez ces deux RFC. Pour cela vous utiliserez l’URL suivante, en remplaçant XXXX par le numéro du RFC recherché : http://www.ietf.org/rfc/rfcXXXX.txt ;
  3. Parcourez la RFC de HTTP/1.0 pour en comprendre les bases en recherchant particulièrement les passages qui décrivent la façon d’écrire une requête complète. Quels sont les types de requête qu'il est possible d'adresser à un serveur HTTP ?
  4. Notez les principales différences entre HTTP/1.0 et HTTP/1.1.

Connexion directe

L’outil wget est un vrai client HTTP en ce sens qu’il connaît le protocole et qu’il envoie au serveur des requêtes correctement formulées.

Cependant, un serveur n’est rien d’autre qu’un programme qui attend qu’on lui cause sur un port donné.

Il est donc possible d’établir une connexion avec ce serveur, même si, a priori ce n’est pas avec un client HTTP valide.

C’est ce que nous allons tenter de faire maintenant et écrivant à la main des requêtes HTTP valides.

telnet

telnet est une commande permettant de se connecter à un serveur en mode texte. Beaucoup de protocoles de l’Internet utilisent des échanges en mode texte.

La syntaxe générale de la commande telnet est la suivante :

#> telnet adresse_du_serveur port

L’adresse du serveur peut-être une adresse IP ou un nom si l’on dispose d’un serveur DNS.

Une fois connecté, le programme telnet, qui agit comme un client, attend les commandes à transmettre au serveur et ne fournit aucun retour.

Pour quitter telnet, il faut envoyer un message de fin de transmission qui est en rapport avec le protocole utilisé par le serveur contacté ou, à défaut, le caractère d’échappement que la commande vous donne dans son message de démarrage.

En général, la commande telnet se trouve dans le répertoire /usr/bin/.

Exercices

  1. À l’aide de ce que vous avez pu apprendre sur le protocole HTTP, connectez-vous à l’un des serveurs de l’école que l’on peut atteindre depuis le réseau enseignement (www.emse.fr ou kiwi.emse.fr par exemple) sur le port correspondant au protocole HTTP (le port 80) avec la commande telnet(1) (/usr/bin/telnet) et obtenez la page de garde en faisant une requête HTTP/1.0 simple (une requête HTTP se termine par une ligne vide).
  2. Observez l’en-tête de la réponse que vous obtenez et donnez le code de retour HTTP correspondant (donnez également la totalité de l’en-tête).
  3. Préparez plusieurs requêtes simples et complètes, pour obtenir différents documents du serveur parcouru en vous basant sur les liens (balises <a href=...></a>) de la page obtenue. Soumettez ces requêtes au serveur (vous devez vous reconnecter à chaque fois) et donnez les en-têtes que vous obtenez.
  4. Ré-écrivez vos requêtes en tentant cette fois, de respecter le protocole HTTP/1.1. Soumettez les au serveur et donnez les en-têtes obtenus en retour. Y a-t-il une différence de comportement ?
  5. Essayez de vous connecter de la même manière à un serveur extérieur à l’école (www.inria.fr par exemple). Commentez ce que vous obtenez et essayez d’expliquer le pourquoi de ce résultat.

L'étape suivante va consister à traverser le proxy enseignement qui filtre le passage, pour accéder aux sites hors domaine emse.fr.

Le soucis est que ce proxy demande une authentification. En fait, c’est n’est pas réellement un problème et puisque nous disposons de notre couple identifiant/mot-de-passe, il suffit de le lui fournir. Voici comment procéder :

Il faut tout d’abord écrire une requête HTTP valide, à destination d'un proxy, demandant une authentification. Elle doit ressembler à cela :

GET http://www.inria.fr/ HTTP/1.1
Host: www.inria.fr
User-Agent: Smith
Proxy-Authorization: Basic <tas de caractères étranges>

La norme HTTP précise que, dans le cas de l’authentification de type Basic (utilisée ici), le couple identifiant/mot-de-passe doit être codé en base 64 (décrit dans la RFC 3548). Ce codage est très simple et Linux propose une commande permettant de coder un fichier avec cette méthode : base641.

L’utilisation de cette commande est elle-même assez simple, puisqu’il suffit de lui passer en argument un fichier contenant le texte à coder (ici la séquence identifiant:mot-de-passe). Cependant, dans notre cas, ce fichier ne doit pas se terminer par une ligne vide (sinon, la commande va également coder le caractère de retour à la ligne et l'authentification ne fonctionnera pas). Par défaut l’éditeur vim ajoute une ligne vide à la fin de tout fichier qu'il enregistre. Pour remédier à cela, voici comment procéder :

  1. Ouvrez un terminal
  2. Créez un fichier vide avec la commande touch in.txt
  3. Changez les droits de ce fichier pour que vous soyez le seul à pouvoir le lire, en utilisant la commande chmod 600 in.txt
  4. Lancez la commande vim -b in.txt
  5. Une fois dans l’éditeur, tapez la commande :set noeol (ça précise à l’éditeur de ne pas rajouter de caractère \n à la fin du fichier quand il sauvegardera) et validez avec [Entrée]
  6. Appuyez sur la touche [i] pour passer en mode insertion
  7. Entrez, comme dans n’importe quel éditeur, votre texte. Ce texte est donc votre identifiant, suivi d’un : et suivi de votre mot de passe (par exemple dupont:super-mot-de-passe). Ne sautez pas de ligne à la fin !
  8. Appuyez sur la touche [ESC] pour sortir du mode d’édition
  9. Enregistrez votre fichier avec la commande :w et validez avec [Entrée]
  10. Sortez de l’éditeur avec la commande :q et validez avec [Entrée]

Vous ne manquerez pas de remarquer que votre mot de passe figure en clair dans ce fichier, c’est pour cela que nous avons changé ses droits au début. Cependant, il sera sage de supprimer ce fichier une fois les TP terminés...

Exercice :

Nous allons à présent encoder ce fichier en base64 :

  • Ouvrez un terminal si vous n’en avez pas déjà un sous la main
  • Utilisez la commande base64 in.txt > out.txt
  • Affichez le contenu du fichier out.txt qui vient d’être créé, avec la commande cat out.txt

Bravo, vous avez encodé votre credential, vous êtes prêt à vous authentifier auprès du proxy. Il suffit pour cela de remplacer <tas de caractères étranges> dans la requête HTTP par le contenu du fichier out.txt (un copier-coller fera très bien l’affaire mais n'oubliez pas qu'il ne doit y avoir que les caratères présents dans le fichier, ni d'espace ou autre chose à la fin).

À présent connectez vous, toujours avec telnet, au serveur proxy enseignement sur le port 8080 (telnet proxyens.emse.fr 8080) et essayez, avec le protocole HTTP 1.1, d’interroger un serveur extérieur avec comme modèle la requête ci-dessous :

GET http://www.inria.fr/ HTTP/1.1
Host: www.inria.fr
User-Agent: Smith
Proxy-Authorization: Basic ZHVwb250OnN1cGVyLW1vdC1kZS1wYXNzZQ==

Remarque : si vous lisez le manuel de la commande base64 ou mieux, que vous lisez le RFC 3548, vous vous rendrez compte que l’encodage en base 64 est réversible. Vous pouvez donc tout à fait, à partir du code ZHVwb250OnN1cGVyLW1vdC1kZS1wYXNzZQ== retrouver le couple identifiant:mot-de-passe qui a été utilisé... De cela il faut retenir que n’importe qui, à l’écoute du réseau (et ce n’est pas compliqué de faire cela), peut voir passer votre requête d’authentification et retrouver votre couple identifiant:mot-de-passe...

Conclusion

Le protocole HTTP est, commme beaucoup d'autres protocoles, plutôt simple à utiliser et à mettre en œuvre. Il permet de mettre en évidence le mécanisme client/serveur qui régit les échanges sur l'Internet.

La présence d'un proxy sur le réseau a plusieurs objectifs. Un de ces objectifs est d'accélérer la navigation en proposant un mécanisme de cache. Un autre objectif est de filtrer l'accès à l'Internet à l'aide d'une authentification. Cependant, il faut toujours prendre garde au moyen d'authentification utilisé et à son véritable niveau de sécurité.

Bonne navigation !


1 : si d'aventure base64 n'est pas disponible, il y a une méthode alternative avec la commande openssl. Voici les paramètres pour encoder un fichier en base 64 : openssl base64 -in in.txt -out out.txt. Les fichiers in.txt et out.txt sont les mêmes que ceux utilisés dans la description de la commande base64.