Comment fonctionne la méthode HTTP GET par rapport au protocole DNS?

17

J'essaie de comprendre les protocoles de couche application dans la pile TCP / IP. Je sais que les protocoles HTTP et DNS restent à la couche supérieure (couche d'application). Ainsi, lorsqu'un navigateur souhaite accéder à une ressource, il doit envoyer une demande au serveur HTTP, comme par exemple:

GET www.pippo.it/hello.htm HTTP/1.1

En faisant cette demande en suivant les règles du protocole HTTP, il utilise l'URL de la page, pas l'adresse IP.

Je sais que la requête DNS est nécessaire pour convertir l'URL en IP. Ma question est donc la suivante: HTTP appelle-t-il le protocole DNS? Cela me semble impossible, car les deux sont des protocoles de couche supérieure (donc DNS ne peut pas fournir un service à HTTP). De la même manière, même TCP (qui reste à un niveau inférieur) ne peut pas demander un service à un protocole de niveau supérieur comme DNS.

Alors, quand la demande DNS se produit-elle? Et qui exécute une telle demande?

Giancarlo Perlo
la source
1
Pourriez-vous accepter l'une des réponses pour préciser laquelle de ces réponses à la question?
030

Réponses:

38

La requête HTTP en question n'est en fait valide que si le navigateur parle à un intermédiaire (proxy).

Votre exemple ressemblerait un peu plus à ce qui suit si le navigateur parlait directement avec un serveur Web:

GET /hello.htm HTTP/1.1
Host: www.pippo.it

Maintenant, pour mettre cela en perspective, considérons le modèle OSI:

Le modèle OSI

Nous avons 3 systèmes en action:

  • Un client exécutant le navigateur
  • Un serveur web au service du site
  • Un serveur DNS connaissant l'adresse IP du site

Les protocoles impliqués sont, de bas en haut (ensemble pertinent minimum à OP):

  • IP
  • TCP, UDP
  • HTTP, DNS

La communication HTTP se fait via le protocole TCP (TCP est au dessus du protocole IP) tandis que la communication DNS, dans ce cas, se fait via le protocole UDP (UDP est aussi au dessus du protocole IP).

Voici la séquence de communication en bref:

  1. Le client , l' exécution du navigateur, demande au serveur DNS pour un Aenregistrement pour www.pippo.it, en utilisant le protocole UDP.

    1.1. Sur le client, c'est le système d'exploitation qui s'occupe de la résolution et parle au navigateur --- le navigateur ne parle jamais directement au serveur DNS, plutôt via le système d'exploitation en appelant gethostbyname () ou le plus récent getaddrinfo () . Sous Windows, l'ordre dans lequel le système d'exploitation résout les adresses est probablement défini par quelque chose comme ceci , tandis que sous Linux, la priorité de résolution est définie par/etc/nsswitch.conf

  2. Le serveur DNS , utilisant le protocole UDP, répond au client avec un enregistrement / adresse IP, si elle existe

  3. Le client ouvre une connexion TCP sur le port 80 du serveur Web et écrit le texte suivant:

    Requête HTTP:

    GET /hello.htm HTTP/1.1
    Host: www.pippo.it
    

    Vous pouvez imiter la même chose en faisant quelque chose comme ceci dans votre console ou invite de commande:

    > telnet www.pippo.it 80
    Trying 195.128.235.49...
    Connected to www.pippo.it.
    Escape character is '^]'.
    GET /hello.htm HTTP/1.1
    Host: www.pippo.it
    

    suivi de deux lignes vides. Si le contenu demandé existe, le serveur Web l'imprimera à l'écran. S'il y a un navigateur de l'autre côté, le texte de la réponse est analysé par le navigateur et toutes les balises, liens, scripts et images sont affichés dans ce que nous appelons une page Web.

En réalité, il y a plus de détails, par exemple, les navigateurs peuvent mettre en cache les adresses IP si vous avez déjà visité un domaine, de sorte que la résolution DNS devient inutile. En outre, les navigateurs modernes peuvent essayer de résoudre le problème avant d'en avoir réellement besoin ( prélecture DNS ) pour accélérer votre navigation.

