HTTP GET 방법은 DNS 프로토콜과 관련하여 어떻게 작동합니까?


17

TCP / IP 스택의 응용 프로그램 계층 프로토콜을 이해하려고합니다. HTTP와 DNS 프로토콜이 모두 최상위 계층 (응용 프로그램 계층)에 있다는 것을 알고 있습니다. 따라서 브라우저가 리소스에 액세스하려면 다음과 같이 HTTP 서버에 요청을 보내야합니다.

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

이 요청은 HTTP 프로토콜 규칙에 따라 IP 주소가 아닌 페이지 URL을 사용합니다.

URL을 IP로 변환하려면 DNS 요청이 필요하다는 것을 알고 있습니다. 그래서 내 질문은 : HTTP가 DNS 프로토콜을 호출합니까? 둘 다 최상위 계층 프로토콜이므로 DNS는 HTTP에 서비스를 제공 할 수 없으므로 불가능합니다. 같은 방법으로 TCP (낮은 수준에 있음)조차 DNS와 같은 높은 수준의 프로토콜에서 서비스를 요청할 수 없습니다.

DNS 요청은 언제 발생합니까? 그리고 누가 그러한 요청을 수행합니까?


1
이 중 어느 것이 질문에 대한 답인지 명확하게하기 위해 답 중 하나를 받아 들일 수 있습니까?
030

답변:


38

브라우저가 중개자 (프록시)와 대화하지 않으면 해당 HTTP 요청은 실제로 유효하지 않습니다.

브라우저가 웹 서버와 직접 통신하는 경우 예제는 다음과 비슷합니다.

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

이제 이것을 관점에서 살펴 보려면 OSI 모델을 고려하십시오.

OSI 모델

우리는 3 가지 시스템을 운영하고 있습니다 :

  • 브라우저를 실행 하는 클라이언트
  • 사이트를 제공 하는 웹 서버
  • DNS 서버 사이트의 IP 주소를 알고

관련된 프로토콜은 아래에서 위로입니다 (최소 관련 세트는 OP로 설정).

  • IP
  • TCP, UDP
  • HTTP, DNS

HTTP 통신은 TCP 프로토콜을 통해 이루어지며 (TCP는 IP 프로토콜 위에 있음) DNS 통신은 UDP 프로토콜을 통해 이루어집니다 (UDP는 IP 프로토콜 위에 있음).

짧은 통신 순서는 다음과 같습니다.

  1. 클라이언트는 브라우저가 실행되는 요청 DNS 서버를 에 대한 A녹음 www.pippo.itUDP 프로토콜을 사용하여.

    1.1. 클라이언트에서는 해결 부분을 수행하고 브라우저와 다시 대화하는 운영 체제입니다. 브라우저는 gethostbyname () 또는 최신 getaddrinfo () 를 호출하여 OS를 통해 DNS 서버와 직접 대화하지 않습니다 . Windows의 경우, OS는 주소를 해결하는 순서 가능성이 뭔가에 의해 정의되는 리눅스에서 해결 우선 순위에 의해 정의되는 동안,/etc/nsswitch.conf

  2. DNS 서버 받는 사람, 응답을 UDP 프로토콜을 사용하여, 클라이언트 가 존재하는 경우, 녹음 / IP 주소로

  3. 클라이언트 의 포트 80에 TCP 연결을 열고 웹 서버를 다음과 같은 텍스트를 작성합니다 :

    HTTP 요청 :

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

    콘솔이나 명령 프롬프트에서 이와 같은 작업을 수행하여 동일한 작업을 수행 할 수 있습니다.

    > 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
    

    빈 줄 두 개가옵니다. 요청 된 컨텐츠가 존재하면 웹 서버가 컨텐츠를 화면에 인쇄합니다. 다른쪽에 브라우저가 있으면 응답 텍스트가 브라우저에 의해 구문 분석되고 모든 태그, 링크, 스크립트 및 이미지는 웹 페이지라고하는 것으로 렌더링됩니다.

실제로 일부 도메인을 이미 방문한 경우 브라우저가 IP 주소를 캐시 할 수 있으므로 DNS 확인이 불필요 해집니다. 또한 최신 브라우저는 탐색 속도를 높이기 위해 실제로 필요하기 전에 ( DNS 프리 페치 ) 해결을 시도 할 수 있습니다 .

