[Network] 2-5. DNS - The Internet's Directory Service

Park Yeongseo·2024년 7월 15일
0

Network

목록 보기
10/17
post-thumbnail

Computer Networking: A Top-Down Approach, 7th Edition의 번역 및 정리입니다.

호스트는 www.facebook.com, www.gooogle.com과 같이 사람이 기억하기 쉬운 이름을 호스트명으로 가지고 있다. 하지만 이렇게 변동 길이의 알파벳-숫자의 문자열은 라우터로 처리하기 어렵기 때문에, 호스트는 IP 주소로도 식별된다.

IP 주소는 4바이트로 이루어져 있다(IPv4의 경우). 예를 들어 121.7.106.83이라는 IP 주소를 살펴보자. 마침표가 각 10진수 0~255로 구분되는 바이트를 구분하고 있다. IP 주소의 왼쪽에서 오른쪽으로 갈수록 호스트가 인터넷의 어디에 위치해 있는지, 그 위치 정보가 더 구체적으로 나타난다. 때문에 IP 주소는 계층 구조를 이루고 있다고 말한다.

1. Service Provided By DNS

호스트를 식별하기 위해서는 두 가지 방법, 호스트명과 IP 주소를 이용할 수 있다고 했다. 사람들은 기억할 수 있는 호스트명을 선호하는 한편, 라우터는 고정된 길이에 계층적인 IP 주소를 선호한다. 이러한 차이를 해소하기 위해서는 호스트명을 IP 주소로 변환하는 디렉토리 서비스가 필요한데, 이것이 인터넷의 도메인 이름 시스템(DNS, domain name system)이 하는 일이다.

DNS는 (1) DNS 서버의 계층에 구현되어 있는 분산 데이터베이스이며, (2) 호스트가 이 분산 데이터베이스에 쿼리를 날릴 수 있도록 하는 애플리케이션-계층 프로토콜이다. DNS 서버는 보통 Berkeley Internet Name Domain(BIND) 소프트웨어를 실행하는 UNIX 머신이고, DNS 프로토콜은 UDP와 53번 포트를 이용한다.

DNS는 다른 애플리케이션-계층 프로토콜들에 의해 쓰이기도 한다. 예를 들어 HTTP나 SMTP를 사용할 때, 사용자가 젝송한 호스트명을 IP 주소로 변환할 때 그렇다. 사용자 호스트에서 실행되는 브라우저가 www.someschool.edu/index.html URL을 요청한다고 해보자. 사용자 호스트가 웹 서버 www.someschool.edu로 HTTP 요청 메시지를 보내려면, 사용자 호스트는 우선 해당 웹 서버의 IP 주소를 얻어야 한다. 이는 다음과 같이 이루어진다.

  1. 사용자 기기에서 DNS 애플리케이션의 클라이언트 부분을 실행한다.
  2. 브라우저가 URL에서 호스트명을 추출하고, 호스트명을 DNS 애플리케이션의 클라이언트 사이드에 제출한다.
  3. DNS 클라이언트는 호스트명을 포함한 쿼리를 DNS 서버에 보낸다.
  4. DNS 클라이언트는 호스트명에 해당하는 IP 주소를 포함한 응답을 받는다.
  5. 브라우저는 DNS로부터 IP 주소를 받고, 해당 주소의 80번 포트에 위치한 HTTP 서버와 TCP 연결을 맺는다.

이렇게 DNS를 통해 IP 주소를 찾으면 추가적인 딜레이가 발생하게 되겠지만, IP 주소는 보통 "근처의" DNS 서버에 캐싱되기 때문에, DNS 네트워크 트래픽과 평균 DNS 딜레이는 줄어들게 된다.

