• 15 heures
  • Moyenne

Ce cours est visible gratuitement en ligne.

course.header.alt.is_video

Ce cours existe en livre papier.

course.header.alt.is_certifying

J'ai tout compris !

Mis à jour le 26/06/2019

Rendre mes applications joignables sur le réseau

Connectez-vous ou inscrivez-vous gratuitement pour bénéficier de toutes les fonctionnalités de ce cours !

Avec tout ce que nous avons vu jusqu'à maintenant, nous sommes capables de faire dialoguer ensemble des machines d'un bout à l'autre d'Internet.

Mais ça nous fait une belle jambe, car ce que nous voulons c'est pouvoir faire dialoguer une application cliente avec une application serveur. C'est là où la couche 4 entre en jeu, en ajoutant la notion d'application au réseau. C'est elle qui va faire le lien entre la couche applicative et les couches réseau.

Nous allons voir dans ce chapitre les deux protocoles utilisés en couche 4. Eh oui, il n'y en a pas qu'un seul !
Accrochez-vous, c'est encore à un gros chapitre que vous avez affaire !

La couche 4, ses rôles

Grâce à la couche 2, nous savons dialoguer sur un réseau local.
Grâce à la couche 3, nous savons dialoguer entre réseaux.
Nous sommes donc capables de dialoguer entre deux machines sur des réseaux distants, chacune à un bout du monde.

À quoi va donc bien pouvoir nous servir la couche 4 alors ?

Eh bien, notre objectif n'est pas de faire dialoguer ensemble des machines, mais de faire dialoguer ensemble des applications.
Vous vous rappelez le modèle OSI ? La figure suivante devrait vous rafraîchir la mémoire.

Le modèle OSI

Le modèle OSI

Nous voyons très bien ici que le réseau va servir à transporter l'information fournie par les applications. Ainsi, notre objectif est de faire dialoguer des applications qui sont sur des machines, entre elles.

On voit tout de suite l'intérêt d'avoir une couche du modèle OSI qui soit en charge de la communication entre applications.
Le rôle de la couche 4 est donc de gérer les connexions applicatives.

Nous allons maintenant voir comment les protocoles de couche 4 vont faire cela... eh oui, j'ai bien dit LES protocoles de couche 4.

Un identifiant, le port

Le port

Définition

En couches 2 et 3, nous avions vu qu'il fallait une adresse pour identifier les éléments nécessaires à l'identification des moyens de communication. L'adresse MAC identifie la carte réseau en couche 2, et l'adresse IP identifie l'adresse de notre machine au sein d'un réseau, en couche 3.

Eh bien en couche 4, l'adresse utilisée est le port.

Euh... c'est une adresse ou un port ?

Le port est une adresse. C'est même l'adresse d'une application sur une machine.

Ainsi, nous pourrons identifier toute application qui tourne sur notre machine et qui a besoin de dialoguer sur le réseau.
Si vous vous rappelez, dans le chapitre précédent, j'avais montré que mon serveur MySQL était en écoute sur le numéro 3306.

sd-6123:~# netstat -antp
Connexions Internet actives (serveurs et établies)
Proto Recv-Q Send-Q Adresse locale          Adresse distante        Etat        PID/Program name
tcp        0      0 0.0.0.0:48963           0.0.0.0:*               LISTEN      29575/rpc.statd 
tcp        0      0 127.0.0.1:3306          0.0.0.0:*               LISTEN      5470/mysqld     
tcp        0      0 0.0.0.0:111             0.0.0.0:*               LISTEN      1841/portmap    
tcp        0      0 0.0.0.0:30033           0.0.0.0:*               LISTEN      5249/ts3server_linu
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      29667/sshd      
tcp        0      0 0.0.0.0:25              0.0.0.0:*               LISTEN      30562/master    
tcp        0      0 0.0.0.0:10011           0.0.0.0:*               LISTEN      5249/ts3server_linu
tcp        0      0 127.0.0.1:39027         127.0.0.1:80            TIME_WAIT   -               
tcp        0      0 127.0.0.1:35335         127.0.0.1:3306          TIME_WAIT   -               
tcp        0     48 88.191.45.68:22         79.82.49.130:53745      ESTABLISHED 23488/1         
tcp6       0      0 :::873                  :::*                    LISTEN      6699/rsync      
tcp6       0      0 :::80                   :::*                    LISTEN      18732/apache2   
tcp6       0      0 :::22                   :::*                    LISTEN      29667/sshd

Nous savons maintenant que ce numéro est en fait le port d'écoute de l'application MySQL. Si je reçois une requête MySQL sur l'adresse IP 127.0.0.1 et sur le port 3306, le service MySQL va pouvoir répondre.

Exemple de port en écoute

Prenons la machine d'adresse 88.191.135.63 sur laquelle je fais un netstat :