En outre, votre ordinateur peut contenir des enregistrements statiques dans un hostsfichier. Si un enregistrement correspond à la demande, l'entrée statique locale est utilisée en premier et aucun serveur DNS n'est jamais contacté. Ceci est configurable, et pas nécessairement vrai, mais c'est la valeur par défaut sur les systèmes d'exploitation que je connais.

Hrvoje Špoljar
la source
4
@trikly: c'est à cela que sert l'en-tête «Host». Sans cela, vous ne pouvez avoir qu'un seul site Web par adresse IP. Il s'agit d'une différence clé entre HTTP / 1.0 et HTTP / 1.1. Heureusement, les navigateurs HTTP / 1.0 sont rares maintenant - mais si vous souhaitez les prendre en charge, vous avez besoin d'une adresse IP différente pour chaque site (ils peuvent toujours être hébergés sur le même serveur).
AE
1
@AE Merci. Je pense que ma question n'était pas claire et c'est pourquoi Hrvoje n'a pas compris ce que je disais. (J'aurais dû dire domaine plutôt que URL). Je suis content que tu aies encore compris.
trlkly
1
Vous dites " Ce n'est pas une requête HTTP correcte ", et c'est surtout vrai, mais c'est plus proche que vous n'impliquez: " Pour permettre la transition vers des URL absolues dans toutes les demandes dans les futures versions de HTTP, tous les serveurs HTTP / 1.1 DOIVENT accepter le formulaire URL absolue dans demandes ". (RFC 2616 §5.1.2) Ce GET http://www.pippo.it/hello.htm HTTP/1.1serait donc une demande valide, si inhabituelle. Ce serait également une demande valide et habituelle à un proxy HTTP.
wfaulk
1
gethostbyname()est quelque peu dépassé. On ferait mieux de l'utiliser getaddrinfo()...
glglgl
1
@Utku malheureusement non car SSH suppose que l'autre extrémité parle le protocole SSH tandis que telnet est un protocole en texte brut et peut être utilisé pour parler à tout autre protocole en clair comme disons POP3, IMAP tant qu'ils n'utilisent pas SSL / TLS, auquel cas vous aurait besoin d'envelopper la session telnet avec une aide comme sslwrap ou quelque chose de similaire.
Hrvoje Špoljar
12

HTTP est transporté sur TCP, qui est un protocole IP. Pour faire une requête HTTP, le navigateur doit ouvrir une connexion TCP, et pour cela, il a besoin de l'adresse IP de destination (c'est-à-dire l'adresse IP du serveur). Pour résoudre le nom d'hôte du serveur, il doit donc émettre une requête DNS (généralement la requête DNS elle-même est envoyée par le système d'exploitation lorsqu'un programme appelle ses fonctions de résolution de noms; cependant, rien n'empêche un programme d'envoyer lui-même des requêtes DNS au DNS serveur). Une fois la connexion établie, il peut envoyer sa requête HTTP, qui contient le chemin d'accès à la ressource demandée, et un champ Host avec le nom d'hôte du serveur (par exemple, Host: www.pippo.it). Le nom d'hôte ne va pas sur la ligne de demande (ce serait en faitGET /hello.htm HTTP/1.1), sauf lorsque la demande est envoyée à un proxy HTTP (et dans ce cas, l'URL complète est présente, y compris la partie protocole, par exemple GET http://www.pippo.it/hello.htm HTTP/1.1),

