Présentation du dialogue au niveau réseau entre une machine cliente et un serveur web (www.google.fr par exemple) Nous considèrerons que les protocoles utilisés sont ceux de la suite TCP/IP, soit TCP, IP et Ethernet pour notre dialogue. (A)--(Routeur NAT)--(Internet)-...-(Serveur) On considère que les machines viennent d'être mises en place et que leurs caches respectifs sont vides (aussi bien ARP que DNS ou applicatif) Un utilisateur se trouve devant la machine A et utilise Internet Explorer (malheureux !) pour naviguer sur Internet. Il entre dans la barre d'adresse l'adresse du site www.google.fr sur lequel il souhaite aller pour faire une recherche. La suite va présenter les différentes étapes qui vont intervenir pour qu'il obtienne la réponse du serveur de www.google.fr. Le navigateur (Internet Explorer) reçoit donc l'ordre d'accéder au site www.google.fr et de renvoyer la réponse à l'utilisateur. Une requête va donc devoir être émise sur le réseau vers le serveur web de www.google.fr pour obtenir la réponse. Pour comprendre comment cette requête va être formulée, nous allons faire un petit rappel sur le modèle OSI, sans pour autant rentrer dans les détails. Modèle OSI: 7 Application 6 Présentation 5 Session 4 Transport 3 Réseau 2 Liaison 1 Physique Ce modèle précise la norme de communication entre équipements réseau. Chacune des couches représentant une ou plusieurs tâches à accomplir pour arriver à communiquer de bout en bout. Lors de l'émission d'une requête, on part des couches dites "hautes" pour descendre vers les couches "basses". Ainsi, la requête demandée par l'application (ici IE) va parcourir les couches une à une, qui vont chacune ajouter l'information qui leur est propre, jusqu'à arriver à un message transportable sur le réseau. C'est ce qu'on appelle le principe d'encapsulation. Notre requête va donc partir de la couche applicative pour aller vers la couche physique qui transportera l'information. Nous ne rentrerons pas dans les détails du système d'exploitation gérant la communication inter-couches. Notre machine doit donc emmetre une requête vers le serveur www.google.fr. 1 - Format de la requête applicative: --------------------------------- Données applicatives ___________________________ | | | GET http://www.google.com | |___________________________| Or, en réseau, nous savons que les machines sont identifiées sur Internet par une adresse IP et non par un nom. Il faut donc que nous trouvions l'adresse du serveur www.google.fr. Le protocole DNS est justement fait pour cela. Nous ne rentrerons pas dans les détails de celui-ci, un livre entier étant nécessaire à sa complète compréhension ! :-) On considère donc que la machine A fait une requête DNS pour obtenir l'adresse IP du serveur www.google.fr et qu'elle obtient sa réponse. Elle peut maintenant envoyer l'information sur le réseau vu qu'elle connait l'adresse IP de destination. L'application envoit donc les informations applicatives à la couche 4 (TCP) qui ajoute ses propres informations, notamment le port destination qui correspond au protocole applicatif utilisé (80:HTTP) et le port source choisi supérieur à 1023. La couche 4 doit alors envoyer l'ensemble des informations (en-tête TCP et données applicatives qui forment le segment TCP) au protocole de couche 3 qui est IP (le choix des protocoles utilisés se fait lors de la création de la socket de connexion) 2 - Format du segment TCP envoyé: --------------------------------- En-tête TCP Données applicatives ++++++++++++++++++++++++++++++++++++++++++++++++++++++++___________________________ | Port source | Port Destination | Autres informations | | | 10351 | 80 | de l'en-tête TCP | GET http://www.google.com | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++____________________|______| La couche 3 a notamment pour rôle de déterminer la passerelle à utiliser pour joindre la machine de destination. Pour cela, elle va voir dans la table de routage dans laquelle des réseaux sont définis et pour lesquels une passerelle est indiquée. Suite au passage par la table de routage, le système sait donc quelle est l'adresse IP de la passerelle à utiliser. Soit il s'agit de l'adresse d'une passerelle située sur le même réseau que la machine A, soit il s'agit directement de l'adresse de la machine destination si celle-ci est sur le même réseau que A. Dans les deux cas, nous obtenons l'adresse IP d'une machine à atteindre, située sur notre propre réseau. Cependant, cette information n'est pas suffisante car pour dialoguer sur le réseau local, il nous faut connaître non pas l'adresse IP mais l'adresse MAC de la machine destination car c'est celle-ci qui est utilisée par le protocole de couche 2 qui achemine les informations sur le réseau. Il nous faut donc maintenant obtenir l'adresse MAC de la machine à atteindre sur notre réseau. Nous avons pour cela le protocole ARP à notre disposition. Etant donné que le cache ARP de notre machine A est vide, il va nous falloir faire un broadcast ARP qui nous permettra d'obtenir l'adresse MAC de la machine à joindre. Dans notre exemple, il s'agit de l'adresse MAC de l'interface interne du routeur NAT. Nous avons maintenant toutes les informations nécessaires pour envoyer les données à la couche 2. La couche 3 ajoute donc ses propres informations au segment TCP, notamment les adresse IP source et destination (la machine A ainsi que le serveur google) et envoit l'ensemble, soit le datagramme IP, à la couche 2, avec l'adresse MAC de la prochaine destination à joindre (l'interface interne du routeur NAT) 3 - Format du datagramme IP: ---------------------------- En-tête IP En-tête TCP Données applicatives *************************************************++++++++++++++++++++++___________________________ | @IP source | @IP dest | Autres informations | PS | PD | Autre | | | @IP A | @IP google | de l'en-tête IP | 10351 | 80 | TCP | GET http://www.google.com | *************************************************++++++++++++++++++++++___________________________| La couche 2 reçoit le datagramme IP et peut alors former la trame Ethernet en ajoutant l'en-tête Ethernet au datagramme IP reçu. L'en-tête Ethernet contient notamment les adresses MAC source et destination (adresse MAC de A et du routeur NAT ici) La trame peut maintenant être envoyée sur le réseau. 4 - Format de la trame Ethernet: -------------------------------- En-tête Ethernet En-tête IP En-tête TCP Données applicatives .................................************************++++++++++++++++++++++____________________________...... | @ MAC DST | @ MAC SRC | Proto | @IP s | @IP d | Autre | PS | PD | Autre | | | | Rtr NAT | A | sup | @IP A | @IP g | IP | 10351 | 80 | TCP | GET http://www.google.com | CRC | .................................************************++++++++++++++++++++++___________________________|...... Elle transite sur le câble en sortie de notre machine puis arrive à l'équipement de connexion, qui est un switch dans notre cas. Le switch, qui est un équipement de couche 2 peut lire l'en-tête Ethernet de la trame. Il regarde l'adresse MAC de destination et cherche dans sa table CAM (correspondance @MAC et numéro de port) pour voir si cette adresse est connectée sur l'un de ses ports. Si c'est le cas, il retransmet la trame sur le bon port, sinon, il la retransmet sur tous les ports en espérant que la machine destination le recevra... (cela n'arrive cependant que très rarement) La trame arrive donc sur l'interface interne du routeur NAT. Si l'on se réfère au modèle OSI, l'information reçue provenant de la couche physique va remonter les couches jusqu'à la couche applicative. Modèle OSI: 7 Application ^ 6 Présentation | 5 Session | Sens de 4 Transport | reception 3 Réseau | des données 2 Liaison | 1 Physique | Ainsi, la trame va être reçue par la couche 2 qui va regarder si l'adresse MAC destination est bien celle de l'interface l'ayant reçue. Si ce n'est pas le cas, la trame est ignorée. Si c'est le cas, l'en-tête Ethernet est lue et les informations sont envoyées à la couche 3 spécifiée dans cette en-tête, soit la couche IP dans notre cas. La couche 3, IP, reçoit le datagramme et lit l'en-tête IP qui contient l'adresse IP de destination. Si l'adresse IP de destination est celle d'une des interfaces de la machine, les informations sont envoyées à la couche supérieure indiquée dans l'en-tête IP Si l'@IP de destination n'est pas celle de notre machine, cela veut dire que l'information doit être routée vers sa destination (nous sommes dans ce cas quand le routeur reçoit le datagramme qui est à destination de google) Le routeur va donc regarder dans sa table de routage par quelle passerelle il doit passer pour envoyer les informations jusqu'au réseau de destination. Dans notre cas, il s'agit d'un routeur sur Internet. Il n'est alors plus nécessaire de remonter les couches. Une petite particularité intervient maintenant. L'adresse source du datagramme IP est celle de la machine A. Or cette adresse est une adresse privée non routée sur Internet. Si le datagramme sort tel quel sur Internet, le serveur google le recevra bien, mais il y aura des problèmes de routage au retour puisque l'adresse de destination du datagramme (qui était en source lors de l'émission du datagramme) n'est pas routée sur Internet. Il est donc nécessaire de modifier l'adresse source lors de l'émission du datagramme. C'est ce que l'on appelle la traduction d'adresse, ou NAT. --> Le routeur met donc en correspondance l'@IP source d'origine ainsi que le port source d'origine (ce qui l'oblige à être capable de lire des informations de couche 4) et l'adresse IP de son interface externe (adresse publique routable sur Internet) ainsi qu'un port source qu'il aura choisi lui-même (il garantit ainsi l'impossibilité d'avoir deux paquets avec deux ports source identiques) Il garde ces informations dans une table que l'on nomme table NAT. 5 - Informations retenues dans la table NAT: -------------------------------------------- @IP A <--> @IP externe du routeur NAT Port source Port source routeur 10351 <--> 36253 En mettant ces informations en correspondance, il pourra de nouveau les remplacer lorsqu'il recevra le paquet de réponse à la requête. Il peut maintenant remplacer l'adresse IP source ainsi que le port source dans le paquet. Notre routeur désire maintenant envoyer les informations au prochain routeur spécifié dans la table de routage, qui appartient à son réseau. Comme précédemment, il doit rechercher l'adresse MAC correspondant à l'interface du prochain routeur. Il pourra alors envoyer les informations à la couche 2 qui pourra former la trame Ethernet qui circulera sur le réseau. Le passage par les différents routeurs sera identique sur le chemin vers le serveur google (NAT mise à part) Le serveur www.google.fr reçoit donc la requête. Il regarde l'adresse MAC de destination qui doit normalement être la sienne si tout s'est bien passé. La couche 2 envoit alors les informations à la couche 3 spécifiée dans l'en-tête Ethernet, soit à la couche IP. La couche IP lit l'en-tête du datagramme IP. L'adresse IP de destination est bien celle de l'une de ses interfaces, le datagramme va donc être traité puis envoyé à la couhe 4 mentionnée dans l'en-tête. Il s'agit ici de TCP. La couche 4 recptionne le segment TCP et lit l'en-tête TCP. Si le port destination spécifié ne correspond à aucune socket en cours, un TCP reset (RST) est renvoyé. Si cela correspond par contre à une socket, la couche TCP traite les informations qui lui sont propres, et les données sont envoyées à la couche applicative liée à la socket. Le serveur web va alors traiter la requête du client et lui renvoyer sa réponse. La réponse va alors suivre le cheminement inverse à travers les couches réseau pour arriver à l'envoi d'une trame Ethernet sur le réseau. La trame va alors circuler sur Internet avec comme adresse IP de destination celle du routeur NAT. Il va donc la recevoir et regarder dans la table NAT la correspondance avec le numéro de port destination TCP utilisé (il reçoit un segment TCP avec le port source 36253 qu'il reconnait dans la table NAT) Il peut maintenant remplacer l'adresse IP destination par celle de la machine A, ainsi que le port TCP source par celui spécifié à l'origine. Le datagramme IP ainsi modifié peut être renvoyé sur le réseau (encapsulé dans une trame Ethernet ;-) La machine A reçoit la trame Ethernet. Les informations vont cheminer à travers les couches réseau jusqu'à l'application d'origine qui est le navigateur Internet qui va recevoir la réponse à sa requête et qui va pouvoir l'afficher à son client. ATTENTION ! Dans cet exemple, j'ai volontairement simplifié la configuration dans laquelle nous nous trouvons. Il faut bien prendre en compte: - que le modèle TCP/IP est différent du modèle OSI (on ne tient pas compte des couches 5 et 6), - qu'on ne tient pas compte de la fragmentation, - qu'on ne tient pas compte non plus du handshake TCP ni des numéros de séquence, etc, - qu'aucun proxy applicatif n'est traversé (voir http://www.lalitte.com/nat pour plus d'infos) - qu'aucun ordre n'est respecté dans les différentes en-têtes. Pour toute question ou en cas d'erreur de ma part, n'hésitez pas à me contacter: eric @ lalitte.com