sd-2412:~# netstat -antp
Connexions Internet actives (serveurs et établies)
Proto Recv-Q Send-Q Adresse locale          Adresse distante        Etat        PID/Program name
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      22762/sshd      
tcp        0      0 0.0.0.0:25              0.0.0.0:*               LISTEN      15434/master
tcp        0      0 127.0.0.1:3306          0.0.0.0:*               LISTEN      10921/mysqld    
tcp        0      0 127.0.0.1:11211         0.0.0.0:*               LISTEN      20952/memcached 
tcp6       0      0 :::80                   :::*                    LISTEN      21800/apache2   
tcp6       0      0 :::22                   :::*                    LISTEN      22762/sshd

Nous voyons ici que le port 80 est en écoute à la ligne 5, et que c'est l'application apache2 qui est un serveur web :

tcp6       0      0 :::80                   :::*                    LISTEN      21800/apache2

Le port 80 est le port utilisé pour les serveurs web. Nous pouvons donc nous douter qu'un serveur web est en écoute sur cette machine ! Il ne nous reste plus qu'à utiliser un client web, soit un simple navigateur, pour nous connecter à cette application.

Essayez sur votre navigateur d'entrer http://163.172.38.160 (voir la figure suivante).

site en écoute

Nous avons entré dans l'URL l'adresse IP 163.172.38.160, et nous avons été redirigés vers mon sitewww.lalitte.com.
C'est normal, car cette adresse est celle de la machine qui héberge mon site.

C'est normal, car notre navigateur, qui est un client web, fait toujours ses requêtes sur le port 80 si un port n'est pas spécifié.

Toutefois, nous pouvons explicitement spécifier un port dans notre URL, par exemple le port 22 qui était en écoute aussi sur la machine. Dans ce cas, nous allons taper 163.172.38.160:22 dans l'URL pour préciser le port voulu.

Essayez avec http://163.172.38.160:22, comme indiqué sur la figure suivante.

port forcé en 22

Notez que cela ne fonctionnera pas sous Chrome. Vous avez donc le droit de changer de navigateur !

Nous voyons que nous tombons sur un serveur ssh. Ça tombe bien, car le port 22 est le port normalement réservé pour un serveur ssh. :)
Nous verrons plus tard quelle est son utilité, mais dès maintenant, nous pouvons voir que derrière chaque port ouvert sur une machine se cache une application !

Quelles adresses pour les ports ?

Beaucoup de ports !

Les ports sont codés en décimal sur deux octets.

Ils peuvent donc prendre $\(2^{16}\)$  vale‌urs, soit 65536 valeurs !
Vu que l'on commence l'adressage des ports à 0, nous pourrons avoir des valeurs de ports de 0 à 65535.
Ça fait quand même pas mal, non ?

Donc nous pourrons faire tourner au maximum 65536 applications en réseau sur une machine. Cela devrait aller... mais on peut quand même parfois arriver à saturation, en cas d'attaque, quand quelqu'un envoie des tonnes de paquets sur nos différents ports pour nous saturer.

OK, nous avons donc 65535 ports à notre disposition.

Or, nous avons vu qu'un serveur web devait être sur le port 80. Y a-t-il d'autres ports réservés ?

Oui, il y a quasiment autant de ports réservés que d'applications réseau qui existent.

Liste des ports

Voici une petite liste des ports réservés, et des applications associées, les plus couramment utilisés :

Application

Port réservé

web

80

mail

25

ssh

22

imap

143

proxy

8080

https

443

Counterstrike

27015

ftp

20/21

dns

53

jeux Blizzard

6112

Si vous ne connaissez pas ces applications, ce n'est pas grave, nous les découvrirons pour la plupart dans la suite de ce cours.

Il y a donc 65535 ports réservés pour les applications ?

Non, seule une partie d'entre eux sont réservés. D'ailleurs, historiquement, ce n'était que les ports inférieurs à 1024 qui étaient réservés. Mais aujourd'hui, beaucoup d'applications qui sortent utilisent des ports au-delà de 1024.

À quoi peuvent bien servir les ports au-dessus de 1024 alors ?

C'est une très bonne question ! Nous avons dit que le port était l'adresse d'une application. Et nous avons vu que les ports étaient notamment utilisés pour les applications serveur, les services.

Mais quid des applications clientes ? Ont-elles aussi une adresse avec un port ?

Eh bien les applications clientes ont des ports, elles aussi, mais ils ne sont pas réservés.
Les ports attribués aux applications clientes sont donnés aléatoirement, au-dessus de 1024, par le système d'exploitation.

Ce n'est pas gênant. Pour un serveur, vu qu'il est en écoute en permanence, il est important que l'on connaisse le port auquel on doit s'adresser. Pour un client, l'application ne va être en écoute que le temps de son fonctionnement. Ainsi, il peut être choisi au hasard tant que le système d'exploitation sait quelle application se trouve derrière quel port.

Et voilà comment nous pouvons dialoguer entre applications client/serveur grâce aux ports !

Nous sommes maintenant prêts pour découvrir le reste de la couche 4, et notamment les deux protocoles qui la composent.

Deux protocoles, TCP et UDP