DNS는 호스트명을 IP 주소로 바꾸는 서비스 외에도 몇 가지 중요한 서비스들을 제공한다.

  • Host aliasing: 호스트는 하나 이상의 별칭을 가질 수 있다. 복잡한 호스트명을 가지고 있는 호스트를 생각해보자. DNS를 이용하면 호스트의 별칭을 통해 호스트의 IP 주소 뿐만 아니라, 그 복잡한 표준(canonical) 호스트명도 알아낼 수 있다.

  • Mail server aliasing: 이메일 주소는 기억하기 쉬운 게 좋다. 하지만 메일 서버의 실제 호스트명은 사실 더 복잡할 수 있다. DNS를 이용하면 메일 애플리케이션에서도 별칭을 이용해 해당 호스트의 표준 호스트명을 알아낼 수 있다.

  • Load distribution: DNS는 복제된 웹 서버 사이의 부하를 분산하는 데에도 쓰일 수 있다. 사용량이 많은 사이트는, 서로 다른 종단 시스템에 돌아가고, 따라서 서로 다른 IP 주소를 가지고 있는 여러 서버들로 복제되곤 한다. 이 복제된 웹 서버들의 경우, 한 표준 호스트명에 IP 주소의 집합이 결부된다. DNS 데이터베이스에는 이러한 IP 주소 집합이 들어가있다. 클라이언트가 해당 주소 집합에 매핑되는 이름에 대한 쿼리를 보내면, 서버는 이 주소 집합을, 순서를 돌려가며 사용자에게 보내준다(DNS rotation). 클라이언트는 보통 이 집합의 첫 번째 IP 주소로 HTTP 요청 메시지를 보내기 때문에, DNS가 이렇게 순서를 바꿔주면 복제 서버들 사이의 트래픽을 분산시키는 결과로 이어진다. 메일 서버의 경우도 마찬가지로 DNS 로테이션이 일어난다.

    HTTP, FTP, SMTP와 마찬가지로 DNS 프로토콜도 애플리케이션-계층 프로토콜이다. DNS 프로토콜도 (1) 클라이언트-서버 패러다임을 이용해, 통신하는 두 종단 시스템 사이에서 실행되며, (2) 통신하는 종단 시스템 사이에서 DNS 메시지를 전송하기 위해 그 기저의 end-to-end 전송 프로토콜에 의존하기 때문이다.

    다만 웹, 파일 전송, 이메일 애플리케이션과 달리, DNS는 사용자끼리 직접 상호작용하기 위해 쓰이는 애플리케이션은 아니고, 사용자 애플리케이션 및 다른 인터넷 소프트웨어에 핵심적인 인터넷 기능을 제공하기 위한 것이다.

2. Overview of How DNS Works

이제는 DNS가 어떻게 동작하는지, 특히 호스트명-IP 주소 변환 서비스에 초점을 맞춰, 높은 수준에서 살펴보자.

사용자 호스트에서 실행되는 어떤 애플리케이션이 호스트명을 IP 주소로 변환하고자 한다고 해보자. 이 애플리케이션은 변환될 필요가 있는 호스트명을 명시하며 DNS의 클라이언트 사이드를 호출한다. 그러면 사용자 호스트의 DNS는 네트워크로 쿼리 메시지를 보낸다. 이때 모든 DNS 쿼리와 응답 메시지는 포트 53에서 UDP 데이터그램으로 보내진다. 수 밀리초에서 수 초 정도의 지연 이후, 사용자 호스트의 DNS는 원하던 매핑을 제공하는 DNS 응답 메시지를 받는다. 이 매핑은 호출 애프리케이션으로 전달된다.

애플리케이션의 입장에서야 DNS는 간단하고 직관적인 변환 서비스를 제공하는 것처럼 보이지만, 이 서비스는 전세계에 분산된 수많은 DNS 서버들을 포함하며, 보다 복잡하게 구현된다.

간단하게, 모든 매핑이 들어있는 하나의 DNS 서버만이 있다고 해보자. 이 중앙 집중형 설계에서 클라이언트는 간단히 모든 쿼리를 하나의 DNS 서버로 보내고, DNS 서버는 해당 클라이언트들에게 직접 응답을 할 수 있다. 하지만 이런 중앙 집중형 설계에는 다음과 같은 문제들이 있다.

  1. A single point of failure: DNS 서버에 크래시가 나면, 모든 인터넷이 멈춘다.
  2. Traffic volume: 한 DNS 서버가 수많은, 모든 DNS 쿼리를 처리해야 한다.
  3. Distant centralized database: 단일 DNS 서버가 모든 클라이언트와 가까이 있을 수는 없다. 멀리 떨어진 클라이언트도 이 DNS 서버에 쿼리를 보내야 하니, 네트워크 상황에 따라 심각한 지연이 발생할 수 있다.
  4. Maintenance: 단일 DNS 서버가 모든 인터넷 호스트에 대한 기록을 해야한다. 데이터베이스도 너무 커질 뿐더러, 새로운 호스트를 위한 업데이트도 매우 자주 일어나게 된다.

