글을 쓸 일이 생겼습니다. 개발자를 위한 글쓰기 플랫폼 rog.idwwt.com에 접속해야겠죠. 주소창에 입력하고 엔터를 칩니다.
이때 컴퓨터 입장에서는 할 일이 있습니다. rog.idwwt.com 이라는 이름만으로는 어디로 가야 할지 모릅니다. 컴퓨터끼리 통신할 때는 결국 IP 주소가 필요합니다. 그러면 rog.idwwt.com 이 어느 IP인지를 먼저 알아내야 합니다.
이 "이름 → IP"를 처리하는 전 세계적인 체계가 DNS(Domain Name System)입니다. 그리고 그 체계 안에서 실제로 "제가 알고 있습니다"라고 답해주는 서버가 네임서버입니다.
네임서버는 역할에 따라 세 종류로 나뉩니다.
- 루트 서버 — 가장 상위입니다. .com은 저 TLD 서버가 관리해처럼 TLD 서버의 위치만 알려줍니다.
- TLD 서버 — .com, .kr 같은 최상위 도메인 단위로 있습니다. 그 도메인은 저 권한 서버가 관리해라고 다음 단계를 안내합니다.
- 권한 서버 — 특정 도메인의 진짜 답을 들고 있는 서버입니다. idwwt.com의 경우 Cloudflare가 여기에 해당합니다. A 레코드, CNAME 같은 실제 레코드가 여기 등록되어 있습니다.
루트와 TLD는 "저쪽으로 가보세요"만 하고, 권한 서버에서 조회가 끝납니다.
IP를 찾는 순서
rog.idwwt.com에 접속하려 합니다. 그러면 컴퓨터는 우선 내 안에서 먼저 해결하는 것을 시도합니다.
첫 번째, /etc/hosts를 봅니다. 내가 직접 도메인과 IP를 써넣을 수 있는 파일입니다. 127.0.0.1은 "내 컴퓨터 자신"을 가리키는 IP이고, 로컬에서 서버를 띄우고 localhost:3000으로 접속할 수 있는 게 이 줄 덕분입니다.
# localhost is used to configure the loopback interface
# when the system is booting. Do not change this entry.
##
127.0.0.1 localhost
255.255.255.255 broadcasthost
::1 localhost
예를 들어 여기에 1.1.1.1 idwwt.com을 추가하면, idwwt.com에 접속할 때 DNS 조회 없이 무조건 1.1.1.1로 가게 됩니다.
여기 없으면 두 번째, 로컬 캐시를 봅니다. 한 번 찾아온 답은 버리지 않습니다. 일정 시간 동안 기억해뒀다가 같은 도메인이 오면 바로 꺼내씁니다. 단, 영원히 남아 있지는 않습니다. 각 레코드에는 TTL(Time to Live)이라는 유효기간이 붙어 있고, 그 시간이 지나면 캐시에서 사라집니다.
➜ dscacheutil -q host -a name rog.idwwt.com
name: rog.idwwt.com
ip_address: 116.45.183.36
116.45.183.36 이 지금 rog.idwwt.com 에 연결된 실제 서버 IP입니다. 캐시에 이미 들어 있다는 건, 이전에 한 번 이 도메인에 접속한 적이 있어서 리졸버가 찾아온 답이 저장되어 있다는 뜻입니다.
여기도 없으면 세 번째, 바깥으로 나갑니다. /etc/resolv.conf에 지정된 외부 DNS 서버로 요청을 보내는 겁니다.
조회 순서를 정리하면 이렇습니다.
- 1. /etc/hosts — 캐시보다 우선, DNS 자체를 건너뜁니다.
- 2. 로컬 캐시
- 3. /etc/resolv.conf에 지정된 외부 DNS
/etc/resolv.conf 에는 현재 KT DNS 서버 주소가 적혀 있습니다. 리졸버 주소를 지정하는 파일입니다. 여기 적힌 서버로 DNS 질의가 나갑니다. 비어 있으면 어디에 물어야 할지 모르니까 조회가 안 됩니다.
이 값은 어떤 네트워크에 연결하느냐에 따라 달라집니다. 공유기에 연결하면, 공유기가 DHCP로 IP를 배정해주면서 DNS 서버 주소도 함께 알려줍니다. 그 값이 /etc/resolv.conf에 자동으로 적히는 겁니다. KT 회선의 공유기라면 KT DNS를, SK 회선이라면 SK DNS를 알려주는 식입니다.
그렇지만 macOS 네트워크 설정에서 DNS를 수동으로 지정하면 DHCP가 알려주는 값을 무시합니다. 공유기가 KT DNS를 쓰라고 알려줘도, 이미 지정해놨으니 무시하는 것입니다.
만약 수동 지정을 하는데 8.8.8.7처 럼 오타를 내면 DNS 조회가 안 됩니다. 8.8.8.7은 존재하지 않기 때문에 응답이 없고, 그러면 idwwt.com의 IP를 아무도 알려주지 못하니까 접속이 안 됩니다. 이 경우에는 IP 주소를 직접 치면 됩니다. 브라우저에 116.45.183.36을 직접 입력하면 DNS 조회 없이 바로 연결됩니다. DNS는 이름을 IP로 바꿔주는 역할만 하기 때문에, IP를 이미 알고 있으면 DNS가 없어도 상관없습니다.
DHCP(Dynamic Host Configuration Protocol)
DHCP 는 네트워크에 연결한 기기에 자동으로 설정값을 배정해주는 프로토콜입니다. DHCP가 배정해주는 것은 IP 주소, 서브넷 마스크, 게이트웨이, DNS 서버입니다. /etc/resolv.conf에 자동으로 값이 적히는 이유는, Wi-Fi 연결 시 DHCP가 알려준 값이 자동으로 들어간 것입니다.
리졸버
/etc/resolv.conf 에 지정된 외부 DNS 서버, 즉 바깥으로 나갔을 때 도달하는 곳이 리졸버(Recursive Resolver)입니다.
8.8.8.8(Google), 1.1.1.1(Cloudflare), 아까 본 203.248.252.2(KT) 같은 것들이 전부 리졸버입니다. 운영 주체가 다를 뿐 역할은 동일합니다. 내 컴퓨터 대신 루트 서버부터 권한 서버까지 순서대로 찾아다니며 최종 답을 가져오는 서버입니다.
내가 "이 도메인 IP가 뭐야?" 라고 한 번만 물어보면, 리졸버가 나 대신 전 과정을 돌아다니며 최종 답을 통째로 가져옵니다. 이걸 재귀 조회(recursive query)라고 합니다.
조회 경로는 이렇습니다.
루트 서버 → TLD 서버(.com 담당) → 권한 서버(idwwt.com 담당) → 진짜 IP
여기서 루트 서버, TLD 서버, 권한 서버 — 이 세 가지가 전부 네임서버(Name Server)입니다. 역할이 달라서 이름이 다를 뿐, 본질은 같습니다. "내가 아는 범위에서 답해주거나, 모르면 다음 담당자를 알려주는 서버"입니다.
네임서버라는 단어가 두 가지 맥락에서 쓰입니다.
- 하나는 DNS 계층 구조를 설명할 때입니다. 루트 서버, TLD 서버, 권한 서버 — 이 셋을 통칭해서 네임서버라고 부릅니다.
- 다른 하나는 "어떤 DNS 서비스를 쓰냐"를 말할 때입니다. "네임서버를 Cloudflare로 바꿨다"는 말은, 그 중 권한 서버 역할을 Cloudflare 에 맡겼다는 뜻입니다. 루트 서버나 TLD 서버는 공공 인프라라 우리가 선택할 수 있는 영역이 아닙니다.
- 같은 단어인데 앞에서는 계층 전체를 가리키고, 뒤에서는 권한 서버 하나만 가리킵니다. 문맥으로 구분해야 합니다.
루트 서버
DNS 계층의 맨 꼭대기입니다.
루트 서버가 아는 건 딱 하나입니다. .com은 어느 TLD 서버가 담당하는지, .kr은 어느 TLD 서버가 담당하는지. 그 이상은 모릅니다. idwwt.com의 IP가 뭔지는 전혀 관심이 없습니다. 그냥 ".com 관련이면 저 TLD 서버한테 물어봐" 라고만 합니다.
TLD 서버
루트 서버 다음 단계입니다. TLD(Top-Level Domain)는 도메인 맨 뒤 조각, .com, .net, .kr, .io 같은 것들입니다. TLD 서버는 그 TLD에 속한 도메인들이 어느 권한 서버를 쓰는지 알고 있습니다.
.com TLD 서버를 예로 들면, 세상의 모든 .com 도메인이 어느 권한 서버에 등록돼 있는지 목록을 갖고 있습니다. 리졸버가 "idwwt.com 어디야?"라고 물으면, TLD 서버는 "idwwt.com은 Cloudflare가 관리해"라고 NS 레코드로 알려주고 끝냅니다. 최종 IP는 여기서도 나오지 않습니다.
권한 서버(Authoritative Server)
여기서 진짜 답이 나옵니다. 특정 도메인의 실제 레코드(A, CNAME, MX 등)를 직접 들고 있는 서버입니다. idwwt.com이라면 Cloudflare가 권한 서버 역할을 합니다.
리졸버가 "idwwt.com의 IP가 뭐야?"라고 물으면, 권한 서버는 "116.45.183.36이야"라고 A 레코드를 돌려줍니다. 추측이나 위임이 아니라 실제 등록된 값 그대로입니다. 도메인을 구입한 뒤 Cloudflare 같은 서비스에서 레코드를 설정하는 게 바로 이 권한 서버에 데이터를 쓰는 행위입니다.
각 단계가 직접 최종 답을 주는 게 아니라 "다음엔 저쪽으로 가보세요"라고 길만 알려줍니다. 이걸 위임(delegation)이라고 합니다.
그리고 이 "어느 네임서버에게 가라"는 이정표가 바로 NS 레코드입니다. A나 CNAME처럼 도메인을 목적지로 연결하는 게 아니라, 이 도메인의 관리를 누가 맡고 있는지를 가리키는 레코드입니다.
idwwt.com의 NS 레코드가 Cloudflare를 가리키고 있기 때문에, 리졸버가 TLD 서버에 물어봤을 때 "Cloudflare한테 가봐"라는 답을 받을 수 있는 겁니다.
NS 레코드는 루트 서버, TLD 서버, 권한 서버 모두 갖고 있습니다. 역할은 조금 다릅니다.
| 서버 | NS 레코드 예시 | 의미 |
| 루트 서버 | .com NS a.gtld-servers.net | "`.com`은 저 TLD 서버가 담당해" (위임) |
| TLD 서버 | idwwt.com NS toby.ns.cloudflare.com | "`idwwt.com`은 저 권한 서버가 담당해" (위임) |
| 권한 서버 | idwwt.com NS toby.ns.cloudflare.com | "이 존의 담당 서버가 나야" (자기 선언) |
루트 서버와 TLD 서버의 NS 레코드는 "다음엔 저쪽으로"라는 위임 이정표이고, 권한 서버의 NS 레코드는 "이 도메인의 담당이 나야"라는 선언입니다. 같은 레코드 타입이지만 누가 들고 있느냐에 따라 역할이 달라집니다.
참고로 리졸버가 루트, TLD, 권한 서버를 순서대로 거치는 건 맞지만, 체인처럼 넘어가는 게 아닙니다. 리졸버가 매번 직접 질의합니다.
리졸버 → 루트 서버 "`.com` TLD 서버 주소 알려줘"
리졸버 ← 루트 서버 "여기야: a.gtld-servers.net"
리졸버 → TLD 서버 "`idwwt.com` 권한 서버 주소 알려줘"
리졸버 ← TLD 서버 "여기야: toby.ns.cloudflare.com"
리졸버 → 권한 서버 "`idwwt.com` IP 알려줘"
리졸버 ← 권한 서버 "116.45.183.36"
리졸버 → 내 컴퓨터 최종 답 전달
루트 서버가 TLD 서버로 직접 넘기는 게 아닙니다. 루트 서버는 리졸버한테 TLD 서버 주소를 알려주고 끝냅니다. 리졸버가 그 주소를 들고 TLD 서버로 새로 질의하는 겁니다. 매번 리졸버가 출발점입니다.
레코드 타입 — A와 CNAME
Cloudflare 같은 네임서버 안에는 DNS 관리 영역이 있습니다. 거기에 레코드를 등록하는 겁니다. idwwt.com 은 카페24에서 샀지만 네임서버는 Cloudflare로 옮겼습니다. CNAME이나 A 레코드를 거기서 관리하고 있습니다.
레코드 타입 중 일단 두 개만 알면 됩니다. A랑 CNAME.
A 레코드는 도메인을 IP 주소로 직접 연결합니다. 무조건 숫자, IP 주소로만 등록할 수 있습니다.
CNAME은 도메인을 다른 도메인으로 연결합니다. 문자열로 등록하는 겁니다. 문자열끼리 매핑을 하는 타입이 CNAME입니다.
권한 서버는 어디를 쓰느냐에 따라 지원하는 기능이 달라집니다. 도메인을 산 곳(카페24, 가비아 등)에서 기본으로 제공하는 DNS를 그대로 쓸 수도 있고, Route 53이나 Cloudflare 같은 전문 DNS로 옮길 수도 있습니다.
레지스트라 내장 DNS
레지스트라 내장 DNS(카페24, 가비아 등)는 도메인을 샀을 때 기본으로 딸려오는 겁니다. A, CNAME, MX 정도 기본 레코드는 되는데, 그 이상을 기대하기 어렵습니다. 와일드카드 안 되고, 레코드 타입도 제한적이고, TTL 최솟값도 높아서 설정 바꿔도 반영이 느립니다. 관리 UI도 단순합니다. 간단한 개인 사이트 수준이면 충분하지만, 뭔가 특이한 설정이 필요하면 막히는 경우가 생깁니다.
전문 DNS (Route 53, Cloudflare 등)
전문 DNS(Route 53, Cloudflare 등)는 DNS가 본업이라 지원 범위가 넓습니다. 와일드카드, SRV, CAA 같은 레코드도 되고, Apex 도메인에 CNAME 못 쓰는 제약을 우회하는 기능도 있습니다. TTL을 거의 0에 가깝게 낮출 수 있어서 변경 사항이 빠르게 반영됩니다.
CNAME이 필요한 이유
서브도메인을 여러 개 만들었습니다. 홈서버 IP가 바뀌면 연결된 모든 서브도메인을 일일이 수정해야 합니다. 수백 개가 되면 수백 개를 전부. 그래서 서브도메인은 CNAME으로, 루트 도메인은 A 레코드로 등록합니다. IP가 바뀌어도 idwwt.com A 레코드 하나만 수정하면 나머지가 다 따라옵니다. 변수화를 하는 겁니다.
한 가지 주의할 점이 있습니다. idwwt.com 같은 루트 도메인(apex domain) 자체에는 CNAME을 쓸 수 없습니다. DNS 표준 제약입니다. CNAME은 반드시 서브도메인에만 씁니다.
rog.idwwt.com 에 접속하면 → idwwt.com으로 가봐 → idwwt.com은 116.45.183.36이네 → 연결. 중간에 하나 거쳐서 치환으로 되게끔 하는 겁니다. IP가 바뀌어도 `idwwt.com` A 레코드 하나만 수정하면 나머지가 다 따라옵니다.
실제 레코드로 읽어보면
지금까지 배운 걸 실제 설정을 통해 봐봅시다.
idwwt.com — 카페24 + Cloudflare
카페24 도메인 관리 화면을 보면 아래와 같습니다.

- 도메인 구입처: 카페24
- 현재 네임서버: toby.ns.cloudflare.com, vida.ns.cloudflare.com
도메인은 카페24에서 샀지만, 권한 서버는 Cloudflare로 바꿔놓은 상태입니다. .com TLD 서버에는 지금 이렇게 등록되어 있습니다.
idwwt.com NS toby.ns.cloudflare.com
idwwt.com NS vida.ns.cloudflare.com
누군가 `idwwt.com`에 접속하면, 리졸버가 `.com` TLD 서버에 물어봤을 때 "Cloudflare한테 가봐"라는 답을 받고, Cloudflare 권한 서버에서 최종 IP를 받아오게 됩니다.