Deux protocoles pour le prix d'un !

En couche 2 comme en couche 3, nous n'avons vu qu'un seul protocole de transport des données (Ethernet pour la couche 2, et IP pour la couche 3).

Alors pourquoi la couche 4 aurait-elle besoin de deux protocoles ?

En fait, les gens qui ont créé les réseaux se sont rendu compte qu'il pouvait y avoir deux besoins différents pour le transport des données des applications :

  • des applications qui nécessitent un transport fiable des données, mais qui n'ont pas de besoin particulier en ce qui concerne la vitesse de transmission ;

  • des applications qui nécessitent un transport immédiat des informations, mais qui peuvent se permettre de perdre quelques informations.

Avez-vous une idée des applications qui font partie de la première catégorie et de celles qui sont dans la seconde ?

La première catégorie regroupe une très grande majorité des applications d'Internet, car bon nombre d'entre elles ont besoin que chaque paquet émis soit reçu coûte que coûte !
Ce sont notamment les applications comme le web, la messagerie, le ssh, beaucoup de jeux en ligne, etc.
Si un paquet est perdu, une page web ne pourra pas s'afficher correctement, ce sera pareil pour un mail, etc.

La seconde catégorie regroupe moins d'applications, mais vous comprendrez vite pourquoi ces applications ont besoin d'être instantanées et peuvent se permettre qu'un paquet ne soit pas reçu. Il s'agit notamment des applications de streaming, comme la radio ou la télé sur Internet.
Pour une radio en ligne, il est essentiel que les informations soient envoyées en temps réel, le plus rapidement possible. Par contre, si un ou plusieurs paquets sont perdus, on ne va pas arrêter la radio pour autant. L'utilisateur aura des coupures de connexion, mais la radio continuera d'émettre.

On identifie donc ainsi deux besoins bien distincts l'un de l'autre :

  • un protocole fiable mais sans nécessité de rapidité ;

  • un protocole rapide sans nécessité de fiabilité.

C'est pour cela que nous avons deux protocoles pour la couche 4 : le protocole TCP et le protocole UDP.

TCP est de la première catégorie, c'est un protocole extrêmement fiable.
Chaque paquet envoyé doit être acquitté par le receveur, qui en réémettra un autre s'il ne reçoit pas d'accusé de réception. On dit alors que c'est un protocole connecté.
On peut le comparer au téléphone. Quand on appelle quelqu'un, on dit "Allo ?" pour savoir si la personne est là et, s'il y a des silences dans la communication, on essaye de voir si la personne est encore à l'écoute, etc. En TCP ce sera pareil, pour chaque information envoyée, on vérifiera que la machine en face l'a bien reçue.

UDP, lui, est un protocole rapide, mais peu fiable. Les paquets sont envoyés dès que possible, mais on se fiche de savoir s'ils ont été reçus ou pas. On dit qu'UDP est un protocole non-connecté.
C'est un peu comme le courrier (sauf que le courrier n'est pas rapide...) On envoie notre lettre, et ensuite, on prie très fort pour que celle-ci arrive, mais on n'en sait rien. :o

Regardons d'un peu plus près chacun de ces protocoles.

UDP, la simplicité

UDP est le protocole le plus simple auquel vous aurez affaire en réseau. Étant donné que les objectifs associés à sa mise en œuvre sont la rapidité et la non-nécessité de savoir si une information est bien reçue, le format des messages envoyés sera très simple !

Le datagramme UDP

Eh oui, on dit datagramme comme pour le message de couche 3 du protocole IP. C'est normal, car datagramme veut dire, en gros, message envoyé dont on ne sait rien sur la bonne transmission ou réception. Voici le contenu d'un datagramme UDP :

Port Source

Port Destination

Longueur totale

Checksum

Données à envoyer

Datagramme UDP

Nous avons ici seulement 4 informations pour l'en-tête UDP. Chacune faisant 2 octets, cela nous fait un en-tête de seulement 8 octets !
C'est le plus petit en-tête que nous ayons vu, et que nous verrons.

Étudions ces champs un par un.

  • Pour le port source, c'est simple, c'est l'adresse de l'application qui envoie l'information.

  • Pour le port destination, c'est l'adresse de l'application destinataire.

  • Ensuite, il y a un champ de 2 octets qui représente la taille d'un datagramme, ce qui veut dire que la taille maximum d'un datagramme sera de $\(2^{16}\)$ soit 65536 octets. Cependant, dans la réalité, il est très rare de voir des datagrammes UDP de plus de 512 octets. Ceci est notamment dû au fait que perdre un petit datagramme est acceptable, mais en perdre un gros est plus gênant, vu qu'UDP n'a pas de gestion des paquets perdus.

  • Pour le checksum, ou CRC, le principe est le même que pour la couche 2 : s'assurer que les données reçues sont bien les mêmes que celles qui ont été transmises.

Tiens, tiens, une question ne vous vient-elle pas à l'esprit ? Non ?