요컨대 단일 DNS의 중앙 집중형 데이터베이스에는 확장성이 없다.

A Distributed, Hierarchical Database

확장성 문제를 처리하기 위해, DNS는 계층 구조를 이루는, 전 세계에 분산된 수많은 서버들을 사용한다. 기본적으로 DNS 서버에는 루트(root), 최상위 도메인(top-level domain), 권한형(authoritative) DNS 서버의 세 클래스가 있다.

DNS 클라이언트가 호스트명 www.amazon.com의 IP 주소를 찾고 싶어 한다고 해보자. 이때 다음과 같은 일들이 일어난다.

  1. 클라이언트는 일단 루트 서버에 접속한다. 루트 서버는 최상위 도메인 com를 위한 TLD 서버를 위한 IP 주소를 반환하다.
  2. 클라이언트는 다음으로 TLD 서버에 접속한다. TLD 서버는 amazon.com를 위한 권한형 서버의 IP 주소를 반환한다.
  3. 마지막으로 클라이언트는 권한형 DNS 서버를 통해 호스트명 www.amazon.com 에 대한 IP 주소를 반환 받는다.

각 DNS 서버 클래스들에 대해 더 자세히 알아 보자.

  • Root DNS Servers: 전세계에는 400개가 넘는 루트 네임 서버들이 있다. 이 루트 네임 서버는 13개의 기구에서 관리한다. 루트 네임 서버는 TLD 서버의 IP 주소를 제공한다.

  • Top-level domain Servers: 각 최상위 도메인(com, org, net, edu, gov, uk, fr, kr 등등)에 대해 TLD 서버가 있다. TLD를 위한 네트워크 인프라는 크고 매우 크고 복잡하다. TLD 서버는 권한형 DNS 서버에 대한 IP 주소를 제공한다.
  • Authoritative DNS Servers: 인터넷에서 공개적으로 접근할 수 있는 호스트를 가지고 있는 조직은 그 호스트명과 IP 주소를 매핑하는, 공개적으로 접근할 수 있는 DNS 레코드를 제공해야 한다. 이 레코드는 그 조직의 권한형 DNS 서버에 들어 있다. 해당 조직은 자기 자신의 권한형 DNS 서버를 구성해 이 레코드를 저장할 수도 있고, 다른 서비스 제공자에게 돈을 내고 그 권한형 DNS 서버에 레코드를 저장할 수도 있다.

루트, TLD, 권한형 DNS 서버는 모두 계층적 구조를 이룬다.

Local DNS Server

DNS 서버에는 로컬 DNS 서버라 불리는 다른 타입의 DNS 서버도 있다. 로컬 DNS 서버는 이 서버 계층 구조에 포함되지는 않지만, DNS 아키텍처에서 핵심적인 역할을 한다.

각 ISP는 로컬 DNS 서버를 가지고 있고, ISP는 호스트가 ISP에 접속할 때, 자신의 로컬 DNS 서버들 중 하나 이상의 IP 주소를 준다. 호스트의 로컬 DNS 서버는 보통 호스트에게 가까이 위치하고 있다. 기업의 경우, 보통 호스트와 같은 LAN에 위치하고, 가정의 경우 몇 개의 라우터만 지나면 되는 거리에 있다. 호스트가 DNS 쿼리를 만들면, 이 쿼리는 로컬 DNS 서버로 보내지고, 로컬 DNS 서버는 프록시의 역할을 한다.

호스트에서 어떤 도메인에 대한 쿼리를 보낸다고 하자. 로컬 DNS 서버가 있으면 이 쿼리는 로컬 DNS 서버로 보내진다. 로컬 DNS 서버는 원래 요청 호스트가 직접 했어야 했던 일들을 모두 대신 한 후, 최종 쿼리 결과를 요청 호스트로 보내준다.

앞에서는 TLD DNS 서버가 호스트명을 위한 권한형 DNS 서버를 알고 있다고 가정했지만, 일반적으로는 그렇지 않다. 대신 TLD 서버는 호스트명을 아는 권한형 DNS 서버를 아는, 중간(intermediate) DNS 서버만을 알 수도 있다.

예컨대 위 그림의 dns.umass.edu가 권한형 DNS 서버가 아니라 중간 DNS 서버라 해보자. 이 서버는 cs.umass.edu로 끝나는 모든 호스트명을 관리하는 권한형 서버 dns.cs.umass.edu의 주소를 반환한다. 이 경우 위 그림의 7번 응답을 받고 나서 로컬 DNS 서버는 dns.cs.umass.edu로 호스트명에 대한 쿼리를 한 번 더 보내고 응답을 받아온 후, 그 결과를 요청 호스트에게로 보내게 된다.

