Wie funktioniert die HTTP-GET-Methode in Bezug auf das DNS-Protokoll?

17

Ich versuche, Anwendungsschichtprotokolle im TCP / IP-Stapel zu verstehen. Ich weiß, dass sowohl das HTTP- als auch das DNS-Protokoll auf der obersten Ebene (Application Layer) verbleiben. Wenn ein Browser auf eine Ressource zugreifen möchte, muss er eine Anfrage an den HTTP-Server senden, wie zum Beispiel:

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

Bei dieser Anforderung gemäß den Regeln des HTTP-Protokolls wird die Seiten-URL und nicht die IP-Adresse verwendet.

Ich weiß, dass eine DNS-Anfrage erforderlich ist, um eine URL in eine IP zu konvertieren. Meine Frage lautet also: Ruft HTTP das DNS-Protokoll auf? Es scheint mir unmöglich, da beide Protokolle der obersten Ebene sind (DNS kann also keinen Dienst für HTTP bereitstellen). Auf die gleiche Weise kann auch TCP (das auf einer niedrigeren Ebene bleibt) keinen Dienst auf einem höheren Protokoll wie DNS anfordern.

Wann kommt die DNS-Anfrage? Und wer führt eine solche Anfrage durch?

Giancarlo Perlo
quelle
1
Können Sie eine der Antworten akzeptieren, um zu klären, auf welche dieser Antworten die Frage zutrifft?
030

Antworten:

38

Die betreffende HTTP-Anfrage ist tatsächlich nur gültig, wenn der Browser mit einem Vermittler (Proxy) spricht.

Ihr Beispiel sieht ungefähr so ​​aus, wenn der Browser direkt mit einem Webserver kommuniziert:

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

Betrachten Sie nun das OSI-Modell, um dies in die richtige Perspektive zu rücken:

Das OSI-Modell

Wir haben 3 Systeme in Aktion:

  • Ein Client , auf dem der Browser ausgeführt wird
  • Ein Webserver, der die Site bedient
  • Ein DNS-Server , der die IP-Adresse der Site kennt

Die beteiligten Protokolle sind von unten nach oben (Mindestrelevanz auf OP gesetzt):

  • IP
  • TCP, UDP
  • HTTP, DNS

Die HTTP-Kommunikation erfolgt über das TCP-Protokoll (TCP steht über dem IP-Protokoll), während die DNS-Kommunikation in diesem Fall über das UDP-Protokoll erfolgt (UDP steht auch über dem IP-Protokoll).

Hier ist die Kommunikationssequenz in Kürze:

  1. Der Client , auf dem der Browser ausgeführt wird, fragt den DNS-Server nach einem AEintrag www.pippo.itunter Verwendung des UDP-Protokolls.

    1.1. Auf dem Client übernimmt das Betriebssystem die Lösung und kommuniziert mit dem Browser. Der Browser kommuniziert nie direkt mit dem DNS-Server, sondern über das Betriebssystem, indem er gethostbyname () oder das neuere Programm getaddrinfo () aufruft . Unter Windows , in dem die Reihenfolge der OS - Adressen aufgelöst wird durch so etwas wie wahrscheinlich definiert dies , während auf Linux die Lösung Vorrang definiert ist durch/etc/nsswitch.conf

  2. Der DNS-Server , der das UDP-Protokoll verwendet, antwortet dem Client mit einer Datensatz- / IP-Adresse, falls vorhanden

  3. Der Client öffnet eine TCP-Verbindung auf dem Port 80 des Webservers und schreibt den folgenden Text:

    HTTP-Anfrage:

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

    Sie können dasselbe nachahmen, indem Sie in Ihrer Konsole oder Eingabeaufforderung Folgendes ausführen:

    > 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
    

    gefolgt von zwei leeren Zeilen. Wenn der angeforderte Inhalt vorhanden ist, druckt der Webserver ihn auf dem Bildschirm aus. Wenn sich auf der anderen Seite ein Browser befindet, wird der Antworttext vom Browser analysiert, und alle Tags, Links, Skripte und Bilder werden auf einer so genannten Webseite gerendert.

In der Realität gibt es einige Details, z. B. können Browser IP-Adressen zwischenspeichern, wenn Sie bereits eine Domain besucht haben, sodass eine DNS-Auflösung nicht mehr erforderlich ist. Moderne Browser versuchen möglicherweise auch, das Auflösen durchzuführen, bevor Sie es tatsächlich benötigen ( DNS-Prefetching ), um das Surfen zu beschleunigen.