Pourquoi avoir un CRC pour le protocole UDP alors qu'il y en a déjà un pour la couche 2 avec le protocole Ethernet ?

En effet, si vous avez bien compris le principe d'encapsulation, vous savez que le datagramme UDP est à l'intérieur de la trame Ethernet, et donc que le CRC de la trame vérifie les données de la couche 4 du protocole UDP.

Pourquoi alors, faire ce CRC deux fois ?

Eh bien la réponse se trouve dans le modèle OSI.
Si vous vous souvenez bien, une des règles associées au modèle OSI est que chaque couche est indépendante. Ainsi, ce n'est pas parce que la couche 2 avec le protocole Ethernet fait un CRC, que la couche 4 ne doit pas en faire, de même que la couche 3.
Étant donné que chacune des couches n'est pas censée savoir qu'une autre couche fait un CRC, chacune implémente son propre CRC.

Les applications qui utilisent UDP

Comme prévu, les applications de streaming vont, en énorme majorité, utiliser UDP, comme la radio sur Internet, la télé sur Internet, etc.
On l'utilise aussi pour la téléphonie sur Internet, plus connue sous le nom de VoIP (Voice Over Internet Protocol) ou ToIP (Telephony Over IP).
Mais on utilise aussi UDP pour transporter deux protocoles majeurs d'Internet que sont le DNS et le SNMP. Nous verrons ces deux protocoles dans les prochains chapitres, ne vous inquiétez pas. Vous savez dès maintenant que ce sont deux exceptions qui utilisent UDP parmi la multitude d'applications qui utilisent TCP.

Que dire d'autre sur UDP ?

Rien. UDP est un protocole simple, aussi simple que la longueur de ce paragraphe... :)

TCP, tout envoi sera acquitté !

C'est dans le titre, le principe de TCP est d'acquitter chaque octet d'information reçue.
À l'inverse d'UDP, il y aura beaucoup d'informations dans l'en-tête TCP pour parvenir à suivre une connexion correctement.
Mais nous n'allons pas tout de suite nous pencher dessus. Nous allons d'abord voir les principes de base de TCP.

Avant de communiquer, on assure la communication.

Prenons une conversation téléphonique. Avant de raconter son histoire, l'interlocuteur va d'abord s'assurer que son partenaire est bien présent au bout du fil. Cela donne:

  • Paul appelle : Tut... tut...

  • René répond : Allo ?

  • Paul commence sa conversation : Allo, salut c'est Paul !

On voit très clairement ici qu'il faut établir la communication avant de parler du sujet. Il en sera de même en TCP.

Les trois premiers paquets envoyés ne serviront qu'à établir la communication. Comme le allo, ce seront des paquets vides qui ne sont là que pour s'assurer que l'autre veut bien parler avec nous.

Comme le téléphone, une connexion TCP va se dérouler comme suit :

  • Tu veux bien dialoguer avec moi ?

  • Oui, je suis OK.

  • OK, bien reçu, on commence la discussion.

Pour cela TCP va utiliser des informations dans son en-tête pour dire si un paquet correspond à une demande de connexion ou si c'est un paquet normal.

Les drapeaux

Étant donné que les paquets qui vont être envoyés pour initialiser la connexion seront vides (ils ne contiendront pas de données) il faudra une information présente dans l'en-tête pour indiquer si c'est une demande de connexion, une réponse ou un acquittement (un acquittement sera une réponse vide qui servira simplement à dire à la machine en face que l'on a bien reçu ses informations, comme quand on dit "han han..." au téléphone pour bien spécifier que l'on écoute ce que dit notre interlocuteur).

Pour cela, il va y avoir ce que l'on appelle des drapeaux (ou flags en anglais) dans l'en-tête TCP. Les drapeaux ne sont rien d'autre que des bits qui peuvent prendre la valeur 0 ou 1. Ainsi, il y aura dans l'en-tête TCP des bits qui vont indiquer quel est le type du message TCP envoyé.

Établissement de la connexion

Le premier paquet sera une demande de synchronisation, comme le allo au téléphone, le flag correspondant est le flag SYN (SYN pour synchronisation !). Tous les flags sont connus sous leur forme courte, de trois lettres seulement.
Ainsi, si je veux me connecter à une application serveur qui fonctionne avec TCP, je vais envoyer un paquet avec le flag SYN positionné pour lui indiquer que je veux dialoguer avec elle, c'est l'équivalent d'un "Tu veux bien dialoguer avec moi ?".

Un serveur recevant une demande SYN doit normalement répondre qu'il est d'accord pour communiquer avec le client. Pour cela il va envoyer un ACK en réponse (ACK comme acquittement, ou acknowledgement en anglais).
MAIS, il va, à son tour, demander si le client veut bien communiquer avec lui et positionner aussi le flag SYN dans sa réponse. Il y aura donc les flags SYN ET ACK positionnés dans sa réponse.

Euh, mais si le client a demandé à communiquer avec le serveur, pourquoi le serveur lui demande s'il veut bien communiquer avec lui ?