또한 컴퓨터에 hosts파일에 정적 레코드가있을 수 있습니다 . 레코드가 요청과 일치하면 로컬 정적 항목이 먼저 사용되고 DNS 서버에 연결되지 않습니다. 이것은 구성 가능하며 반드시 사실 일 필요는 없지만 내가 알고있는 운영 체제의 기본값입니다.


4
@trikly : 그것이 'Host'헤더의 목적입니다. 그것없이 당신은 IP 주소 당 하나의 웹 사이트를 가질 수 있습니다. 이는 HTTP / 1.0과 HTTP / 1.1의 주요 차이점입니다. 고맙게도 HTTP / 1.0 브라우저는 드물지만,이를 수용하려면 각 사이트마다 다른 IP 주소가 필요합니다 (여전히 동일한 서버에서 호스팅 될 수 있음).
AE

1
@AE 감사합니다. 내 질문에 불분명 한 것 같아서 Hrvoje가 내가 한 말을 이해하지 못한 것입니다. (URL이 아닌 도메인을 말 했어야 함). 아직도 이해해서 다행입니다.
trlkly

1
" 이것은 올바른 HTTP 요청이 아닙니다. "라고 말하지만 대부분 사실입니다. " 향후 HTTP 버전의 모든 요청에서 absoluteURI로 전환 할 수 있으 려면 모든 HTTP / 1.1 서버가 요청 ". (RFC 2616 §5.1.2) GET http://www.pippo.it/hello.htm HTTP/1.1이례적인 경우에는 유효 할 것입니다. HTTP 프록시에 대한 유효하고 일반적인 요청이기도합니다.
wfaulk

1
gethostbyname()다소 구식입니다. 하나는 더 나은 사용합니다 getaddrinfo()...
glglgl

1
텔넷은 일반 텍스트 프로토콜 인 반면 SSH는 상대방이 SSH 프로토콜을 사용한다고 가정하고 SSL / TLS를 사용하지 않는 한 POP3, IMAP와 같은 다른 일반 프로토콜과 통신하는 데 사용될 수 있기 때문에 @Utku는 불행히도 아니요 sslwrap 또는 이와 유사한 것을 사용하여 텔넷 세션을 래핑해야합니다.
Hrvoje Špoljar

12