Darüber hinaus verfügt Ihr Computer möglicherweise über statische Datensätze in einer hostsDatei. Wenn ein Datensatz mit der Anforderung übereinstimmt, wird zuerst der lokale statische Eintrag verwendet und es wird nie ein DNS-Server kontaktiert. Dies ist konfigurierbar und nicht unbedingt wahr, aber es ist die Standardeinstellung für die mir vertrauten Betriebssysteme.

Hrvoje Špoljar
quelle
4
@trikly: Dafür ist der 'Host'-Header gedacht. Ohne sie können Sie nur eine Website pro IP-Adresse haben. Dies ist ein wesentlicher Unterschied zwischen HTTP / 1.0 und HTTP / 1.1. Zum Glück sind HTTP / 1.0-Browser derzeit rar - aber wenn Sie sie bedienen möchten, benötigen Sie für jede Site eine andere IP-Adresse (sie können weiterhin auf demselben Server gehostet werden).
AE
1
Vielen Dank. Ich glaube, ich war in meiner Frage unklar, und deshalb verstand Hrvoje nicht, was ich sagte. (Ich hätte sagen sollen, Domain statt URL). Ich bin froh, dass du es noch verstanden hast.
trlkly
1
Sie sagen " Dies ist keine korrekte HTTP-Anforderung ", und das ist größtenteils der Fall, aber es ist näher, als Sie vermuten: " Damit in zukünftigen Versionen von HTTP alle Anforderungen auf absoluteURIs umgestellt werden können, MÜSSEN alle HTTP / 1.1-Server das absoluteURI-Formular in akzeptieren Anfragen ". (RFC 2616 §5.1.2) Wäre GET http://www.pippo.it/hello.htm HTTP/1.1also eine gültige, wenn auch ungewöhnliche Anfrage. Es wäre auch eine gültige und übliche Anfrage an einen HTTP-Proxy.
Wfaulk
1
gethostbyname()ist etwas veraltet. Man sollte besser getaddrinfo()...
Glglgl
1
@Utku leider nein, da SSH davon ausgeht, dass das andere Ende das SSH-Protokoll spricht, während Telnet das Klartextprotokoll ist und verwendet werden kann, um mit jedem anderen Klartextprotokoll wie POP3, IMAP zu sprechen, sofern Sie in diesem Fall kein SSL / TLS verwenden Müsste eine Telnet-Sitzung mit einem Helfer wie sslwrap oder etwas Ähnlichem abschließen.
Hrvoje Špoljar
12