Eh bien la réponse à cette question est primordiale pour comprendre TCP.
Quand on veut communiquer en TCP, on n'établit pas une, mais deux connexions.
Car TCP considère qu'il va y avoir une communication dans un sens, et une communication dans l'autre sens. Il établit donc une connexion pour chaque sens de communication.

Ainsi, quand le serveur répond à la requête SYN, il acquitte la demande avec le ACK, et fait une demande de connexion pour l'autre sens de communication, du serveur vers le client, en positionnant le flag SYN. La réponse a donc les flags SYN ET ACK positionnés.

Toutefois, notre connexion n'est pas encore établie... Il faut encore que le client accepte la demande de connexion faite par le serveur. Le client va donc renvoyer un paquet avec un flag ACK.

Cela donne le résultat que vous pouvez voir en figure suivante.

3 Way Handshake
3 Way Handshake

Nous voyons bien ici la différence entre la communication bleue de A vers B et la communication rouge de B vers A.
On voit d'ailleurs les couleurs des flags associés : en bleu, le premier SYN pour la demande de connexion de A vers B et le ACK dans la réponse pour acquitter la demande de connexion de A vers B ; en rouge le SYN pour la demande de connexion de B vers A et l'acquittement ACK dans le dernier paquet.

L'établissement de la connexion TCP s'est donc fait par l'échange de trois paquets. C'est pour cela qu'on l'appelle Three Way Handshake ou poignée de main tripartite en français (mais tous les spécialistes utilisent le terme anglais, comme souvent en réseau)

Continuation de la connexion

Maintenant que la communication est établie, les applications peuvent s'échanger des paquets autant qu'elles le veulent !
Le principe au niveau des flags est simplement d'avoir positionné le flag ACK. Donc tout paquet échangé après l'établissement de la connexion n'aura que le flag ACK de positionné. Presque, car nous n'avons vu que deux flags pour l'instant...
Néanmoins, ce qui est sûr, c'est que le flag ACK sera positionné sur tous les paquets, pour acquitter la réception des paquets précédents.
Voyez en figure suivante le schéma de la continuité d'une connexion.

Continuité de la connexion
Continuité de la connexion
Fin de la connexion

Toutes les bonnes choses ont une fin, et les connexions TCP aussi ! :p
Une fois que les applications ont terminé leur communication, il faut encore fermer la connexion.
Eh oui, on ne va pas laisser la connexion indéfiniment ouverte ! Si nous ne les libérions jamais, nos ports seraient rapidement tous utilisés.

Donc, de la même façon que l'on a utilisé des paquets vides et des flags pour établir une connexion, nous allons faire de même pour la clôturer.
Le flag que l'on va utiliser alors, à l'opposé de SYN, est le flag FIN.

Imaginons que le client veuille fermer la connexion, il envoie donc un paquet avec le flag FIN positionné.

Donc il n'y a que le flag FIN de positionné ?

Non, car comme nous l'avons vu, dès lors qu'une connexion est établie, tout paquet contiendra un flag ACK pour acquitter le paquet précédent. Donc lorsque l'on demandera la fermeture de la connexion avec le flag FIN, on en profitera pour acquitter le paquet précédent reçu en ajoutant aussi le flag ACK. La demande de fermeture contiendra donc les flags FIN et ACK.

Le serveur pourra ensuite, lui aussi, demander la fermeture de la communication dans l'autre sens, et acquitter la réception de la demande de fin. Il placera donc, lui aussi, les flags FIN et ACK.

Super ! Et là, notre connexion est fermée ?

Pas encore ! Le serveur a demandé la fermeture de la communication dans le sens serveur -> client, mais le client ne lui a pas encore acquitté cette demande. Si jamais ce paquet était perdu, le serveur et le client continueraient à avoir leur connexion ouverte. Il faut donc que le client réponde au serveur qu'il a bien reçu sa demande de fermeture en envoyant un dernier paquet ACK. C'est seulement à ce moment que la connexion est fermée complètement et que les ressources des machines sont libérées (voir la figure suivante).

Terminaison de la connexion
Terminaison de la connexion

Nous venons donc de voir comment se déroulait une connexion TCP : l'établissement à l'aide du three way handshake, la continuation et la fermeture. Il nous reste à voir les détails de l'en-tête TCP et notamment les flags dont nous avons parlé.

Le segment TCP

Voici un nouveau terme pour nous : le segment TCP.
Nous avions la trame Ethernet, le datagramme IP, le datagramme UDP, et nous avons maintenant le segment TCP.
Nous n'allons pas encore représenter en détail toutes les informations de l'en-tête du segment TCP mais nous allons nous concentrer sur les éléments qui nous intéressent. Nous verrons par la suite le détail de celui-ci. N'ingurgitons pas tout d'un coup, au risque de faire une indigestion !

Voici donc la bête:

Port Source

Port Destination

???

Flags

???

Checksum

???

Données à envoyer

Segment TCP

