[DNS의 뿌리를 찾아서 - 1편] 도메인 네임이 IP 주소가 되기까지
네트워크를 공부한다면 OSI 7 Layer 라는 개념은 익히 들었을 것이라고 생각합니다. L1부터 L4까지는 Infrastructure 영역, L5부터는 Application 영역이라고도 합니다. 하지만 Application 영역에서 Infrastructure에 해당하는 서비스가 있는데 그게 DNS 입니다.
지금부터 두 편에 걸쳐 DNS에 대한 완벽 이해를 목표로 블로그 글을 작성해보려고 합니다. 이 글을 보시는 모든 분들이 DNS에 대한 이해에 도움이 되었으면 좋겠습니다.
DNS는 왜 필요할까?
네이버에 접속할 때 우리는 브라우저 주소창에 www.naver.com을 입력합니다. 그러면 브라우저는 네이버 웹 서버와 TCP/IP 연결을 맺어야 합니다.
컴퓨터(호스트)끼리 통신하려면 상대의 IP 주소를 반드시 알아야 합니다. 하지만 우리는 네이버의 IP 주소를 모릅니다. 그런데도 어떻게 www.naver.com만 입력해서 접속할 수 있을까요?
이 질문에 답하기 전에 거꾸로 생각해 보겠습니다. 처음부터 IP 주소를 직접 입력하면 되지 않을까요?
IP 주소만으로는 불편하다, 외우기 쉬운 도메인 네임을 사용하자.
물론 가능은 하지만, 이 방법에는 두 가지 문제가 있습니다.
첫째, 외우기 어렵습니다. 1.2.3.4 같은 숫자 조합을 자주 가는 사이트마다 외워야 한다고 생각해 보세요. 연락처 앱 없이 모든 사람의 전화번호를 외우고 다니는 것과 비슷합니다.
둘째, IP 주소는 바뀔 수 있습니다. 서버를 다른 곳으로 옮기거나 서버를 늘리면 IP 주소가 달라집니다. IP 주소로만 접속한다면 그때마다 모든 사용자가 새 주소를 알아내야 합니다.
그래서 사람은 IP 주소 대신 www.naver.com 같은 도메인 네임을 사용합니다. 도메인 네임은 IP 주소에 대응되는, 사람이 읽기 쉬운 문자열 형태의 이름입니다.
서버의 IP 주소가 바뀌면 도메인 네임은 그대로 두고, 이름에 연결된 IP 주소만 바꾸면 됩니다. 덕분에 사용자는 IP 주소가 바뀐 줄도 모른 채 계속 같은 이름으로 접속할 수 있습니다.
이름을 IP 주소로 바꿔 주는 네임 서버
하지만 컴퓨터는 여전히 IP 주소로 통신합니다. 그래서 누군가는 도메인 네임을 IP 주소로 바꿔 주어야 합니다. 이 역할을 하는 것이 네임 서버(DNS 서버)입니다. 네임 서버는 도메인 네임과 IP 주소의 대응 정보를 관리하고, 질문을 받으면 해당 IP 주소를 알려 줍니다.
1
2
브라우저: www.naver.com의 IP 주소가 뭐야?
네임 서버: 1.2.3.4야. (예시 주소)
브라우저는 이렇게 알아낸 IP 주소로 네이버 웹 서버에 연결합니다.
브라우저가 네임 서버에 IP 주소를 물어본 뒤, 받은 IP 주소로 웹 서버에 연결하는 과정
DNS가 없던 시절에는 어땠을까?
초기 인터넷(ARPANET)에서는 모든 호스트의 이름과 IP 주소를 HOSTS.TXT라는 파일 하나에 적어 두었다고 합니다. 이 파일은 SRI-NIC라는 한 기관이 관리했고, 각 컴퓨터는 주기적으로 이 파일을 내려받아 사용했습니다.
호스트가 적을 때는 이 방법으로 충분했습니다. 하지만 인터넷에 연결된 호스트가 빠르게 늘어나자 한계가 드러났습니다.
- 파일이 계속 커져서 내려받는 부담이 커졌습니다.
- 모든 변경을 한 곳에서 처리하다 보니 갱신이 늦어졌습니다.
- 모든 이름이 하나의 목록에 들어 있어서, 겹치지 않는 이름을 정하기가 점점 어려워졌습니다.
그래서 1983년, 이름 관리를 여러 서버에 나누어 맡기는 방식이 제안되었습니다. 이것이 DNS입니다.
그 흔적은 지금도 우리 컴퓨터에 남아 있습니다. macOS·Linux의 /etc/hosts, Windows의 C:\Windows\System32\drivers\etc\hosts 파일이 바로 그것입니다. 대부분의 운영체제는 DNS에 묻기 전에 이 파일부터 확인합니다.
DNS란 무엇일까?
먼저 한 줄로 말하면, DNS(Domain Name System)는 도메인 네임을 IP 주소로 바꿔 주는 시스템입니다. DNS는 HOSTS.TXT처럼 모든 이름을 파일 하나에 적어 두지 않고, 여러 서버에 나누어 관리합니다.
그렇다면 전 세계의 수많은 도메인 네임을 어떻게 나누어 관리할까요? 핵심은 이름 자체를 계층으로 나누고, 그 계층마다 담당하는 서버를 두는 것입니다.
도메인 네임의 계층 구조
도메인 네임은 온점(.)을 기준으로 여러 단계로 나뉘고, 각 단계가 하나의 계층을 이룹니다.
www.example.com을 예로 들어 보겠습니다. 사실 이 이름의 맨 끝에는 평소 생략하는 점이 하나 더 있습니다. 생략된 점까지 포함해서 쪼개 보면 다음과 같습니다.
도메인 네임은 오른쪽으로 갈수록 범위가 넓고, 왼쪽으로 갈수록 좁아집니다. 영어로 주소를 쓸 때 “동 -> 구 -> 시 -> 나라” 순서로 적는 것과 같습니다. 우리나라 주소는 반대로 “시 -> 구 -> 동” 순서로 적습니다.
가장 넓은 루트에서 출발해서 com -> example -> www 순서로 범위를 좁혀 가며 원하는 대상을 가리킵니다.
루트 도메인
모든 도메인 네임의 출발점이자 계층의 맨 꼭대기입니다. 도메인 네임 맨 끝의 점(.)이 바로 루트 도메인을 뜻합니다.
즉, 도메인 네임의 진짜 마지막은 TLD가 아니라 루트입니다. 다만 평소에는 이 점을 생략하기 때문에 TLD가 마지막처럼 보일 뿐입니다. 실제로 주소창에 www.google.com.처럼 끝에 점을 붙여 입력해도 대부분 정상적으로 접속됩니다.
최상위 도메인(TLD, Top-Level Domain)
루트 바로 아래 단계로, com, net, org, kr 등이 있습니다. com처럼 용도에 따라 나눈 TLD도 있고, kr, jp처럼 국가별로 나눈 TLD도 있습니다.
2단계, 3단계 도메인
TLD 아래로는 2단계, 3단계 도메인이 이어집니다. 위 예시에서는 example이 2단계, www가 3단계 도메인입니다.
계층적 네임 서버
이렇게 이름을 계층으로 나눠 두면, 계층마다 관리하는 곳을 따로 둘 수 있습니다. com 아래의 이름은 com을 맡은 곳이, example.com 아래의 이름은 example.com의 주인이 관리하는 방식으로 생각하시면 됩니다.
그래서 네임 서버도 도메인 네임과 같은 모양의 계층을 이룹니다. 루트를 맡는 서버, com을 맡는 서버, example.com을 맡는 서버가 각각 따로 있습니다.
또 같은 역할을 하는 서버도 한 대가 아니라 여러 대이며, 전 세계 곳곳에 흩어져 있습니다. 서버가 한 대뿐이라면 그 서버가 멈추는 순간 아무도 이름을 찾을 수 없고, 전 세계의 질문이 한곳에 몰려 감당할 수 없기 때문입니다. HOSTS.TXT 시절 한 곳에 모든 일이 몰려서 생긴 문제를, 일을 나누어 맡기는 방식으로 해결한 셈입니다.
이제 각 계층을 맡는 네임 서버를 위에서부터 살펴보겠습니다.
루트 네임 서버
계층의 맨 꼭대기인 루트 도메인을 맡는 네임 서버입니다. 루트 네임 서버는 www.example.com의 IP 주소를 직접 알지 못합니다. 대신 “com은 이 TLD 네임 서버에 물어보세요”처럼 다음에 물어볼 TLD 네임 서버의 주소를 알려 줍니다.
루트 네임 서버는 a.root-servers.net부터 m.root-servers.net까지 13개의 이름으로 운영됩니다. 하지만 실제 서버가 13대뿐인 것은 아닙니다. 같은 이름의 서버가 전 세계에 복제되어 2,000곳이 넘는 곳에서 동작합니다(2026년 10월 기준, root-servers.org). 이렇게 여러 곳의 서버가 같은 IP 주소를 함께 쓰고, 질문은 네트워크상 가장 가까운 서버로 가는 방식을 애니캐스트(anycast)라고 합니다.
TLD 네임 서버
com, kr 같은 최상위 도메인을 맡는 네임 서버입니다. TLD 네임 서버도 최종 IP 주소는 알지 못합니다. 대신 “example.com은 이 네임 서버에 물어보세요”처럼 그 아래 도메인을 맡은 네임 서버의 주소를 알려 줍니다. 예를 들어 com은 Verisign이라는 회사가, kr은 한국인터넷진흥원(KISA)이 관리합니다.
책임 네임 서버
example.com처럼 특정 도메인을 직접 맡고 있는 네임 서버입니다. 영어로는 Authoritative Name Server라고 하며, “권한 있는 네임 서버”라고도 부릅니다. 자신이 맡은 도메인에 대한 질문에는 다른 서버로 넘기지 않고 바로 답할 수 있습니다. www.example.com의 IP 주소 같은 최종 답을 가지고 있는 곳이 바로 여기입니다.
도메인을 사서 웹사이트에 연결할 때 설정하는 네임 서버(가비아, AWS Route 53, Cloudflare 등)가 보통 이 책임 네임 서버입니다.
로컬 네임 서버
로컬 네임 서버는 위 계층에 속한 서버가 아닙니다. 클라이언트를 대신해 이 계층을 찾아다니는 서버입니다. 우리 컴퓨터가 도메인 네임의 IP 주소를 알고 싶을 때 가장 먼저 묻는 곳이 바로 로컬 네임 서버입니다. 보통 인터넷 서비스 제공자(ISP)가 자동으로 정해 주지만, Google의 8.8.8.8이나 Cloudflare의 1.1.1.1 같은 공개 DNS 서버를 직접 지정해서 쓸 수도 있습니다. 예를 들어 KT 인터넷을 쓰면 KT의 DNS 서버(168.126.63.1)가 로컬 네임 서버가 됩니다.
로컬 네임 서버는 답을 모르면 루트 네임 서버부터 차례로 물어 내려가며 답을 찾아옵니다. 이미 답을 알고 있다면 이 과정 없이 바로 알려 줍니다. 답을 찾아가는 과정은 바로 다음 섹션에서, 이미 아는 답을 기억해 두는 방법은 2편의 DNS 캐시에서 자세히 살펴보겠습니다.
정리하면
처음에 DNS를 “도메인 네임을 IP 주소로 바꿔 주는 시스템”이라고 한 줄로 소개했습니다. 이제 조금 더 정확히 말하면, DNS는 계층적이고 분산된 도메인 네임 관리 체계입니다.
그리고 DNS라는 말은 이 체계에 질문하고 답을 받을 때 쓰는 통신 규칙, 즉 애플리케이션 계층의 프로토콜을 가리키기도 합니다. DNS 질의는 주로 UDP 53번 포트를 사용합니다.
왜 TCP가 아니라 UDP일까? DNS는 대부분 짧은 질문 하나와 짧은 답 하나로 끝나는 대화이기 때문입니다.
- 빠릅니다. TCP는 데이터를 보내기 전에 연결부터 맺어야 하지만(3-way handshake), UDP는 질문을 바로 보냅니다.
- 서버가 가볍습니다. UDP 서버는 답하고 바로 잊으면 돼서 가볍습니다. 전 세계의 질문을 받는 네임 서버가 TCP를 쓴다면 서버가 무거워집니다.
- 손실이 나도 괜찮습니다. 응답이 오지 않으면 다시 물어보면 되기 때문이죠.
다만 TCP를 사용하는 경우도 있습니다. 답이 너무 커서 UDP 한도를 넘거나, 네임 서버끼리 도메인 정보 전체를 복사할 때(영역 전송)는 TCP를 사용합니다.
DNS는 어떻게 IP 주소를 찾아올까?
앞에서 로컬 네임 서버는 답을 모르면 루트 네임 서버부터 차례로 물어 내려간다고 했습니다. 이번에는 주소창에 www.example.com을 입력한 순간부터 IP 주소를 받을 때까지의 과정을 처음부터 따라가 보겠습니다.
컴퓨터 안에서 먼저 찾아본다
내 컴퓨터는 곧바로 네임 서버에 묻지 않습니다. 먼저 이미 알고 있는 답이 있는지 확인합니다.
- 브라우저: 최근에 조회해서 기억해 둔 주소가 있는지 확인합니다.
- 운영체제: 운영체제가 기억해 둔 주소와 앞에서 본
hosts파일을 확인합니다.
여기서 답을 찾으면 네임 서버에 묻지 않고 바로 접속합니다. 이렇게 기억해 둔 답을 DNS 캐시라고 하는데, 2편에서 자세히 다루겠습니다.
컴퓨터 안에서 답을 찾지 못했을 때 비로소 로컬 네임 서버에 묻습니다.
로컬 네임 서버가 대신 찾아온다
로컬 네임 서버도 답을 모르는 상황이라고 가정해 보겠습니다. 이때는 아래 그림처럼 8단계를 거칩니다.
8단계 전체 흐름: 로컬 네임 서버가 안내를 따라 각 서버에 차례로 묻는다
그림의 2~7단계처럼 로컬 네임 서버가 안내를 따라 각 서버에 차례로 묻는 방식을 반복적 질의라고 합니다. 반면 1단계에서 내 컴퓨터가 로컬 네임 서버에 한 질문은 성격이 다릅니다. 이 차이는 바로 다음 섹션에서 살펴보겠습니다.
재귀적 질의와 반복적 질의
DNS 질의는 질문을 받은 서버가 어디까지 책임지느냐에 따라 두 가지로 나눌 수 있습니다.
재귀적 질의(Recursive Query)
재귀적 질의는 “끝까지 알아내서 최종 답만 알려 주세요”라고 맡기는 질의입니다. 질문을 받은 서버는 다른 서버에 묻는 일까지 모두 대신 처리하고, 최종 답을 돌려줘야 합니다.
일상으로 비유하면 대행 서비스와 비슷합니다. 서류 발급을 맡기면 대행사가 여러 기관을 돌아다니며 처리하고, 나는 완성된 서류만 받습니다.
재귀적 질의: 각 서버가 다음 서버에 대신 묻고, 답은 같은 길을 거꾸로 따라 돌아온다
반복적 질의(Iterative Query)
반복적 질의는 질문을 받은 서버가 자기가 아는 만큼만 답하고, 나머지는 질문한 쪽이 직접 찾아가는 질의입니다. 서버는 답을 알면 답을, 모르면 “다음은 저 서버에 물어보세요”라는 안내를 돌려줍니다. 질문한 쪽은 이 안내를 따라 다음 서버에 다시 묻는 일을 답을 얻을 때까지 반복합니다.
비유하면 안내 데스크입니다. “그 업무는 3층 창구로 가세요”라고 알려 줄 뿐, 3층에 가서 다시 묻는 것은 내 몫입니다.
실제로는 두 방식을 섞어서 씁니다
앞의 로컬 네임 서버가 대신 찾아온다에서 본 8단계 그림을 다시 보면, 재귀적 질의와 반복적 질의가 함께 쓰이고 있습니다.
- 내 컴퓨터 -> 로컬 네임 서버(1, 8단계): 재귀적 질의입니다. 내 컴퓨터는 한 번 묻고 최종 답만 받습니다.
- 로컬 네임 서버 -> 루트·TLD·책임 네임 서버(2~7단계): 반복적 질의입니다. 로컬 네임 서버가 안내를 따라 직접 돌아다닙니다.
로컬 네임 서버는 이렇게 재귀적 질의를 받아 끝까지 답을 찾아 주기 때문에 재귀 리졸버(Recursive Resolver)라고도 부릅니다.
그렇다면 재귀적 질의 그림처럼 루트 네임 서버가 끝까지 대신 찾아 주면 안 될까요? 실제로 루트와 TLD 네임 서버는 재귀적 질의를 처리해 주지 않습니다. 이유는 부하입니다.
재귀적 질의를 받은 서버는 다른 서버의 답이 올 때까지 그 질문을 붙잡고 기다려야 합니다. 전 세계의 질문을 받는 루트 네임 서버가 이 일까지 떠맡으면 금방 감당할 수 없게 됩니다. 반면 “com은 저기에 물어보세요”라는 안내는 자기가 가진 정보만으로 바로 답할 수 있어서 부담이 훨씬 적습니다.
그래서 끝까지 찾아다니는 무거운 일은 ISP나 Google, Cloudflare 같은 곳의 로컬 네임 서버가 나누어 맡고, 계층 위쪽의 서버는 가벼운 안내만 합니다. DNS는 처음부터 한 곳에 일이 몰리지 않도록 이름 관리를 여러 서버에 나누어 맡기는 방식으로 만들어졌습니다. 질문을 처리할 때도 마찬가지로, 무거운 일과 가벼운 일을 서로 다른 서버가 나누어 맡는 것입니다.
직접 확인해 보기
dig라는 명령어로 이 과정을 직접 볼 수 있습니다. macOS에는 기본으로 설치되어 있고, Linux에서는 dnsutils(또는 bind-utils) 패키지로 설치할 수 있습니다.
+trace 옵션을 붙이면 루트 네임 서버부터 차례로 물어 내려가는 과정을 단계별로 보여 줍니다. +nodnssec은 보안 관련 레코드(DNSSEC)를 빼서 출력을 간단하게 만드는 옵션입니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$ dig +trace +nodnssec www.example.com
. 46748 IN NS a.root-servers.net.
. 46748 IN NS b.root-servers.net.
(... m.root-servers.net까지 13개 생략 ...)
;; Received 823 bytes from <로컬 네임 서버 IP>#53 in 6 ms
com. 172800 IN NS a.gtld-servers.net.
com. 172800 IN NS b.gtld-servers.net.
(... m.gtld-servers.net까지 13개 생략 ...)
;; Received 840 bytes from 192.36.148.17#53(i.root-servers.net) in 155 ms
example.com. 172800 IN NS hera.ns.cloudflare.com.
example.com. 172800 IN NS elliott.ns.cloudflare.com.
;; Received 363 bytes from 192.5.6.30#53(a.gtld-servers.net) in 6 ms
www.example.com. 300 IN A 172.66.147.243
www.example.com. 300 IN A 104.20.23.154
;; Received 76 bytes from 172.64.35.228#53(elliott.ns.cloudflare.com) in 7 ms
출력은 빈 줄을 기준으로 네 덩어리로 나뉩니다. 각 줄은 이름 / TTL / 클래스(IN, 인터넷) / 타입 / 값 순서이고, ;; Received 줄은 어느 서버에게서 답을 받았는지 보여 줍니다.
- 첫 번째 덩어리: 로컬 네임 서버에게서 루트 네임 서버 목록을 받습니다. 앞에서 본
a.root-servers.net부터m.root-servers.net까지 13개의 이름이 보입니다. - 두 번째 덩어리: 루트 네임 서버(
i.root-servers.net)가com을 맡은 TLD 네임 서버 목록을 알려 줍니다. 최종 답이 아니라 “다음은 여기에 물어보세요”라는 안내입니다. - 세 번째 덩어리: TLD 네임 서버(
a.gtld-servers.net)가example.com을 맡은 책임 네임 서버를 알려 줍니다.example.com은 Cloudflare의 네임 서버를 쓰고 있네요. - 네 번째 덩어리: 책임 네임 서버(
elliott.ns.cloudflare.com)가 드디어www.example.com의 IP 주소를 알려 줍니다.
타입 NS는 “이 영역을 맡은 네임 서버”, A는 “이 이름의 IPv4 주소”를 뜻합니다. 레코드 종류는 2편에서 자세히 다루겠습니다.
+trace를 쓰면 첫 번째 단계 이후로는dig가 직접 로컬 네임 서버 역할을 맡아 루트부터 반복적 질의를 보냅니다. 그래서 이 출력은 로컬 네임 서버가 안에서 하는 일을 내 컴퓨터에서 재현해 본 결과라고 보시면 됩니다. 응답받는 서버와 IP 주소는 실행하는 시점과 위치에 따라 다를 수 있습니다.
마지막 줄의 300도 눈여겨볼 만합니다. 이 답을 300초 동안 기억해 둬도 된다는 뜻인데, 2편에서 볼 DNS 캐시와 이어지는 내용입니다.
정리하면
- 내 컴퓨터는 브라우저 -> 운영체제 순서로 먼저 답을 찾아보고, 없으면 로컬 네임 서버에 묻습니다.
- 내 컴퓨터 -> 로컬 네임 서버는 재귀적 질의, 로컬 네임 서버 -> 루트·TLD·책임 네임 서버는 반복적 질의입니다.
- 루트와 TLD 네임 서버는 부하 때문에 재귀적 질의를 처리하지 않고, 다음에 물어볼 서버만 안내합니다.
그런데 IP 주소 하나를 얻으려고 매번 이 8단계를 거친다면 어떨까요? 느릴 뿐 아니라, 전 세계의 질문이 루트 네임 서버로 몰릴 것입니다. 실제로는 그렇게 되지 않는데, 그 이유는 2편에서 DNS 캐시와 함께 살펴보겠습니다.
