DNS 리졸버가 DNS 서버에 보낸 Request Message에는 총 3가지 정보가 포함되어 있다.
서버나 메일 배송 목적지(메일 주소에서 @ 뒷부분의 이름) 같은 이름을 의미한다.
쉽게 생각하면 도메인명을 의미한다고 보면 된다.
DNS 구조를 고안할 때 인터넷 이외 네트워크에서도 이를 사용할 수 있도록 만들었다.
이 때문에 어떤 네트워크에서 DNS 구조를 사용하는지 식별하기 위하여 클래스라는 정보를 추가했다.
하지만 현재는 인터넷 이외의 네트워크는 소멸되었으므로 클래스는 항상 인터넷을 의미하는 "IN"으로 고정되어 있다.
이름에 어떤 타입의 정보가 지원되는지를 나타낸다.
A일 경우 이름에 IP 주소가 지원되는 것을 의미하며 MX일 경우 메일 배송 목적지가 지원됨을 의미한다.
추가로 IP 주소에서 이름을 조사할 때 사용하는 PTR, 이름에 닉네임(alias)을 붙이기 위한 CNAME, DNS 서버의 IP 주소를 등록하는 NS, 도메인 자체 속성 정보를 등록하는 SOA 등이 있다.
이렇게 다양한 타입이 존재하는 것을 통하여 DNS 서버는 도메인 명에 대응되는 IP 주소를 반환해 주는 역할뿐만이 아닌 다양한 역할을 수행할 수 있다는 것을 알 수 있다.
이 타입에 따라 Response로 클라이언트(브라우저)에게 보내지는 응답 내용 또한 달라진다.
먼저 알아 둬야 할 것은 DNS 등록 정보는 위와 같은 표 형태로 저장되어 있지 않고 설정 파일에 등록되어 있다.
또한 이렇게 한 번에 "www.sample.com" 이름에 해당하는 Row Data를 검색하는 방식도 아니다.
하지만 DNS 서버 동작 과정을 간단히 보기 위해서 위 표와 같이 표현했음을 알고 가자.
참고로 위 표에서 1개 Row Data에 해당하는 데이터를 저장한 설정 파일을 "리소스 레코드"라고 한다.
DNS 서버는 Request Message에 담겨 있는 이름, 클래스, 타입 3가지가 일치하는 정보를 검색한다.
그리고 3가지 항목이 모두 일치할 경우 해당 설정 파일에 저장되어 있는 데이터(위 표에선 192.168.0.1)이라는 값을 뽑아낸다.
이후 Respond Message에 이 정보를 담아 보냄으로써 브라우저는 도메인 명과 대응되는 IP 주소를 얻을 수 있게 된다.
도메인 명에 대응하는 IP 주소를 조회하는 A 타입은 위 과정으로 끝이 나지만 메일 배송 목적지를 조회하는 MX는 데이터 추출 방식이 조금 더 복잡하다.
먼저 MX 타입은 이메일 주소의 @ 뒤에 있는 목적지 도메인명을 이름으로 전달한다.
예를 들어 "test@sample.com"으로 문자를 보내고 싶을 경우 "sample.com"이 이름으로 할당되어 DNS 서버에 요청을 보내는 것이다.
이 경우 DNS 서버는 이름, 타입, 클래스가 일치하는 정보를 찾을 것이며 위 표에서는 "10 mail.sample.com"이 검색될 것이다.
A 타입과는 다르게 데이터가 2개 항목으로 되어 있는 것을 볼 수 있으며 IP 주소 값도 존재하지 않는다.
앞에 있는 숫자는 "메일 서버의 우선 순위"를 뜻하며 뒤에 있는 숫자는 "메일 서버의 이름"에 해당한다.
메일 배송 목적지로 DNS 서버에 복수의 메일 서버가 등록되어 있을 수 있는데 이때 우선순위 값이 작은 메일 서버를 우선 선택하게 된다.
만약 우선순위에 의거하여 메일 서버 이름이 선택되었다면 메일 서버 이름을 Request Message 이름값으로 지정하고 A 타입으로 지정하여 DNS 서버에서 다시 검색을 수행한다.
이렇게 검색을 수행하면 메일 서버의 IP 주소가 검색될 것이다.(위 표에서는 192.168.0.137)
이를 통해 MX 타입일 경우 DNS 서버는 "메일 서버의 우선 순위", "메일 서버 이름", "메일 서버 IP 주소" 총 3개의 데이터를 클라이언트(브라우저) 측에 보내게 된다.
이때 조금 알아두면 좋은 것이 "www"이다.
흔히 사이트에 무조건 "www"가 붙어야 한다고 생각하는 경우가 있다. 하지만 이 www는 처음 웹 구조를 만들 때 "www"라는 이름으로 웹 서버를 등록한 것이 많아 관례가 된 것일 뿐 필수 값은 아니다.
즉, 단순히 A 타입으로 DNS 서버에 등록만 시켜 놓으면 www가 아닌 wsw로도 웹 서버 이름으로써 사용 가능하다.
DNS 서버가 어떻게 동작하는지 알기 위해선 도메인 계층부터 알 필요가 있다.
인터넷에는 막대한 수의 서버가 존재하며 이 모든 서버를 1개의 DNS 서버에 등록하는 것은 사실상 불가하다.
따라서 DNS 서버 여러 대에 정보를 분산시킨 뒤 다수의 DNS 서버가 연대하여 정보를 찾아내는 구조를 통해 동작하게 된다.
DNS에서 취급하는 도메인명은 점 구분자(.)를 통해 계층을 구분할 수 있다.
각 계층을 모두 "도메인"이라고 하며 오른쪽에 위치할수록 상위 계층 도메인이다.
여기서 잘 알아야 하는 것이 "도메인명"과 "도메인"의 차이이다. 이 둘이 헷갈리면 아래 내용도 헷갈린다.
"www.sample.com"이라는 URL이 있다고 가정하자. 이때 점을 포함한 "www.sample.com"을 도메인명이라고 한다.
그리고 점으로 구분된 계층인 "www", "sample", "com"이 바로 도메인이 되는 것이다.
또한 오른쪽에 위치할 수록 상위 계층이므로 가장 상위 도메인은 "com"이 될 것이다.
이렇게 계층화된 도메인 정보를 DNS 서버에 등록하는데 이때 1개의 도메인은 DNS 서버 1개에만 등록된다.
즉, 1개 도메인이 여러 개의 DNS 서버에 존재할 수는 없다는 것이다.
이럴 경우 1개의 도메인을 분할 할 수 없어 곤란하다고 생각할 수도 있다.
예를 들어 "sample.com" 도메인명을 사용하는 어느 사이트는 1번 "sample.com"에는 블로그를, 2번 "sample.com"에는 카페 기능을 사용하고 싶을 수도 있는데 "sample" 도메인은 분할할 수 없으므로 기능 분리가 안된다고 생각할 수 있다.
하지만 이는 도메인 아래에 하위 도메인을 생성함으로써 쉽게 해결 가능한 문제이다.
예를 들어 블로그를 사용하고 싶을 경우 "blog.sample.com"으로 sample에 하위 도메인으로써 blog를 추가해주면추가해 주면 되고 카페의 경우 "cafe.sample.com"으로 sample 하위 도메인으로써 cafe를 추가해 주면 된다.
즉, DNS 서버는 도메인명과 동일하게 계층 구조로 되어 있으므로 하위 도메인을 추가함으로써 계속해서 도메인 분할 혹은 생성이 가능하다는 것이다.
추가로 인터넷의 도메인은 회사나 국가 및 단체 등 모든 곳에서 할당할 수 있다.
예를 들어 "kr"은 대한민국이라는 국가에 할당된 도메인이며 "co"는 기업에 할당된 도메인이다.
(즉, co.kr은 한국에 존재하는 기업의 페이지라는 것이다)
"www.sample.co.kr"에 접속할 경우 "sample"이 회사에 할당된 도메인이며 최하위의 "www" 도메인이 서버의 이름을 담당하게 되는 것이다.
도메인에는 "루트 도메인"이라 불리는 최상위 도메인이 존재한다.
이 루트 도메인은 도메인명에는 주로 생략되어 있기 때문에 생소한 개념일 수 있다.
인터넷에는 DNS 서버가 여러 개 있기 때문에 모든 DNS 서버를 방문하여 도메인과 대조하며 확인할 수 없다.
그래서 아래와 같은 방법을 고안했다.
먼저 하위 도메인을 담당하는 DNS 서버의 IP 주소를 상위 DNS 서버에 등록한다.
그리고 상위 DNS 서버의 IP 주소를 상위 서버의 상위 DNS 서버에 등록하는 것이다.
이 경우 최상위 도메인이 저장된 DNS 서버에 방문하면 하위 DNS 서버에 이동할 수 있을 것이며 이 과정을 반복하다보면 최종적으로 도메인명과 대응되는 IP 주소를 알 수 있게 될 것이다.
예를 들어 "www.sample.com"이라는 URL이 있다고 가정하자.
이 경우 최상위 도메인인 "com"은 "sample" 도메인이 저장된 DNS 서버의 IP 주소를 저장하고 있으며 "sample" 도메인을 저장한 DNS 서버는 "www" 도메인을 저장하는 DNS 서버의 IP 주소를 가지고 있다.
그리고 "www" 도메인을 저장한 DNS 서버는 "www.sample.com"과 대응되는 IP 주소를 가지고 있기 때문에 이 값을 불러와 도메인명과 대응되는 IP를 찾을 수 있는 것이다.
여기에서 "루트 도메인"이라는 개념이 나온다.
"www.sample.com"이라는 도메인 명이 주어졌을 때 우리 눈으론 com 같은 최상위 도메인부터 DNS Server 탐색이 시작될 것이라고 생각한다.
그런데 생각해보면 이는 조금 비효율적인 방법이다.
지금 생각나는 최상위 도메인으로 사용되는 도메인만 해도 "net", "kr", "com", "so" 등 여러 가지가 있다.
모든 DNS 서버를 조회하는 것은 불가능하다 했으니 브라우저나 OS에 최상위 도메인으로 사용하고 있는 모든 IP 주소가 저장되어 있어야 할 것이다.
하지만 이럴 경우 최상위 도메인이 추가될 때 관리가 복잡해지며 공간의 낭비 또한 발생할 수 있다.
이런 문제를 해결하기 위해 나온 개념이 "루트 도메인"인 것이다.
사실 "www.sample.com"이라는 도메인명은 "www.sample.com."에서 마지막 점을 생략한 것이다.
즉, 마지막 점 이후 아무것도 없는 값이 루트 도메인 역할을 하는 것이다.
하지만 마지막 점을 붙일 경우 가독성도 떨어지고 가독성을 위해 루트 도메인에 이름을 붙여줄 경우 모든 사이트의 길이가 루트 도메인 길이만큼 길어질 것이다.
따라서 그냥 마지막 점을 생략하고 무조건 루트 도메인부터 시작한다고 판단하는 것이다.
루트 도메인 서버에 최상위 도메인을 저장하는 서버들에 대한 IP 주소가 저장되어 있으므로 모든 DNS 서버를 조회하거나 수많은 최상위 도메인 IP 주소를 OS에 저장하지 않고서도 바로 최상위 도메인 DNS 서버에 접근할 수 있게 되는 것이다.
이때 중요한 점이 루트 도메인 DNS 서버의 IP 주소를 인터넷에 존재하는 모든 DNS 서버에 전부 등록해야 한다는 것이다.
클라이언트 PC는 처음에 PC와 가장 가까운 DNS 서버에 접속하게 되는데 모든 DNS 서버에 루트 도메인 DNS 서버 IP 주소가 저장되어 있어야지만 어떤 DNS 서버에서든 루트 도메인 DNS 서버로 바로 이동할 수 있을 것이다.
루트 도메인의 DNS 서버에 할당된 IP 주소는 전 세계에 13개밖에 없으며 좀처럼 변경되지 않으므로 그렇게 어려운 작업은 아니다.
또한 루트 도메인 DNS 서버에 관한 정보는 DNS 서버 SW를 설치할 경우 자동으로 등록이 완료되기 때문에 신경을 쓸 필요가 크게 없다.
먼저 클라이언트는 가장 가까운 DNS 서버에 "www.sample.com"의 IP 주소를 찾아달라는 요청 메시지를 보낸다.
이 과정은 Socket 라이브러리에 있는 DNS Resolver가 수행하며 이전에 설명했으므로 자세한 설명은 생략하겠다.
일단 이 도메인은 루트 도메인의 DNS 서버에 접근하여 "www.sample.com"의 IP 주소를 물어본다.(1번 과정)
루트 도메인은 이 정보를 가지고 있지 않으므로 가지고 있는 정보 중 "com" 도메인을 저장하고 있는 DNS 서버의 IP 주소를 반환한다.
즉, "나는 답을 모르지만 com 도메인이 사용되고 있으니 그 도메인의 DNS 서버가 알 수도 있어"라고 말하며 다른 곳으로 가서 물어보도록 하는 것이다.
답을 받은 DNS 서버는 com 도메인의 DNS 서버로 이동하여 "www.sample.com"의 IP 주소를 물어본다.(2번 과정)
com 도메인의 DNS 서버 또한 이 정보를 가지고 있지 않기 때문에 자신의 하위 도메인인 "sample" 도메인의 DNS 서버 IP 주소를 반환한다.
즉, "com이 들어 있긴 하지만 'www.sample.com' 정보는 저장하고 있지 않아. 하지만 'sample.com'으로 구성되어 있으니 내 하위 도메인 서버 중 sample DNS Server가 이를 알 수도 있어"라고 말하며 sample 도메인의 DNS 서버에 책임을 떠넘긴다.
그리고 sample 도메인의 DNS 서버로 이동하여 "www.sample.com"에 대해 물어보겠지만 sample 도메인 DNS Server의 하위 도메인인 www 도메인의 DNS Server IP 주소를 알려주고 이곳에 물어보라고 응답을 보낼 것이다(3번 과정)
이후 다시 답변을 받은 DNS 서버는 이번엔 www 도메인의 DNS 서버로 이동하여 "www.sample.com"의 IP 주소를 물어본다.(4번 과정)
이 곳엔 "www.sample.com"이라는 도메인명과 일치하는 리소스 레코드가 존재할 것이다.
왜냐하면 가장 하위 도메인까지 이동했기 때문에 만약 이곳에 데이터가 없을 경우 존재하지 않는 사이트인 것이다.
www 도메인의 DNS Server는 "www.sample.com"에 대응되는 IP 주소를 추출하여 응답으로 보내줄 것이다.
이렇게 도메인명과 대응되는 IP 주소를 받은 DNS Server는 Respond Message에 IP 주소를 담아 클라이언트에게 보내줄 것이며 클라이언트는 도메인명과 대응되는 IP 주소를 파악할 수 있게 되는 것이다.
물론 현실에서는 무조건 위와 같이 동작하지는 않는다.
현실에서는 1개의 DNS 서버에 복수 도메인 정보가 등록되어 있는 경우도 있기 때문에 도메인 1개당 1개의 DNS 서버가 존재한다고 단정 지을 수 없다.
이 경우 상위의 DNS 서버에서 조회한 후 한 단계를 건너뛰고 그 아래의 DNS 서버에 접근하게 된다.
a.b.c라는 도메인명에 대한 정보를 얻어와보자.
이때 b와 c 도메인이 1개의 공통된 DNS 서버에 저장되어 있다 가정하자.
이 경우 루트 도메인 서버에서 c가 저장된 DNS 서버로 접근할 텐데 b 또한 동일한 DNS 서버에 저장되어 있기 때문에 아예 b.c에 대한 정보를 클라이언트 측에 반환하는 것이다.
이 경우 클라이언트는 "c"에 대한 정보만 받아오길 기대했으나 "b.c"가 왔기 때문에 바로 "a" 도메인이 저장된 DNS 서버로 이동하면 되는 것이다.
하지만 큰 틀은 위에서 설명한 개념을 벗어나지 않는다.
캐시란 한 번 사용한 데이터를 데이터의 이용 장소와 가까운 고속 기억장치에 저장하여 이후 다시 사용할 때 조금 더 빠르게 데이터에 접근하는 기술을 말한다.
CPU와 메모리 사이에 존재하는 캐시 메모리나 디스크 장치에 데이터를 저장하는 방식으로 사용하는데 네트워크에서도 이 캐시 기술을 사용하여 고속화하는 방법이 일반화되어 있다.
DNS 서버는 한 번 조사한 도메인명에 관한 기록을 캐시에 저장해 둔다.
이후 만약 캐시에 저장된 정보가 존재할 경우 캐시에 저장된 정보를 회답하여 그 위치에서부터 계층 구조를 탐색하면 되기 때문에 더욱 빠르게 정보를 찾을 수 있다.
또한 조회한 도메인이 존재하지 않는다는 것도 캐시에 보존 가능하기 때문에 이름이 존재하지 않는 경우에도 빠른 회답이 가능해진다.
주의할 점은 캐시에 정보를 저장한 후 등록 정보가 변경될 수도 있다는 점이다.
등록 정보가 변경될 경우 실제 데이터와 캐시에 저장된 데이터가 다르기 때문에 정상적으로 동작하지 않을 수 있다.
따라서 DNS 서버에 저장되는 캐시 정보엔 유효 기한이 존재하며 유효 기간이 지날 경우 캐시에서 삭제된다.
또한 조회에 응답할 때 이 것이 캐시 정보인지 IP 주소를 저장하고 있는 DNS 서버에서 받아왔는지를 알린다.