Nous pouvons voir qu'il reste encore quelques points d'interrogation, mais ne vous inquiétez pas, nous les détaillerons par la suite.
L'en-tête fait 20 octets, comme celui de la couche 3.
Faisons le détail de ce que nous pouvons voir.

  • port source et port destination, on connaît !

  • les flags,
    ils sont au nombre de 6 et nous en connaissons déjà 3 ;

    • SYN

    • ACK

    • FIN

    • RST

    • PSH

    • URG

  • enfin, le checksum que nous connaissons aussi.

Il nous reste trois flags à expliciter, sachant que RST a une importance plus forte que les deux autres.

Nous verrons dans un prochain chapitre qu'en TCP chaque octet de données envoyé doit être acquitté. Si jamais il y a une incohérence entre les données envoyées et les données reçues, la connexion est considérée comme anormale et la machine qui s'en rend compte doit prévenir l'autre pour arrêter la connexion et en mettre en place une nouvelle.
Cela se fait grâce au flag RST.

Si deux machines A et B ont établi une connexion TCP et qu'après quelques échanges la machine A se rend compte qu'il y a une incohérence dans la connexion, elle va envoyer un paquet contenant le flag RST pour indiquer l'incohérence et demander à la machine B de clore la connexion.
Donc pour une fois, la connexion ne sera pas terminée par la séquence FIN+ACK, FIN+ACK, ACK.

De la même façon, si j'envoie un paquet SYN sur le port d'une machine qui est fermé, celle-ci doit me répondre RST pour me signifier que le port demandé n'est pas en écoute.

Les flags PSH et URG peuvent être positionnés pour indiquer que le paquet doit être traité en priorité par la machine destinataire, mais nous ne détaillerons pas plus leur utilisation, car elle n'est pas nécessaire pour comprendre le fonctionnement des réseaux. Si vous souhaitez en savoir plus, je vous invite à jeter un coup d’œil au lien suivant.

Nous avons donc vu, en partie pour l'instant, le contenu d'un segment TCP ainsi que le suivi des connexions. Nous allons maintenant présenter un cas un peu plus concret pour bien fixer les idées.

Étude d'une connexion TCP complète

Après avoir étudié la théorie, nous allons passer à la pratique et voir concrètement les segments qui sont échangés lors d'une communication entre un client et un serveur. Nous verrons aussi dans cette partie comment utiliser un logiciel qui permet d'écouter ce qui passe sur le réseau, un sniffer.

Wireshark, l'explorateur du réseau

Présentation de l'outil

Wireshark est un programme qui permet d'écouter ce qui passe sur le réseau et qu'on appelle communément un sniffer (prononcer sniffeur).

Concrètement, Wireshark récupère les paquets réseau qui arrivent sur votre carte et interprète leur contenu intelligemment pour vous les présenter. Il permet ainsi de voir tous les paquets à destination de votre carte réseau.

En effet, tous les paquets qui passent sur votre carte réseau ne sont pas obligatoirement à destination de votre machine. C'est le cas des broadcasts par exemple, ou si jamais vous êtes un routeur et que des paquets transitent par vous. De la même façon, sur un réseau commuté (où les machines sont reliées entre elles avec un switch) nous ne verrons pas passer tous les paquets réseau, mais seulement ceux qui sont à destination de notre carte (ceux qui ont pour adresse MAC destination celle de notre carte ou le broadcast).

Donc Wireshark va recevoir les 0 et les 1, et comme il connaît les protocoles réseau, il sera capable de les interpréter et de nous les présenter joliment !
Voici à la figure suivante un exemple de ce que peut nous présenter Wireshark.

Exemple Wireshark
Exemple Wireshark

On peut y avoir plein de lignes avec tout plein de caractères !
Chacune de ces lignes a une signification et un sens. Nous allons maintenant les étudier.

Présentation de la fenêtre Wireshark

La fenêtre se compose en gros de quatre parties :

  • les menus et commandes ;

  • la présentation résumée des paquets reçus ;

  • la présentation détaillée d'un paquet ciblé ;

  • le contenu hexadécimal du paquet.

Menus et commandes

Le menu présenté en figure suivante est essentiellement composé des actions que nous pouvons faire avec Wireshark. Dans notre cas, nous ne nous servirons que de quelques actions.

Menu Wireshark
Menu Wireshark

Il y a cependant une partie qui peut être importante pour nous, c'est la partie filter. Nous pouvons filtrer ici les informations affichées par Wireshark en fonction de certains critères, comme par exemple les adresses ou les ports. Cela permet notamment de suivre plus facilement une connexion TCP de A à Z sans avoir tous les paquets parasites qui peuvent circuler sur le réseau. Nous l'utiliserons par la suite.

On peut voir en figure suivante la liste résumée des paquets reçus avec les adresses IP source et destination, le dernier protocole encapsulé ainsi que quelques informations sur le contenu du paquet.

Présentation résumée Wireshark
Présentation résumée Wireshark

