본 글은 Computer Networking: a Top Down Approach의 DNS 챕터를 정리한 글입니다.
인간에게는 주민 번호와 이름 등의 속성이 있다.
이때, 주민 번호로 누군가를 구별하는 것보다 이름으로 구별하는 것이 더 간단하고 이해하기 쉬울 것이다.
인터넷 호스트를 쉽게 식별할 수 있게 해주는 것은 호스트 네임 이다. (www.google.com
등)
하지만 이 호스트 네임은 호스트가 인터넷 상에서 어떤 위치에 존재하는 지를 제공하지는 않는다. 그래서 호스트는 IP 주소로 식별되기도 한다.
IP 주소는 4바이트의 계층적 구조로 표현된다.
각 바이트는 0~255까지의 10진수로 표기하며, 마침표로 구분한다.
우편 주소처럼 왼쪽에서 오른쪽으로 주소를 읽어나갈 수록 네트워크 상에서 어디에 존재하는지 파악할 수 있다. (121.7.106.83
)
인간이 호스트 네임을 선호하는 반면에 라우터는 IP 주소를 필요로 한다.
결국 호스트 네임을 변환해주는 디렉토리 서비스가 필요하고, 이것이 도메인 이름 시스템(DNS)이다.
DNS
클라이언트 측 DNS 앱이 실행된다. (보통 브라우저에 내장되어 있다고 한다.)
브라우저가 URL에서 호스트 네임을 추출해 DNS 앱에 전달한다.
DNS 클라이언트가 호스트 네임을 포함한 쿼리를 DNS 서버에 송신한다.
DNS 클라이언트가 호스트 네임의 IP 주소가 포함된 Response를 수신한다.
브라우저가 DNS에게 IP 주소를 전달받고, 해당 주소의 80 포트에 존재하는 HTTP 서버 프로세스와 TCP 연결을 생성한다.
(위와 같은 과정에 지연 시간을 최소화하기 위해 DNS 서버에 IP 주소가 캐싱된다)
Host aliasing(호스트 별칭)
복잡한 호스트 네임을 가진다면, 두개이상의 앨리어스 네임을 가질 수 있다.
예시로, relay1.west-coast.enterprise.com
이라는 호스트 네임이라면, enterprise.com
과 www.enterprise.com
이 앨리어스 네임이 가능할 수 있다.
이때 relay1.west-coast.enterprise.com
는 캐노니컬(canonical, 정식) 호스트 네임이라고 불리게 된다.
일반적으로 기억하기 쉬운(mneomonic, 니모닉) 호스트 네임을 더 많이 사용하며,
앨리어스 네임을 통해 캐노니컬 호스트 네임과 IP 주소를 얻을 수 있다.
Mail server aliasing(메일 서버 별칭)
이메일은 니모닉한 주소를 사용하는 게 바람직하지만, 메일 서버의 호스트 네임은 훨씬 복잡하다.
만약 @yahoo.com
메일이라면, 캐노니컬 호스트 네임은 relay1.west-coast.yahoo.com
일 수 있다.
이것 또한 메일 앱에서 DNS를 호출하여 앨리어스 네임으로부터 캐노니컬 호스트 네임과 IP 주소를 얻어낸다. MX 레코드를 통해 이것이 가능해진다.
Load distribution(부하 분산)
DNS는 cnn.com
과 같은 사용량이 많은 사이트를 위해 여러 대의 서버가 존재한다.
각 서버는 각각 다른 IP 주소를 갖고 있고, 하나의 앨리어스 네임에 연결된다.
DNS 데이터베이스에 이 일련의 IP 주소 집합이 저장되어 있고, 이것의 순서를 바꿔가며 응답한다. 왜냐하면 보통 HTTP Request 메시지는 집합의 첫번째 IP에 보내지기 때문이다.
이런 DNS의 로테이션은 다수의 서버에 트래픽을 분산하고, 메일 서버에도 동일하게 사용된다.
위에서 설명된 것처럼, URL이 입력되면
클라이언트 사이드 DNS가 쿼리를 전송하고 응답을 받아 앱에 전달한다.
실제로 이 과정은 분산된 수많은 DNS 서버와 앱 계층 프로토콜로 구성되어 있어 상당히 복잡하다.
이런 DNS 서버는 가장 단순하게 구현한다면 중앙 집중식 DNS 서버로 구성할 수 있을 것이다.
중앙 집중식 설계는 단순하다는 것 때문에 매우 매력적이지만, 호스트 수가 방대한 오늘 날의 인터넷에는 부적합하다. 아래와 같은 문제가 있다.
단일 장애 지점. 중앙 서버가 다운되면 인터넷 전체가 다운된다.
트래픽 양. 수억 개의 호스트의 HTTP Request와 이메일에 대한 DNS 쿼리를 혼자서 처리하는 것은 불가능하다.
멀리 존재하는 중앙 집중식 DB. 단일 DNS 서버가 모든 클라이언트에게 가까울 수는 없다. 이로 인해 상당한 지연이 발생한다.
유지 보수. 단일 DNS 서버가 모든 인터넷 호스트에 대한 기록을 보관해야 하고, 자주 업데이트도 해야하는데 하나의 DB임에도 너무 방대해진다.
이것을 단순히 말하면 확장(scale)이 불가능하다는 것이다.
따라서 DNS는 분산하는 것으로 설계한다.
확장 문제를 해결하기 위해 DNS는 계층으로 구성된다. 호스트에 대한 맵핑은 DNS 서버에 분산되어 있다.
보통 계층 구조의 DNS 서버는 루트(Root) 서버, 최상위 도메인(TLD, Top-level domain) 서버, 권한(Authoritative) 서버로 나뉘어진다.
우선 클라이언트가 루트 서버 중 하나에 접근한다. 이것을 통해 TLD 서버의 IP 주소를 얻어낸다. (예시에서는 com
TLD 서버)
이후 amazon.com
권한 서버에 접근하여 www.amazon.com
호스트 네임의 IP 주소를 얻어낸다.
루트, TLD, 권한 서버에 대해 자세히 알아보자.
루트(root) 서버
최상위 도메인(TLD) 서버
com
org
net
edu
uk
fr
과 같은 국가 도메인을 포함한 최상위 도메인을 위한 서버들이다. com
은 Verisign Global Registry Services
가 관리하고 있으며, edu
는 Educause
가 관리한다.권한(Authoritative) 서버
루트, TLD, 권한 서버는 모두 DNS 서버 계층 구조에 속하는데, 로컬 DNS 서버도 굉장히 중요한 역할을 한다.
엄밀히 말하면 서버 계층 구조에 속하지 않지만, DNS 아키텍처의 중심이다.
가정용 혹은 교육기관 ISP(인터넷 서비스 제공자)는 로컬 DNS 서버(기본 네임 서버라고도 함)를 가지고 있다.
호스트가 ISP에 연결하면, 로컬 DNS 서버의 IP를 제공받는다. (DHCP를 통해)
일반적으로 호스트와 근접한 곳에 있으며, 가정용 ISP라면 일반적으로 몇 개의 라우터로 호스트와 분리되어 있다.
호스트가 DNS 쿼리를 전송하면, 로컬 DNS 서버가 프록시(캐시) 역할을 하며 쿼리를 서버 계층 구조로 전달한다.
뉴욕대 호스트인 cse.nyu.edu
와 로컬 DNS dns.nyu.edu
가 존재
gaia.cs.umass.edu
를 저장한 권한 서버를 dns.umass.edu
라고 가정
cse.nyu.edu
가 gaia.cs.umass.edu
를 요청한다면 어떤 과정이 일어날까?
뉴욕대 로컬 DNS인 dns.nyu.edu
에 쿼리 메시지가 전송됨
로컬 DNS에서 edu
에 해당하는 TLD 서버 주소를 루트에 요청
여러 개의 TLD 서버 주소가 응답되고,
이 중 하나에 umass.edu
권한 서버 주소를 요청함. dns.umass.edu
가 응답으로 돌아옴.
이제 로컬 DNS 서버가 dns.umass.edu
에 쿼리를 직접 전송하고,
gais.cs.umass.edu
의 IP 주소가 응답으로 돌아옴
위 과정에 총 4개의 쿼리와 4개의 응답 메시지가 전송되었음.
(이것은 DNS 캐싱으로 줄일 수 있음)
TLD 서버가 권한 서버 대신 권한 서버를 알고 있는 중간 DNS 서버를 알고 있을 수도 있음
위 예시를 그대로 이어서 이번에는 중간 DNS 서버가 dns.umass.edu
라고 해보자.
그러면 요청이 들어왔을 때, dns.umass.edu
는 cs.umass.edu
로 끝나는 호스트 네임의 모든 권한 서버의 IP 주소들을 가진 dns.cs.umass.edu
의 IP 주소를 응답함.
dns.cs.umass.edu
가 gaia.cs.umass.edu
의 주소를 응답해줄 것이다.
이 과정에서는 5개의 요청과 5개의 응답으로 총 10개가 쓰여짐.
이렇듯 재귀적인 쿼리와 반복적인 쿼리가 계속해서 발생하며,
이론적으로 모든 쿼리는 재귀 혹은 반복 쿼리이다.
DNS는 지연을 줄이고 DNS 메시지 수를 줄이기 위해 캐싱을 광범위하게 활용한다.
캐싱은 굉장히 간단한데, 쿼리 송수신 중에 획득한 (호스트네임-IP주소) 맵핑을 캐싱하는 것이다. (메모리에 캐싱)
호스트네임-IP주소 맵핑은 영구적이지는 않기 때문에, 보통 2일마다 캐시된 정보를 삭제한다.
캐싱이 되면 DNS 서버가 재귀/반복 쿼리를 전송하지 않고, 즉각적으로 응답한다.
로컬 DNS는 TLD 서버의 IP 주소도 캐싱할 수 있다. 그 덕에 루트 서버를 거치지 않아도 된다.
분산 데이터베이스로 구현된 DNS 서버는 호스트네임-IP주소 맵핑을 포함하는 리소스 레코드(RR)을 저장한다.
각 DNS Response 메시지에는 한개 이상의 RR이 포함된다.
리소스 레코드는 아래와 같은 필드를 포함하는 튜플이다.
(Name, Value, Type, TTL)
**TTL**: RR의 **유효 기간**. 캐시에서 제거돼야 하는 시기를 결정한다.
Type 별로 Name, Value의 의미가 달라진다.
(www.naver.com, 145.37.93.126, A, ...)
foo.com
), Value는 권한 서버의 호스트 네임이다.(foo.com, dns.foo.com, NS, ...)
(foo.com, relay1.bar.foo.com, CNAME, ...)
(foo.com, mail.bar.foo.com, MX, ...)
보통 A 타입 레코드는 권한 서버에게 저장되고, 캐싱된 서버에도 저장이 된다.
캐싱이 되지 않았다면 NS 레코드를 저장하고 있을 것이고,
이것의 Value로 하여금 A 타입 레코드도 가지게 된다.
DNS 메시지에는 쿼리와 Response 메시지 오직 두 종류만 존재한다.
두 메시지 모두 동일한 형식을 갖는다.
헤더 섹션
여러 필드가 있는 첫 12바이트이다.
첫 16비트는 쿼리를 식별하는 숫자로, Response 메시지에 복사되어 클라이언트가 해당 숫자로 쿼리와 일치시킨다.
플래그 필드에는 쿼리/Response 플래그가 있고 (0은 쿼리, 1은 Response)
권한 플래그는 응답 서버가 DNS 권한 서버라면 설정된다.
재귀 희망 플래그는 클라이언트(호스트 or DNS 서버)에 레코드가 없고, 재귀를 수행하기를 원할 때 설정된다. 재귀가 가능하면 Response에 재귀 사용 가능 플래그가 설정된다.
4개의 숫자 필드도 존재하는데, 해당 유형들의 데이터 발생 횟수를 나타낸다. (아래 필드에 존재하는 데이터들)
질문(question) 섹션
쿼리에 대한 정보가 포함되어 있다.
이름을 포함하는 name 필드, 쿼리의 유형(타입 A, MX 등)이 포함된다.
응답(answer) 섹션
쿼리한 호스트 네임에 대한 RR이 포함된다.
호스트 네임에 여러 개의 IP 주소가 존재할 수 있으므로, 여러 개의 RR이 담겨있을 수 있다.
권한 섹션
추가 섹션
유용한 레코드가 포함되어 있다.
예시로 타입 MX 쿼리에 대한 Response의 응답 섹션에는 메일 서버의 캐노니컬 네임을 제공하는 RR이 포함되고, 추가 섹션에는 해당 캐노니컬 네임의 IP 주소를 제공하는 A 레코드가 포함된다.
networkutopia
라는 도메인 네임을 등록하려 함
dns1.networkutopia.com
(212.2.212.1
)
dns2.networkutopia.com
(212.212.212.2
)
위 DNS 서버들을 등록할 때,
com
TLD 서버에 타입 NS 및 A 레코드를 삽입해야 한다.
(networkutopia.com, dns1.networkutopia.com, NS, ...)
(dns1.networkutopia.com, 212.212.212.1, A, ...)
www.networkutopia.com
에 대한 타입 A 레코드와mail.networkutopia.com
에 대한 타입 MX 레코드가사용자가 www.networkutopia.com
를 주소창에 입력
로컬 DNS 서버에 DNS 쿼리가 전송됨
로컬 DNS 서버는 com
TLD 서버에 연결함 (캐싱한 적 없다면 루트 서버를 거쳐야 됨)
com
TLD 서버에 저장된 NS 레코드 및 A 레코드를 포함한 Response를 로컬 DNS에게 보냄
로컬 DNS 서버가 212.212.212.1
에게 www.networkutopia.com
의 A 레코드(IP 주소)를 요청함
A 레코드에는 IP 주소(예: 212.212.71.4
)가 담겨져 있으며,
로컬 DNS가 호스트에게 전달함으로써 클라이언트의 브라우저와 212.212.71.4
의 TCP 연결이 구성됨. 그리고 HTTP 요청을 보낼 수 있게 된다.