HTTP는 IP 프로토콜 인 TCP를 통해 전송됩니다. HTTP 요청을하려면 브라우저가 TCP 연결을 열어야하며,이를 위해서는 대상 IP 주소 (예 : 서버의 IP 주소)가 필요합니다. 하기 위해 해결 서버의 호스트 이름을, 그것은 DNS 요청을 (일반적으로 DNS는 프로그램이 이름 확인 기능을 호출 할 때 자체 운영 체제에서 보낸 요청 발행하는 것이 있습니다 만, 아무것도 방지 DNS에 자체 DNS 요청을 보내는에서 프로그램 섬기는 사람). 연결이 설정되면 요청 된 리소스의 경로가 포함 된 HTTP 요청과 서버의 호스트 이름 (예 :)이 포함 된 호스트 필드를 보낼 수 있습니다 Host: www.pippo.it. 호스트 이름은 요청 줄에 가지 않습니다 (실제로GET /hello.htm HTTP/1.1), 요청이 HTTP 프록시로 전송되는 경우를 제외하고 (이 경우 프로토콜 부분을 포함하여 전체 URL이 존재 함 GET http://www.pippo.it/hello.htm HTTP/1.1)


고마워, 지금은 명확하지만 완전히하지는 않습니다. 브라우저가 DNS 요청을 발행해야한다고 작성합니다. 알았지 만 DNS 서버에서 IP를받은 후에는 어떻게 사용합니까? 그런 IP는 HTTP 요청에 나타나지 않습니다. 따라서 HTTP 요청을 발행하기 전에 여전히 하나 이상의 단계가 있다고 가정하고 연결 시작이라고 생각합니다. 이 점은 나에게 분명하지 않습니다 ... 다시 한번 감사합니다!
지안카를로 펄로

5
실제로, HTTP 요청이 전송되는 TCP 연결을 열려면 IP가 필요합니다. 실제로 클라이언트와 서버의 IP 주소는 모든 연결 패킷과 함께 전송됩니다. 이것이 작동하는 방법을 배우는 가장 좋은 방법은 패킷 캡처 도구 (Wireshark는 훌륭한 멀티 플랫폼 및 오픈 소스 도구)를 설치하고 간단한 HTTP 요청을 캡처하고 나머지 네트워크 활동에서 필터링하여 방법을 살펴 보는 것입니다. 모든 패킷은 유선으로 전송되었습니다. 실제로 TCP 연결 전에 DNS 요청을 볼 수 있어야합니다.
Ale

1
프록시 요청은 전체 URL을 GET 행에 넣지 말고 호스트 헤더를 사용해야합니다.
OrangeDog

1
@OrangeDog : 아니요, 반대로. RFC 7230 (섹션 5.3.2)은 명시 적으로 프록시에 요청한 클라이언트가 요청 라인에서 절대 URI를 사용해야한다고 명시하고 있습니다. ( 요청 라인에서 정보를 복제하는 호스트 헤더 가 여전히 있어야합니다 ; 섹션 5.4).
hmakholm이 Monica를 지난

7

절차는 다음과 같습니다.

  1. 사용자 (귀하)는 브라우저에 다음과 같은 URL을 제공합니다. http://www.pippo.it/hello.htm
  2. 브라우저는이를 세 부분으로 나눕니다.

    • 실험 계획안 http
    • 호스트 이름 www.pippo.it
    • URL 경로 /hello.htm

    (더 복잡한 URL은 다른 부분도 가질 수 있으므로 지금은 그 가능성을 무시할 것입니다)

  3. 브라우저는 IP 연결을 만들려면 IP 주소가 필요하다는 것을 알고 있습니다. IP 주소를 얻으려면 주소를 캐시하지 않은 경우 DNS를 사용해야합니다.

    1. 브라우저는 운영 체제에 DNS 서버의 IP 주소를 묻습니다. 그것이 얻는다고 가정하십시오 8.8.8.8.
    2. 브라우저는 다음과 같은 다중 계층 연결을 구성합니다.

      • IP 계층 : 연결 8.8.8.8
      • UDP 계층 : 대상 포트 53에 대한 패킷 설정
      • DNS 계층 : A호스트 이름 에 대한 레코드에 대한 DNS 요청 작성www.pippo.it

      물론 관련된 패킷의 정확한 형식과 같은 세부 사항을 생략하고 있습니다.

    3. 브라우저가 IP 주소를 제공합니다 (IP 등의 상위 계층에 UDP의 상부에 적층) DNS 응답을 수신 www.pippo.it,하자는 말할10.11.12.13
  4. 브라우저는 TCP 연결을 만들려면 포트 번호가 필요하다는 것을 알고 있습니다. 포트 번호를 얻으려면 http내부 테이블에서 프로토콜 을 찾고 포트 80을 사용해야한다는 것을 알게됩니다.
  5. 브라우저는 다음과 같은 다중 계층 연결을 구성합니다.

    • IP 계층 : 연결 10.11.12.13
    • TCP 계층 : 대상 포트 80으로 패킷 설정
    • HTTP 계층 : /hello.htm호스트 에서 URL 에 대한 HTTP 요청을 작성 www.pippo.it하십시오 (컴퓨터 10.11.12.13가 여러 도메인을 호스트하고 있기 때문에 원하는 도메인을 알아야 함).

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

    물론 TCP 핸드 셰이크 및 기타의 모든 세부 사항을 생략하고 있습니다.

  6. 브라우저는 다음 내용을 포함하는 HTTP 응답 (IP 위에 레이어 된 TCP 위에 레이어 된 것)을받습니다. hello.htm

그리고 좋은 측정을 위해 브라우저가 해당 응답의 내용을 검사하고 필요한 추가 리소스 (이미지, CSS, Javascript 등)를 식별한다고 언급합니다. 그런 다음 각 리소스에 대해이 전체 프로세스를 반복합니다.


4
3 단계는 실제로 응용 프로그램 자체가하는 것이 아닙니다. 응용 프로그램 은 OS 와 같은 것을 사용 getaddrinfo하거나 gethostbynameOS에 주소를 확인하도록 요청합니다. 또한 OS는 일반적으로 여러 메커니즘을 사용하여 DNS뿐만 아니라 이름을 조회합니다. (DNS 외에 일반적으로 적어도 hosts 파일들)
Håkan Lindqvist

감사! 정말 인상적이고 상세한 답변이며 매우 유용합니다!
지안카를로 펄로
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.