Recursive query vs. Iterative query

쿼리의 종류에는 재귀형(recursive) 쿼리와 반복형(iterative) 쿼리가 있다. 위 그림에서 요청 호스트에서 로컬 DNS 서버로 가는 쿼리는 재귀형 쿼리로, 요청 호스트가 자신을 대신해 매핑을 얻어 오도록 하는 쿼리다. 이후의 2, 4, 6번 쿼리는 반복형 쿼리로, 각 DNS 서버에서 로컬 DNS 서버로 직접 응답을 얻어 온다.

아래의 그림은 모든 쿼리가 재귀형인 DNS 쿼리 체인이다. 다만 보통 실제 쿼리는 위 Figure 2.19의 패턴을 따른다.

DNS Caching

DNS 캐싱은 DNS 시스템에서 아주 중요하며, DNS는 DNS 캐싱을 이용해 지연 성능을 높이고 DNS 메시지의 수를 줄인다.

쿼리 체인에서 DNS 응답을 받은 DNS 서버는 해당 매핑을 자신의 로컬 메모리에 캐싱한다. 예를 들어 Figure 2.19의 로컬 DNS 서버는 어떤 DNS 서버로부터 응답을 받을 때마다 해당 응답에 들어있는 정보를 캐싱할 수 있다. 만약 호스트명/IP 주소 쌍이 DNS 서버에 캐싱되어 있고, 같은 호스트명에 대한 쿼리가 해당 서버에 도달하면, DNS 서버는 다른 DNS 서버로 쿼리를 보내지 않고 바로 해당 쿼리에 대한 응답을 보낼 수 있을 것이다. 다만 호스트명-IP 주소의 매핑이 영구적이지는 않기 때문에 DNS는 캐싱된 정보를 일정 기간이 지나면 버려야 한다.

3. DNS Records and Messages

DNS 분산 데이터 베이스를 함께 구현하는 DNS 서버들은 리소스 레코드(RR, resource record)들도 함께 저장하며, 이 리소스 레코드들 중에는 호스트명-IP 주소 매핑을 제공하는 것도 있다. 각 DNS 응답 메시지는 하나 이상의 RR을 가지고 있다.

RR은 다음과 같이 네 개의 필드를 가지고 있는 튜플이다.

(Name, Value, Type, TTL)

TTL은 리소스 레코드의 유효 기간으로, 해당 리소스가 캐시에서 지워져야 하는지의 여부를 결정한다. 아래에서는 Type에 따라 NameValue 필드가 어떤 의미를 하는지를 살펴보자.

  • Type=A일 때, Name은 호스트명이고 Value는 호스트의 IP 주소에 해당한다.
  • Type=NS이면 Name은 도메인이고, Value는 해당 도메인에 속하는 호스트의 IP 주소를 어떻게 얻을 수 있을지 아는 권한형 DNS 서버의 호스트명이 된다. 이 타입은 쿼리 체인을 따라 DNS 쿼리를 계속 보내야 할 때 쓰인다.
  • Type=CNAME이면 Name은 별칭 호스트명, Value는 표준 호스트명이다.
  • Type=MX이면, Name은 별칭 호스트명, Value는 메일 서버의 표준 이름이다.

메일 서버의 표준 이름(canonical name)을 얻고자 할 때에는 MX, 그 외 다른 서버의 표준 이름을 얻으려 할 때에는 CNAME을 사용한다.

DNS Messages

DNS 메시지에는 쿼리와 응답 두 종류의 메시지 밖에 없는데, 이 메시지들은 동일한 형식을 가지고 있다.

Header Section

첫 번째 12 바이트는 헤더 섹션으로, 여러 필드가 있다. 첫 번째 필드는 쿼리를 식별하기 위한 16-bit 필드다. 이 필드는 쿼리에 대한 응답 메시지에도 복사되어, 클라이언트가 보낸 쿼리와 받은 응답을 매치할 수 있도록 한다.

