Como o método HTTP GET funciona em relação ao protocolo DNS?

17

Estou tentando entender os protocolos da camada de aplicativo na pilha TCP / IP. Eu sei que os protocolos HTTP e DNS ficam na camada superior (camada de aplicativo). Portanto, quando um navegador deseja acessar um recurso, ele deve enviar uma solicitação ao servidor HTTP, como por exemplo:

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

Fazendo essa solicitação seguindo as regras do protocolo HTTP, ele usa o URL da página, não o endereço IP.

Eu sei que a solicitação de DNS é necessária para converter o URL em IP. Então, minha pergunta é: o HTTP invoca o protocolo DNS? Parece-me impossível, pois ambos são protocolos de camada superior (portanto, o DNS não pode fornecer um serviço para HTTP). Da mesma forma, mesmo o TCP (que permanece em um nível inferior) não pode solicitar um serviço em um protocolo de nível superior como o DNS.

Então, quando acontece a solicitação de DNS? E quem executa essa solicitação?

Giancarlo Perlo
fonte
1
Você poderia aceitar uma das respostas para esclarecer qual delas responde a pergunta?
030

Respostas:

38

A solicitação HTTP em questão não é realmente válida, a menos que o navegador esteja conversando com um intermediário (proxy).

Seu exemplo seria um pouco mais parecido com o seguinte se o navegador estivesse conversando diretamente com um servidor da Web:

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

Agora, para colocar isso em perspectiva, considere o modelo OSI:

O modelo OSI

Temos 3 sistemas em ação:

  • Um cliente executando o navegador
  • Um servidor da web que atende o site
  • Um servidor DNS que conhece o endereço IP do site

Os protocolos envolvidos são, de baixo para cima (conjunto mínimo relevante para OP):

  • IP
  • TCP, UDP
  • HTTP, DNS

A comunicação HTTP é feita através do protocolo TCP (o TCP está no topo do protocolo IP) enquanto a comunicação DNS, neste caso, é feita no protocolo UDP (o UDP também está no topo do protocolo IP).

Aqui está a sequência de comunicação em resumo:

  1. O cliente , executando o navegador, pede ao servidor DNS para um Arecorde para www.pippo.it, utilizando o protocolo UDP.

    1.1 No cliente, é o sistema operacional que faz a parte de resolução e retorna ao navegador - o navegador nunca se comunica diretamente com o servidor DNS, mas pelo sistema operacional, invocando gethostbyname () ou o getaddrinfo () mais recente . No Windows, a ordem em que o sistema operacional resolve endereços é provavelmente definida por algo como isso , enquanto no Linux a precedência resolver é definida por/etc/nsswitch.conf

  2. O servidor DNS , usando o protocolo UDP, responde ao cliente com um endereço IP / registro, se existir

  3. O cliente abre uma conexão TCP na porta 80 do servidor da web e grava o seguinte texto:

    Solicitação HTTP:

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

    Você pode imitar a mesma coisa fazendo algo assim no console ou no prompt de comando:

    > 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
    

    seguido por duas linhas vazias. Se o conteúdo solicitado existir, o servidor da web o imprimirá na tela. Se houver um navegador do outro lado, o texto da resposta será analisado pelo navegador e todas as tags, links, scripts e imagens serão renderizados no que chamamos de página da web.

Na realidade, existem mais alguns detalhes, por exemplo, navegadores podem armazenar em cache endereços IP se você já visitou algum domínio, para que a resolução do DNS se torne desnecessária. Além disso, os navegadores modernos podem tentar resolver antes que você realmente precise ( pré-busca de DNS ) para acelerar sua navegação.

Além disso, seu computador pode ter registros estáticos em um hostsarquivo. Se um registro corresponder à solicitação, a entrada estática local será usada primeiro e nenhum servidor DNS será contatado. Isso é configurável e não necessariamente verdadeiro, mas é o padrão nos sistemas operacionais com os quais estou familiarizado.

Hrvoje Špoljar
fonte
4
@ Trikly: é para isso que serve o cabeçalho 'Host'. Sem ele, você pode ter apenas um site por endereço IP. Essa é a principal diferença entre HTTP / 1.0 e HTTP / 1.1. Felizmente, os navegadores HTTP / 1.0 são raros agora - mas se você quiser atendê-los, precisará de um endereço IP diferente para cada site (eles ainda podem ser hospedados no mesmo servidor).
AE
1
@AE Obrigado. Acho que não estava claro na minha pergunta, e é por isso que Hrvoje não entendeu o que estava dizendo. (Eu deveria ter dito o domínio em vez do URL). Estou feliz que você ainda tenha entendido.
trlkly
1
Você diz " Isso não é uma solicitação HTTP correta ", e isso é verdade, mas é mais próximo do que você sugere: " Para permitir a transição para AbsolURIs em todos os pedidos em futuras versões do HTTP, todos os servidores HTTP / 1.1 DEVEM aceitar o formulário AbsolURI em pedidos ". (RFC 2616 §5.1.2) Portanto, GET http://www.pippo.it/hello.htm HTTP/1.1seria uma solicitação válida, se não usual. Também seria uma solicitação válida e usual para um proxy HTTP.
wfaulk
1
gethostbyname()está um pouco desatualizado. Alguém poderia usar getaddrinfo()...
glglgl
1
@Utku infelizmente não, porque o SSH presume que a outra extremidade fala o protocolo SSH, enquanto o telnet é um protocolo de texto sem formatação e pode ser usado para conversar com qualquer outro protocolo sem formatação, como POP3, IMAP, desde que eles não usem SSL / TLS. Nesse caso, você precisaria encerrar a sessão de telnet com o helper como sslwrap ou algo semelhante.
Hrvoje Špoljar
12