Ale
la source
Merci, maintenant c'est plus clair, mais pas complètement. Vous écrivez que le navigateur doit émettre une demande DNS. D'accord, mais après avoir reçu l'IP du serveur DNS, comment l'utilise-t-il? Je veux dire, une telle IP n'apparaît pas dans la requête HTTP. Je suppose donc qu'il reste encore une étape avant d'émettre la requête HTTP et je pense que c'est l'ouverture de la connexion. Ce point n'est pas très clair pour moi ... Merci encore!
Giancarlo Perlo
5
En effet, l'IP est nécessaire pour ouvrir la connexion TCP, à l'intérieur de laquelle la requête HTTP est transportée. En fait, l'adresse IP du client et du serveur est envoyée avec TOUS les paquets de la connexion. La meilleure façon d'apprendre comment cela fonctionne est probablement d'installer un outil de capture de paquets (Wireshark est un excellent multiplateforme et open source), de capturer une simple requête HTTP, de la filtrer du reste de l'activité réseau et de voir comment tous les paquets ont été envoyés sur le fil. Vous devriez également pouvoir voir la demande DNS avant la connexion TCP.
Ale
1
Les requêtes mandatées doivent utiliser l'en-tête Host et non mettre l'URL complète dans la ligne GET.
OrangeDog
1
@OrangeDog: Non, au contraire. La RFC 7230 (section 5.3.2) dit explicitement qu'un client qui fait une demande à un proxy DOIT utiliser un URI absolu dans la ligne de demande. (Il doit toujours y avoir un en-tête Host dupliquant les informations de la ligne de demande; section 5.4).
hmakholm a quitté Monica
7

La procédure se déroule comme suit:

  1. L'utilisateur (vous) donne au navigateur une URL, comme http://www.pippo.it/hello.htm
  2. Le navigateur divise cela en trois parties:

    • Protocole http
    • Nom d'hôte www.pippo.it
    • Chemin URL /hello.htm

    (une URL plus compliquée pourrait aussi avoir d'autres parties, j'ignorerai cette possibilité pour l'instant)

  3. Le navigateur sait que pour créer une connexion IP, il a besoin d'une adresse IP. Pour obtenir une adresse IP, il doit utiliser DNS (sauf si l'adresse est mise en cache).

    1. Le navigateur demande au système d'exploitation l'adresse IP d'un serveur DNS; supposons que ça arrive 8.8.8.8.
    2. Le navigateur crée la connexion multicouche suivante:

      • Couche IP: se connecter à 8.8.8.8
      • Couche UDP: définir le paquet pour le port de destination 53
      • Couche DNS: créer une demande DNS pour un Aenregistrement pour le nom d'hôtewww.pippo.it

      Bien sûr, j'omets beaucoup de détails sur, par exemple, le format exact des paquets impliqués.

    3. Le navigateur reçoit une réponse DNS (en couches sur UDP en couches sur IP, etc.) qui donne l'adresse IP pour www.pippo.it, disons que c'est10.11.12.13
  4. Le navigateur sait que pour créer une connexion TCP, il a besoin d'un numéro de port. Pour obtenir un numéro de port, il recherche le protocole httpdans sa table interne et apprend qu'il doit utiliser le port 80.
  5. Le navigateur crée la connexion multicouche suivante:

    • Couche IP: se connecter à 10.11.12.13
    • Couche TCP: définissez les paquets sur le port de destination 80
    • Couche HTTP: créez une demande HTTP pour l'URL /hello.htmsur l'hôte www.pippo.it(car l'ordinateur 10.11.12.13peut héberger plusieurs domaines, il doit donc savoir lequel est souhaité)

      GET /hello.htm HTTP/1.1
      Host: www.pippo.it
      ...
      

    Bien sûr, j'omet tous les détails de la négociation TCP et autres.

  6. Le navigateur reçoit une réponse HTTP (superposée sur TCP superposée sur IP, etc.) contenant le contenu de hello.htm

Et pour faire bonne mesure, je mentionnerai que le navigateur examine maintenant le contenu de cette réponse et identifie toutes les ressources supplémentaires nécessaires: images, CSS, Javascript, etc. Ensuite, il répète tout ce processus pour chacune de ces ressources.

David Z
la source
4
L'étape 3 n'est vraiment pas quelque chose que l'application elle-même fait. L'application utilise simplement quelque chose comme getaddrinfoou gethostbynamepour demander au système d'exploitation de résoudre l'adresse correspondante. De plus, le système d'exploitation utilise généralement plusieurs mécanismes pour essayer de rechercher des noms, pas seulement DNS. (En général, au moins le fichier hosts en plus du DNS.)
Håkan Lindqvist
Merci! C'est une réponse vraiment impressionnante et détaillée et très utile aussi!
Giancarlo Perlo