그 뒤에는 많은 플래그들이 있는 플래그 필드가 있다. 플래그에는 다음과 같은 것들이 있다.

  • 쿼리/응답 플래그. 쿼리인 경우 0, 응답인 경우 1
  • 권한형 서버 플래그. 질의된 이름에 대한 권한형 DNS 서버로부터의 응답인 경우 1.
  • recursion-desired 플래그. 재귀 질의인 경우 1.

헤더 섹션에는 이외의 네 필드도 있는데, 이 필드들은 헤더 뒤의 네 데이터 섹션에 해당하는 것들이 몇 개 씩 있는지를 나타낸다.

Data Section

  • Question section에는 물어볼 쿼리에 대한 정보가 있다. 이 섹션에는 물어볼 이름을 포함하는 이름 필드와, 해당 이름에 대해 물어볼 질문의 종류를 가리키는 타입 필드가 있다.
  • DNS 서버로부터의 응답의 경우, answer section에는 질의된 이름에 대한 RR이 포함되어 있다. 한 응답의 answer 섹션에는 여러 개의 RR이 들어가 있을 수도 있다.
  • Authority section에는 다른 권한형 서버의 레코드가 들어있다.
  • Additional section에는 다른 유용한 레코드들이 들어있다. 예를 들어 MX 쿼리에 대한 응답의 answer 필드에는 메일 서버의 표준 호스트명이 들어 있는데, additional section에는 추가로 해당 메일 서버의 표준 호스트명의 IP 주소를 제공하는 타입 A 레코드가 있을 수도 있다.

Inserting Records into the DNS Database

위에서는 DNS 데이터베이스에서 레코드를 탐색하는 데에 초점을 맞춰 논의를 진행했다. 그렇다면 어떻게 레코드를 데이터베이스에 넣을 수 있을까?

새로운 도메인명은 레지스트라(registrar)에 등록한다. 레지스트라는 도메인명의 고유성을 검증하고 이를 DNS 데이터베이스에 입력하고, 그러한 서비스에 대가로 돈을 받는 영리 단체다. 1999년 이전에는 레지스트라가 하나 밖에 없었지만, 지금은 많은 레지스트라들이 있고, ICANN(Internet Corporation for Assigned Names and Numbers)에서 다양한 레지스트라들에 대한 승인을 내리고 있다.

도메인명을 레지스트라에 등록할 때에는 이름과 함께 주/보조 권한형 DNS 서버의 IP 주소도 제공해야 한다. 그러면 레지스트라는 그에 해당하는 Type NS, Type A 레코드를 TLD 서버에 넣는다.

예를 들어 networkutopia.com이라는 도메인을 등록하려고 한다고 해보자. dns1.networkutopia.com, dns2.networkutopia.com이 각각 주/보조 권한형 DNS 서버의 이름이고 그 IP 주소는 차례로 212.2.212.1, 212.212.212.2라 하자.

레지스트라는 TLD에 주 권한형 DNS 서버를 등록하기 위해 다음의 두 RR을 DNS에 넣는다

(networkutopia.com, dns1.networkutopia.com, NS)
(dns1.networkutopia.com, 212.212.212.1, A)

www.networkutopia.com 웹 서버를 위한 Type A RR과, mail.networkutopia.com 메일서버를 위한 Type MX RR도 권한형 DNS 서버에 넣었다고 해보자.

이제 누군가가 웹 페이지 www.networkutopia.com에 접속하려고 한다 해보자. 호스트는 일단 DNS 쿼리를 자신의 로컬 DNS 서버로 보내고, DNS 서버는 TLD com 서버에 접속한다. TLD 서버에는 위의 Type NS, Type A RR이 있다. TLD com 서버는 사용자의 로컬 DNS 서버에 두 RR을 담아 답장을 보낸다.

이후 로컬 DNS는 212.212.212.1(권한형 서버)로 DNS 쿼리를 보내, www.networkutopia.com에 해당하는 Type A 레코드를 요청한다. 응답에는 원하던 웹 서버의 IP 주소(예를 들어 212.212.71.4)가 들어있고, 로컬 DNS 서버는 이를 사용자 호스트로 돌려준다. 사용자의 브라우저는 이제 212.212.71.4:80과 TCP 연결을 시작하고, 이 연결로 HTTP 요청을 보낸다.

최근까지 DNS 서버의 내용은 정적으로 설정되었지만, 요즈음에는 DNS 프로토콜에 UPDATE 옵션이 추가되어 DNS 메시지로 동적으로 데이터를 추가하거나 삭제할 수 있게 됐다.

0개의 댓글