O HTTP é transportado pelo TCP, que é um protocolo IP. Para fazer uma solicitação HTTP, o navegador precisa abrir uma conexão TCP e, para isso, precisa do endereço IP de destino (ou seja, o endereço IP do servidor). Para resolver o nome do host do servidor, é necessário emitir uma solicitação DNS (geralmente a própria solicitação DNS é enviada pelo sistema operacional quando um programa chama suas funções de resolução de nomes; no entanto, nada impede que um programa envie solicitações DNS por si só ao DNS servidor). Depois que a conexão é estabelecida, ela pode enviar sua solicitação HTTP, que contém o caminho para o recurso solicitado, e um campo Host com o nome do host do servidor (por exemplo, Host: www.pippo.it). O nome do host não vai na linha de solicitação (seria realmenteGET /hello.htm HTTP/1.1), exceto quando a solicitação é enviada para um proxy HTTP (e, neste caso, a URL completa está presente, incluindo a parte do protocolo, por exemplo GET http://www.pippo.it/hello.htm HTTP/1.1),

Ale
fonte
Obrigado, agora é mais claro, mas não completamente. Você escreve que o navegador precisa emitir uma solicitação de DNS. Ok, mas depois de receber o IP do servidor DNS, como ele é usado? Quero dizer, esse IP não aparece na solicitação HTTP. Portanto, suponho que ainda haja mais uma etapa antes de emitir a solicitação HTTP e acho que é a abertura da conexão. Este ponto não está muito claro para mim ... Obrigado mais uma vez!
Giancarlo Perlo
5
De fato, o IP é necessário para abrir a conexão TCP, dentro da qual a solicitação HTTP é transportada. Na verdade, o endereço IP do cliente e do servidor é enviado junto com TODOS os pacotes da conexão. A melhor maneira de aprender como isso funciona é provavelmente instalar uma ferramenta de captura de pacotes (o Wireshark é uma excelente plataforma multiplataforma e de código aberto), capturar uma solicitação HTTP simples, filtrá-la do restante da atividade de rede e ver como todos os pacotes foram enviados pelo fio. Você também deve poder ver a solicitação de DNS antes da conexão TCP.
Ale
1
Solicitações por proxy devem estar usando o cabeçalho Host, não colocando o URL completo na linha GET.
Pare de prejudicar Monica
1
@ OrangeDog: Não, pelo contrário. A RFC 7230 (seção 5.3.2) diz explicitamente que um cliente que faz uma solicitação a um proxy DEVE usar um URI absoluto na linha de solicitação. (Deve ainda ser um cabeçalho host duplicação de informação a partir da linha pedido; a secção 5.4).
hmakholm deixou Monica em
7

O procedimento é assim:

  1. O usuário (você) fornece ao navegador uma URL, como http://www.pippo.it/hello.htm
  2. O navegador divide isso em três partes:

    • Protocolo http
    • nome de anfitrião www.pippo.it
    • Caminho do URL /hello.htm

    (um URL mais complicado também pode ter outras partes, ignorarei essa possibilidade por enquanto)

  3. O navegador sabe que, para criar uma conexão IP, ele precisa de um endereço IP. Para obter um endereço IP, ele precisa usar o DNS (a menos que tenha o endereço em cache).

    1. O navegador solicita ao sistema operacional o endereço IP de um servidor DNS; suponha que fique 8.8.8.8.
    2. O navegador constrói a seguinte conexão de várias camadas:

      • Camada IP: conecte-se a 8.8.8.8
      • Camada UDP: defina o pacote para a porta de destino 53
      • Camada DNS: crie uma solicitação DNS para um Aregistro para o nome do hostwww.pippo.it

      É claro que estou omitindo muitos detalhes sobre, por exemplo, o formato exato dos pacotes envolvidos.

    3. O navegador recebe uma resposta DNS (em camadas sobre UDP em camadas sobre IP etc.) que fornece o endereço IP www.pippo.it, digamos que seja10.11.12.13
  4. O navegador sabe que, para criar uma conexão TCP, ele precisa de um número de porta. Para obter um número de porta, ele httpconsulta o protocolo em sua tabela interna e aprende que deve usar a porta 80.
  5. O navegador constrói a seguinte conexão de várias camadas:

    • Camada IP: conecte-se a 10.11.12.13
    • Camada TCP: defina pacotes para a porta de destino 80
    • Camada HTTP: crie uma solicitação HTTP para o URL /hello.htmno host www.pippo.it(porque o computador 10.11.12.13pode estar hospedando vários domínios, portanto, ele precisa saber qual é o desejado)

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

    Claro que estou omitindo todos os detalhes do aperto de mão TCP e tal.

  6. O navegador recebe uma resposta HTTP (em camadas sobre TCP em camadas sobre IP etc.) contendo o conteúdo de hello.htm

E, para uma boa medida, mencionarei que o navegador agora examina o conteúdo dessa resposta e identifica quaisquer recursos adicionais necessários: imagens, CSS, Javascript, etc. Em seguida, repete todo esse processo para cada recurso.

David Z
fonte
4
O passo 3 realmente não é algo que o próprio aplicativo faz. O aplicativo usa apenas algo como getaddrinfoou gethostbynamesolicita ao sistema operacional que resolva o endereço. Além disso, o sistema operacional normalmente usa vários mecanismos para tentar procurar nomes, não apenas DNS. (Normalmente, pelo menos, o arquivo hosts, além de DNS.)
Håkan Lindqvist
Obrigado! É uma resposta realmente impressionante e detalhada e muito útil também!
Giancarlo Perlo