HTTP wird über TCP transportiert, ein IP-Protokoll. Um eine HTTP-Anfrage zu stellen, muss der Browser eine TCP-Verbindung herstellen und benötigt dazu die Ziel-IP-Adresse (dh die IP-Adresse des Servers). Um den Hostnamen des Servers aufzulösen , muss er daher eine DNS-Anfrage stellen (im Allgemeinen wird die DNS-Anfrage selbst vom Betriebssystem gesendet, wenn ein Programm seine Funktionen zur Namensauflösung aufruft; nichts hindert ein Programm jedoch daran, DNS-Anfragen selbst an das DNS zu senden Server). Sobald die Verbindung hergestellt ist, kann sie ihre HTTP-Anfrage senden, die den Pfad zur angeforderten Ressource und ein Host- Feld mit dem Hostnamen des Servers enthält (z Host: www.pippo.it. B. ). Der Hostname steht nicht in der Anforderungszeile (das wäre tatsächlich der Fall)GET /hello.htm HTTP/1.1), es sei denn, die Anforderung wird an einen HTTP-Proxy gesendet (und in diesem Fall ist die vollständige URL einschließlich des Protokollteils vorhanden, z. B. GET http://www.pippo.it/hello.htm HTTP/1.1).

Ale
quelle
Danke, jetzt ist es klarer, aber nicht ganz. Sie schreiben, dass der Browser eine DNS-Anfrage stellen muss. OK, aber nachdem die IP vom DNS-Server empfangen wurde, wie wird sie verwendet? Ich meine, eine solche IP erscheint nicht in der HTTP-Anfrage. Ich gehe also davon aus, dass es noch einen weiteren Schritt gibt, bevor die HTTP-Anforderung ausgegeben wird, und ich denke, dass dies das Öffnen der Verbindung ist. Dieser Punkt ist mir nicht sehr klar ... Nochmals vielen Dank!
Giancarlo Perlo
5
Tatsächlich wird die IP benötigt, um die TCP-Verbindung zu öffnen, innerhalb derer die HTTP-Anforderung transportiert wird. Tatsächlich wird die IP-Adresse von Client und Server zusammen mit ALLEN Paketen der Verbindung gesendet. Der beste Weg, um zu erfahren, wie dies funktioniert, ist die Installation eines Paketerfassungstools (Wireshark ist eine hervorragende plattformübergreifende und Open-Source-Lösung), die Erfassung einer einfachen HTTP-Anfrage, das Herausfiltern aus dem Rest der Netzwerkaktivität und das Überprüfen der Funktionsweise Alle Pakete wurden auf dem Draht gesendet. Sie sollten die DNS-Anfrage tatsächlich auch vor der TCP-Verbindung sehen können.
Ale
1
Proxy-Anforderungen sollten den Host-Header verwenden und nicht die vollständige URL in die GET-Zeile einfügen.
Hören Sie auf, Monica
1
@OrangeDog: Nein, im Gegenteil. RFC 7230 (Abschnitt 5.3.2) besagt ausdrücklich, dass ein Client, der eine Anforderung an einen Proxy sendet, einen absoluten URI in der Anforderungszeile verwenden MUSS. (Es muss noch ein Host-Header vorhanden sein, der Informationen aus der Anforderungszeile dupliziert; Abschnitt 5.4).
Henning Makholm
7

Die Prozedur geht so:

  1. Der Benutzer (Sie) gibt dem Browser eine URL wie http://www.pippo.it/hello.htm
  2. Der Browser teilt das in drei Teile:

    • Protokoll http
    • Hostname www.pippo.it
    • URL-Pfad /hello.htm

    (Eine kompliziertere URL könnte auch andere Teile haben. Diese Möglichkeit werde ich vorerst ignorieren.)

  3. Der Browser weiß, dass er zum Herstellen einer IP-Verbindung eine IP-Adresse benötigt. Um eine IP-Adresse zu erhalten, muss DNS verwendet werden (sofern die Adresse nicht zwischengespeichert ist).

    1. Der Browser fragt das Betriebssystem nach der IP-Adresse eines DNS-Servers. Angenommen, es wird 8.8.8.8.
    2. Der Browser baut die folgende mehrschichtige Verbindung auf:

      • IP-Schicht: Verbindung zu 8.8.8.8
      • UDP-Schicht: Paket für Zielport 53 festlegen
      • DNS-Schicht: Erstellen Sie eine DNS-Anforderung für einen AEintrag für den Hostnamenwww.pippo.it

      Natürlich verzichte ich auf viele Details, z. B. zum genauen Format der betroffenen Pakete.

    3. Der Browser empfängt eine DNS-Antwort (überlagert mit UDP überlagert mit IP usw.), die die IP-Adresse www.pippo.itangibt, sagen wir, dass dies der Fall ist10.11.12.13
  4. Der Browser weiß, dass er zum Herstellen einer TCP-Verbindung eine Portnummer benötigt. Um eine Portnummer zu erhalten, schlägt es das Protokoll httpin seiner internen Tabelle nach und erfährt, dass es Port 80 verwenden sollte.
  5. Der Browser baut die folgende mehrschichtige Verbindung auf:

    • IP-Schicht: Verbindung zu 10.11.12.13
    • TCP-Schicht: Pakete auf Zielport 80 setzen
    • HTTP-Ebene: Erstellen Sie eine HTTP-Anforderung für die URL /hello.htmauf dem Host www.pippo.it(da der Computer 10.11.12.13möglicherweise mehrere Domains hostet, muss er wissen, welche gewünscht wird).

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

    Natürlich verzichte ich auf alle Details des TCP-Handshakes und so weiter.

  6. Der Browser empfängt eine HTTP-Antwort (überlagert mit TCP überlagert mit IP usw.), die den Inhalt von enthält hello.htm

Und zum guten Teil möchte ich erwähnen, dass der Browser jetzt den Inhalt dieser Antwort untersucht und alle zusätzlichen Ressourcen identifiziert, die benötigt werden: Bilder, CSS, Javascript usw. Anschließend wird der gesamte Vorgang für jede dieser Ressourcen wiederholt.

David Z
quelle
4
Schritt 3 ist nicht wirklich etwas, was die Anwendung selbst tut. Die Anwendung verwendet nur so etwas wie getaddrinfooder gethostbyname, um das Betriebssystem zu bitten, die Adresse dafür aufzulösen. Außerdem verwendet das Betriebssystem in der Regel mehrere Mechanismen, um nach Namen zu suchen, nicht nur nach DNS. (In der Regel mindestens die Hosts-Datei zusätzlich zu DNS.)
Håkan Lindqvist
Vielen Dank! Es ist eine wirklich beeindruckende und detaillierte Antwort und auch sehr nützlich!
Giancarlo Perlo