DNS 서버 동작 원리: 도메인 이름이 IP 주소로 바뀌기까지
브라우저 주소창에 daleseo.com을 치고 엔터를 누르면 1초도 안 되어 페이지가 뜨는데요. 이 짧은 순간에 사실은 인터넷 곳곳에 있는 여러 대의 서버가 서로 묻고 답하면서 이 도메인이 어떤 IP 주소를 가리키는지 알아내는 작업이 벌어지고 있습니다.
이 일을 책임지는 시스템이 바로 DNS(Domain Name System)이고, 실제로 작업을 수행하는 주체가 DNS 서버입니다. 예전에 DNS 레코드 유형이나 dig 명령어를 다루면서 표면만 살짝 짚었었는데요. 이번에는 한 걸음 더 들어가서 도메인 이름이 IP 주소로 바뀌기까지 어떤 서버가 어떤 순서로 일하는지 차근차근 들여다보겠습니다.
DNS가 풀어주는 문제
컴퓨터끼리는 IP 주소로 통신을 하는데요. 예를 들어 어떤 웹 서버가 185.199.111.153 같은 IP 주소를 가지고 있다면, 우리가 그 사이트에 접속하려면 사실은 이 숫자에 연결을 해야 합니다.
문제는 사람이 이런 숫자를 외우기가 너무 어렵다는 점입니다. 게다가 IP 주소는 호스팅 서비스나 클라우드 환경에 따라 꽤 자주 바뀌기도 하죠. 그래서 우리는 daleseo.com이나 naver.com처럼 외우기 좋은 이름을 쓰고, 그 이름을 실제 IP 주소로 바꿔주는 일은 누군가에게 맡기기로 한 것입니다.
그 누군가가 바로 DNS 서버입니다. 사람에게 친숙한 도메인 이름과 컴퓨터에 필요한 IP 주소 사이를 통역해주는 통역사라고 보면 이해가 쉽습니다.
한 종류가 아닌 DNS 서버
흔히 “DNS 서버”라고 뭉뚱그려 부르지만, 실제로는 역할이 다른 여러 종류의 서버가 협력해서 하나의 응답을 만들어 냅니다. 크게 보면 네 종류의 서버가 있는데요.
가장 먼저 마주치는 건 재귀 리졸버(Recursive Resolver)입니다. 우리가 사용하는 컴퓨터, 스마트폰, 공유기 같은 클라이언트가 직접 말을 거는 상대가 바로 이 친구입니다. 통신사가 운영하는 DNS 서버나 구글의 8.8.8.8, 클라우드플레어의 1.1.1.1 같은 공개 DNS가 모두 재귀 리졸버에 해당하죠. 클라이언트가 “daleseo.com이 뭐야?”라고 물으면, 답을 알아낼 때까지 다른 서버들에게 대신 물어봐주는 심부름꾼 역할을 합니다.
그다음으로 루트 네임 서버(Root Name Server)가 있습니다. 인터넷 전체에서 도메인 체계의 꼭대기에 자리 잡고 있는 서버인데요. 직접 도메인의 IP 주소를 알려주지는 않고, “.com은 저쪽 서버에 물어봐”, “.net은 그쪽으로 가봐”처럼 다음 목적지를 안내해 줍니다. 전 세계에 13개의 논리적 이름(a.root-servers.net부터 m.root-servers.net까지)으로 운영되고, 실제 물리 서버는 애니캐스트(Anycast) 방식으로 수백 곳에 분산되어 있습니다.
그 아래 단계로 TLD(Top-Level Domain) 네임 서버가 있는데요. .com, .net, .org, .kr 같은 최상위 도메인을 관리하는 서버입니다. daleseo.com을 예로 들면, .com TLD 서버는 “이 도메인의 권한은 porkbun.com의 네임 서버가 가지고 있어”라고 다음 목적지를 알려줍니다. 여기서도 IP 주소 자체는 알려주지 않아요.
마지막이 권한 네임 서버(Authoritative Name Server)입니다. 특정 도메인에 대한 진짜 답을 가지고 있는 서버죠. daleseo.com의 권한 네임 서버에 가서 물어보면 그제야 “이 도메인의 IP는 185.199.111.153이야”라고 최종 답을 받게 됩니다. 도메인 등록 서비스(Porkbun, Cloudflare, GoDaddy 등)나 호스팅 업체가 이 서버를 운영합니다.
질의가 흐르는 순서
이제 네 종류의 서버가 실제로 어떻게 협력하는지 한 편의 짧은 이야기처럼 따라가보겠습니다. 우리가 브라우저에서 daleseo.com을 열었다고 가정해볼게요.
먼저 컴퓨터의 운영체제 안에 있는 작은 모듈인 스터브 리졸버(Stub Resolver)가 깨어납니다. 이 친구는 자체적으로 답을 찾을 능력은 없고, 그냥 미리 설정된 재귀 리졸버에게 질문을 그대로 넘겨주는 역할만 합니다. 보통 인터넷 공유기가 알려주는 통신사 DNS 서버 IP가 여기에 들어 있죠.
질문을 받은 재귀 리졸버는 자기 캐시를 먼저 살펴봅니다. 누군가가 최근에 같은 질문을 했다면 답이 그대로 남아 있을 테니까요. 캐시에 없다면 본격적으로 추적을 시작합니다.
클라이언트 → 재귀 리졸버 → 루트 네임 서버
→ TLD 네임 서버 (.com)
→ 권한 네임 서버 (porkbun)
→ 최종 IP 주소 응답
재귀 리졸버는 우선 루트 네임 서버에게 묻습니다. “daleseo.com을 알고 있어?” 루트 서버는 “나는 모르는데 .com을 관리하는 TLD 서버 IP를 알려줄게”라고 답합니다.
받은 IP를 가지고 이번에는 .com TLD 서버에 묻습니다. “daleseo.com을 알고 있어?” TLD 서버는 “그 도메인은 porkbun.com의 네임 서버가 책임지고 있어”라고 답하면서 그 권한 서버의 IP를 함께 줍니다.
마지막으로 권한 네임 서버에 묻습니다. “daleseo.com의 IP가 뭐야?” 그제야 권한 서버는 “185.199.111.153이야”라고 진짜 답을 돌려줍니다. 재귀 리졸버는 이 답을 자기 캐시에 저장한 뒤 처음 질문을 던졌던 클라이언트에게 그대로 전달합니다.
여기서 흥미로운 점은 클라이언트는 이 모든 과정을 전혀 몰라도 된다는 것입니다. 재귀 리졸버에게 한 번 물어보고 한 번 답을 받았을 뿐인데, 그 사이에는 사실 서너 번의 추가 질의가 일어나고 있는 셈이죠. 이름 그대로 재귀적으로 답을 찾아 와준다고 해서 재귀 리졸버라는 이름이 붙었습니다.
캐싱이 없으면 인터넷이 멈춥니다
방금 본 흐름을 모든 사용자가 모든 사이트에 접속할 때마다 처음부터 거친다면, 인터넷은 금방 마비될 것입니다. 루트 네임 서버는 초당 수백억 건의 질의를 처리해야 할 테고, 페이지가 뜨는 시간도 지금보다 훨씬 길어지겠죠.
그래서 DNS는 거의 모든 단계에서 캐싱을 활용합니다. 재귀 리졸버가 한 번 받아온 답은 일정 시간 동안 메모리에 남아 있어서, 같은 도메인에 대한 다음 질의는 외부로 나가지 않고 그 자리에서 답이 나갑니다. 운영체제와 브라우저도 자체적으로 짧은 캐시를 두기 때문에 같은 탭에서 사이트를 다시 여는 정도라면 DNS 서버까지 가지 않는 경우가 많습니다.
이 캐시가 얼마나 오래 유효한지를 정해주는 값이 TTL(Time To Live)입니다. DNS 레코드마다 함께 묶여 있는 숫자인데요. 단위는 초이고, dig 명령어로 조회해보면 다음과 같이 도메인 이름과 레코드 사이에 보이는 값입니다.
daleseo.com. 600 IN A 185.199.111.153
여기서 600이 TTL입니다. 즉 이 레코드는 600초(10분) 동안 캐시에 보관해도 된다는 뜻입니다. TTL이 짧으면 변경 사항이 빨리 전파되지만 캐시 적중률이 낮아져 트래픽이 늘어나고, 길면 그 반대가 됩니다. 그래서 평소에는 길게 두다가 도메인 이전이나 IP 변경을 앞두고 일시적으로 짧게 줄여놓는 운영 방식이 흔합니다.
캐시 덕분에 DNS는 빠르지만, 반대로 그 캐시 때문에 변경이 곧바로 반영되지 않는 단점도 생깁니다. DNS 설정을 바꿨는데 한참 동안 옛 IP로 접속되는 경험을 해보신 적이 있을 텐데요. 어딘가의 DNS 서버나 운영체제에 예전 레코드가 캐싱돼 있다가 TTL이 만료돼야만 새 값으로 갱신되기 때문입니다.
권한 서버와 재귀 리졸버는 다릅니다
처음 DNS를 공부할 때 헷갈리기 쉬운 부분이 권한 네임 서버와 재귀 리졸버의 차이입니다. 둘 다 “DNS 서버”라고 불리지만 역할은 정반대에 가깝습니다.
권한 네임 서버는 특정 도메인에 대한 답을 직접 가지고 있는 서버입니다. 예를 들어 daleseo.com의 권한 네임 서버는 이 도메인의 모든 레코드를 관리하고, 그 도메인에 대한 질의가 오면 자기가 알고 있는 답을 돌려줍니다. 다른 도메인에 대해 물어봐도 답하지 않죠. 자기가 책임지는 영역만 답하는 전문가라고 보면 됩니다.
재귀 리졸버는 반대로 자기가 직접 아는 답이 거의 없습니다. 클라이언트가 무엇을 묻든 일단 받아서, 답을 알 만한 권한 서버를 찾아 돌아다니며 답을 모아오는 역할을 합니다. 모든 도메인에 대한 질의를 받지만, 답은 직접 가지고 있지 않은 거죠. 손님의 부탁을 듣고 백방으로 알아봐 주는 안내 데스크에 가깝습니다.
이 두 역할을 한 서버가 동시에 수행할 수도 있지만, 운영상 보안과 성능 이유로 분리하는 것이 일반적입니다. 권한 서버에 재귀 질의를 허용하면 DNS 증폭 공격에 악용될 수 있기 때문입니다.
공개 DNS 서버라는 선택지
평소에는 인터넷 회선을 제공하는 통신사가 자기네 재귀 리졸버를 자동으로 할당해 줍니다. 별도 설정 없이 그냥 쓸 수 있어서 편하죠. 다만 통신사 DNS는 응답이 느리거나, 일부 사이트가 차단돼 있거나, 특정 페이지로 강제 리다이렉트되는 경우가 가끔 있습니다.
그래서 공개 DNS 서버로 갈아타는 분들도 많은데요. 자주 거론되는 몇 가지를 추려보면 다음과 같습니다.
- Google Public DNS —
8.8.8.8,8.8.4.4. 안정성과 속도 면에서 검증되어 있고 전 세계에 분산돼 있습니다. - Cloudflare DNS —
1.1.1.1,1.0.0.1. 빠른 응답과 사용자 추적 최소화를 내세웁니다. - Quad9 —
9.9.9.9. 보안에 초점을 맞춰 알려진 악성 도메인을 자동으로 차단해 줍니다. - OpenDNS —
208.67.222.222. 콘텐츠 필터링 같은 부가 기능을 함께 제공합니다.
운영체제의 네트워크 설정에서 DNS 서버 IP를 위 값들로 바꿔주면 그 시점부터 모든 도메인 질의가 해당 공개 DNS로 흘러가게 됩니다. 공유기에 한 번 설정해두면 집 안의 모든 기기에 동시에 적용되는 것도 편리한 부분이죠.
다만 어느 DNS를 쓰느냐에 따라 응답 속도가 달라질 수는 있어도 사이트 자체의 속도가 빨라지지는 않습니다. DNS는 첫 연결 단계에서만 한 번 거치는 과정이고, 그 뒤의 페이지 로딩은 어디까지나 웹 서버의 성능에 달려 있기 때문입니다.
직접 들여다보는 법
이론만 보면 추상적이니, 실제로 DNS 서버가 어떻게 답하는지 dig 명령어로 한번 들여다보겠습니다. +trace 옵션을 붙이면 재귀 리졸버가 거치는 모든 단계를 그대로 보여줍니다.
dig daleseo.com +trace
실행해보면 가장 먼저 13개의 루트 네임 서버 목록이 출력됩니다. 그다음에는 .com TLD 서버들의 정보가 나오고, 마지막으로 daleseo.com의 권한 네임 서버(porkbun.com)가 응답한 최종 A 레코드가 나타납니다. 우리가 한 번의 질의로 받은 답이 사실은 여러 단계를 거친 결과라는 것을 눈으로 확인할 수 있는 거죠.
특정 DNS 서버에 직접 묻고 싶다면 @ 기호를 사용합니다. 예를 들어 구글 공개 DNS에 질의하려면 다음과 같이 실행합니다.
dig @8.8.8.8 daleseo.com
이렇게 하면 통신사 DNS가 아니라 구글의 재귀 리졸버에게 직접 묻게 됩니다. DNS 설정을 바꾼 직후 어느 서버에는 반영이 됐고 어느 서버에는 아직인지 확인할 때 유용합니다.
권한 네임 서버를 알고 싶다면 NS 레코드를 조회하면 됩니다.
dig daleseo.com NS +short
curitiba.ns.porkbun.com.
fortaleza.ns.porkbun.com.
maceio.ns.porkbun.com.
salvador.ns.porkbun.com.
이 도메인의 진짜 답을 가지고 있는 서버가 누구인지가 한눈에 들어옵니다. 도메인 이전을 했다면 이 목록이 새 등록 업체의 네임 서버로 바뀌었는지 확인하는 데도 쓸 수 있고요.
마치며
DNS 서버는 클라이언트가 던진 한 번의 질문을 받아서 루트, TLD, 권한 서버를 차례로 거치며 답을 찾아오고, 그 결과를 캐싱해 다음 요청부터는 빠르게 응답해주는 시스템이라고 정리할 수 있겠습니다. 평소에는 의식하지 않고 쓰지만 도메인을 새로 연결하거나 사이트가 갑자기 안 열릴 때 그 안에서 무슨 일이 벌어지는지 알고 있으면 디버깅 시간을 크게 줄일 수 있습니다.
이 글에서 다룬 흐름이 머릿속에 그려졌다면, 다음 단계로는 DNS 레코드 유형을 통해 권한 네임 서버에 어떤 종류의 답을 등록해둘 수 있는지 살펴보시기 바랍니다. DNS 보안 측면에서는 응답을 위변조로부터 보호하는 DNSSEC, 질의 자체를 암호화하는 DoH(DNS over HTTPS)와 DoT(DNS over TLS)도 점점 중요해지고 있는 주제입니다.
DNS 표준의 가장 정통한 자료가 궁금하다면 RFC 1034와 RFC 1035를 참고하세요. 1987년 문서이지만 오늘날 우리가 쓰는 DNS의 거의 모든 동작이 여기서 출발합니다.
This work is licensed under
CC BY 4.0