La présentation détaillée d'un paquet ciblé est la partie qui va nous permettre de voir en détail le contenu des en-têtes (voir la figure suivante). Wireshark pourra interpréter tout le contenu de chaque en-tête et nous pourrons ainsi distinguer les informations contenues dans chaque paquet.

Présentation détaillée
Présentation détaillée

Le contenu hexadécimal du paquet est un peu plus complexe : c'est le contenu brut du paquet non interprété par Wireshark (voir la figure suivante). Cela peut être utile si l'on veut voir le contenu réel d'un paquet et pas seulement ce que Wireshark interprète. Il peut y avoir des différences...

Contenu hexadécimal
Contenu hexadécimal

Passons maintenant à l'étude complète d'une connexion. Pour cela, vous devez installer Wireshark !

Étude d'une connexion complète

Installation de Wireshark

Pour installer Wireshark, rien de plus simple.
Pour nos amis sous Windows, il faut se rendre sur le site de téléchargement de Wireshark et exécuter l'installation en suivant les instructions.
Sous Linux, je vous invite à utiliser votre gestionnaire de paquets préféré :
# apt-get install wireshark.
Il ne nous reste plus qu'à lancer le logiciel.

Lancement de la connexion et du sniffer

Nous allons essayer de sniffer toute une connexion entre notre machine et un serveur sur Internet. 
Dans Wireshark, nous allons choisir sur quelle interface réseau nous voulons récupérer le trafic. Il est possible que vous ayez plusieurs interfaces réseau, comme une carte Ethernet ET une carte wifi. Dans ce cas, il faudra bien expliciter sur quelle carte réseau passe le trafic Internet.

Pour cela, nous allons cliquer dans le menu Capture, puis Interfaces, comme indiqué sur la figure suivante.

Capture interface Wireshark
Capture interface Wireshark

Une fenêtre s'ouvre en nous montrant nos différentes interfaces disponibles (voir la figure suivante). Nous allons cliquer sur Start pour commencer la capture, en choisissant l'interface qui reçoit le trafic Internet (celle qui reçoit des paquets en fait, en1 chez moi).

Interfaces Wireshark
Interfaces Wireshark

Dès que vous avez cliqué, la capture commence et vous devriez commencer à voir s'afficher les paquets reçus par votre carte réseau. Vous pouvez maintenant aller sur votre navigateur préféré et commencer une connexion vers le site. 
Attendez que la page soit affichée, et retournez dans Wireshark pour arrêter la capture en appuyant sur le menu Capture, puis Stop.

Vous devriez maintenant avoir reçu quelques paquets réseau que nous allons analyser ensemble. Mais avant cela, nous allons essayer de faire le tri dans tous les paquets reçus. En effet, il arrive souvent qu'il y ait beaucoup de trafic réseau et que les paquets qui nous intéressent soient perdus parmi les autres. Il est alors possible dans Wireshark de donner des critères pour filtrer les paquets présentés.

Pour cela, nous allons indiquer un filtre dans la partie filter. Nous allons prendre l'exemple d'un site dont l'IP serait 80.248.210.229 (vous pouvez adapter cet exemple avec l'adresse  de votre choix). Dans cet exemple, nous ne voulons afficher que les paquets qui contiennent l'adresse IP 80.248.210.229. Nous allons donc indiquer dans le filtre ip.addr == 80.248.210.229.

Filtre Wireshark
Filtre Wireshark

Cliquez sur Apply afin d'appliquer le filtre.

Vous ne devriez voir maintenant que les paquets qui concernent votre connexion avec l'IP concernée par le filtre.

Connexion siteduzero.com
Connexion site

Nous voyons bien dans la colonne info que les trois premiers paquets sont des paquets TCP ayant successivement les flags SYN, SYN+ACK et ACK. La connexion est donc bien initialisée !

Nous allons maintenant étudier quelques-uns de ces paquets en détail.

Étude des paquets

Nous allons cliquer sur le premier paquet SYN et observer son contenu.
Dans la fenêtre juste en dessous, celle de présentation détaillée d'un paquet, nous voyons les différentes couches de notre paquet représentées.

Détail d'un paquet complet
Détail d'un paquet complet

La première ligne représente notre paquet de façon brute, la couche 1 du modèle OSI, les 1 et les 0 en somme !
La seconde ligne représente la couche 2 du modèle OSI, on peut y voir notamment les adresses MAC.

La troisième ligne représente la couche 3 du modèle OSI, et on y voit notamment les adresses IP.
Enfin, la quatrième ligne représente la couche 4 du modèle OSI, et on y voit les ports TCP.

Euh... mais... il n'y a pas de couche 7 applicative ?

Eh bien non, pas encore. En effet, avant de pouvoir échanger nos données applicatives, il faut que la connexion TCP soit établie. Il faut donc que notre three way handshake soit terminé. Ce sont donc seulement des segments TCP qui sont d'abord échangés, et seulement ensuite, le quatrième paquet de la connexion devrait contenir des données applicatives.

Nous allons maintenant regarder en détail le contenu de chaque couche.
Commençons par la couche 2:

Détail de la couche 2
Détail de la couche 2

Comme nous pouvions nous y attendre, nous voyons les éléments que nous connaissons déjà, car nous les avons vus en étudiant la couche 2, souvenez-vous !

Adresse MAC DST

Adresse MAC SRC

Protocole de couche 3

Données à envoyer

CRC

Trame Ethernet
Nous voyons bien l'adresse MAC destination, puis l'adresse MAC source, et enfin le protocole de couche 3 utilisé, qui est ici IP.

Cela prouve aussi que je ne vous ai pas raconté que des bêtises jusqu'à maintenant. :p

Intéressons-nous à la couche 3 :

Détail de la couche 3
Détail de la couche 3

Là, c'est plus complexe, car nous n'avons pas encore vu le contenu complet de l'en-tête IP. Cependant, nous pouvons reconnaître en fin d'en-tête les adresses IP source et destination.

Enfin, intéressons-nous à la couche 4 :

Détail de la couche 4
Détail de la couche 4

Comme pour la couche 3, nous ne connaissons pas encore tout le contenu de la couche 4 mais nous pouvons reconnaître les ports en début d'en-tête ainsi que les flags en milieu d'en-tête.
On voit d'ailleurs que le flag SYN est positionné, mais Wireshark peut nous donner encore plus de détails en cliquant sur le triangle devant les flags.

Détail des flags
Détail des flags

Nous voyons bien ici les 6 flags que nous connaissons, URG, ACK, PSH, RST, SYN et FIN. Parmi ceux-ci, seul le flag SYN est positionné.
Le premier segment de notre connexion est bien un segment SYN de demande d'ouverture de connexion.

Si l'on clique sur le second paquet de la connexion, nous pouvons voir dans la couche 4 les flags SYN et ACK positionnés. Et de la même façon pour le flag ACK dans le troisième.
Notre connexion TCP est donc bien initialisée.

Nous devrions par conséquent avoir dans les prochains paquets les échanges applicatifs, c'est-à-dire les échanges web, de couche 7.
Effectivement, nous pouvons déjà voir que la trame contient une couche supplémentaire après la couche TCP. C'est notre protocole web dans la couche applicative.

Couche applicative dans notre paquet
Couche applicative dans notre paquet

Nous allons pouvoir cliquer sur le petit triangle pour en développer le contenu.

Contenu applicatif
Contenu applicatif

Nous pouvons voir ensuite différents paquets échangés entre le client et le serveur du site. Ces paquets peuvent être applicatifs, mais il y a aussi des paquets qui ne contiennent pas de données applicatives.
On appelle ces paquets des paquets de signalisation.
Ils servent à maintenir proprement la connexion entre les deux machines en indiquant en permanence à l'autre machine où nous en sommes de la connexion. C'est ce qui permet de garantir qu'aucune information ne sera perdue lors des échanges. Nous le verrons plus tard en détail.

Une fois que notre navigateur a reçu toutes les informations et que le site s'affiche, il nous reste à clore proprement la connexion TCP.

Comme vous le savez, cela se fait avec la séquence FIN+ACK, FIN+ACK, ACK.

Fermeture de la connexion TCP
Fermeture de la connexion TCP

Nous pouvons voir en détail les flags FIN et ACK de positionnés dans les paquets.

Flags FIN et ACK en fin de connexion
Flags FIN et ACK en fin de connexion

Notre connexion est bel et bien fermée !

Conclusion

Nous avons pu voir grâce au sniffer Wireshark les paquets qui circulaient sur notre réseau, et même suivre en détail le déroulement d'une connexion TCP qui a bien confirmé ce que nous avions appris.

Vous aurez maintenant la possibilité d'aller voir ce qui se passe, en détail, au niveau réseau, si jamais vous avez des problèmes de connexion.

Le sniffer est un outil indispensable pour un administrateur réseau dès lors qu'il veut comprendre en détail ce qui peut empêcher le bon fonctionnement de celui-ci, donc gardez-le sous la main. Chaque fois que vous aurez du mal à comprendre un mécanisme réseau, ou que vous devrez comprendre en détail ce qui ne marche pas, le sniffer sera votre meilleur allié !

  • Vous connaissez maintenant les adresses des applications réseau sur notre machine, qui sont les ports.

  • Vous savez maintenant que la couche 4 contient deux protocoles, TCP et UDP, qui diffèrent, car TCP est en mode connecté.

  • Et enfin, vous avez pu comprendre concrètement ce qui circulait sur le réseau grâce à l'utilisation d'un sniffer.

Si vous êtes arrivés jusqu'ici en étudiant correctement le cours et en faisant l'effort de bien le comprendre et de mettre en pratique les TP, vous connaissez maintenant le réseau !

Maintenant que nous avons une vision globale des couches réseau et que nous avons fait un peu de pratique, nous allons voir comment rendre nos applications joignables quand elles se situent sur un réseau privé, comme derrière une box chez vous.

Exemple de certificat de réussite
Exemple de certificat de réussite