본문으로 건너뛰기

안동민 개발노트

본문 시작

DNS의 구조와 동작

계층형 도메인 이름과 루트·TLD·권한·재귀 DNS 서버의 역할을 익히고 질의와 캐시가 이어지는 해석 과정을 추적합니다.

브라우저 주소창에 www.google.com을 입력하면 구글의 웹 페이지가 나타납니다.

하지만 TCP/IP로 패킷을 보내려면 먼저 목적지 IP 주소가 필요합니다.

사람이 쓰는 도메인 이름을 IP 주소나 다른 DNS 데이터로 해석해 주는 분산 시스템이 DNS(Domain Name System)입니다.

DNS는 전화번호부에 비유되곤 하지만, 실제로는 전 세계에 분산된 거대한 계층적 데이터베이스입니다.

DNS는 사람이 읽는 이름을 네트워크가 쓰는 데이터로 바꾼다

사용자는 도메인 이름을 입력하고, 네트워크는 IP 주소와 메일 서버 같은 레코드를 필요로 한다. DNS는 그 사이에서 위임과 캐시를 이용해 답을 찾는다.

  1. 분산

    한 서버가 전 세계 이름을 모두 들고 있지 않다.

  2. 계층 위임

    root, TLD, zone 순서로 책임이 나뉜다.

  3. TTL 캐시

    같은 답은 정해진 시간 동안 재사용한다.


도메인 이름 체계

도메인 이름은 오른쪽에서 왼쪽으로 계층 구조를 가집니다.

도메인 이름은 오른쪽에서 왼쪽으로 위임을 따라간다

마지막 점은 루트이고, 그 왼쪽으로 TLD, 등록 도메인, 호스트 또는 서브도메인 label이 이어진다.

  1. 1. Root

    Root 루트 서버는 `.com`을 담당하는 TLD 서버를 알려준다.

  2. 2. TLD

    TLD `.com` 서버는 `example.com`의 권한 서버를 알려준다.

  3. 3. Zone

    Zone `example.com` 권한 서버가 `www` 레코드의 실제 답을 낸다.

  • 루트(Root): 도메인의 최상위입니다. 보통 표기하지 않지만, 정확히는 www.example.com.처럼 마지막에 점이 하나 더 있습니다. 이 마지막 점이 루트를 의미합니다.

  • TLD(Top-Level Domain): com, org, net, kr 등 최상위 도메인입니다. .com은 일반 TLD(gTLD), .kr은 국가 코드 TLD(ccTLD)입니다.

  • SLD(Second-Level Domain): example처럼 일반적으로 조직이나 서비스를 식별하는 부분입니다. .com 같은 gTLD에서는 보통 이 레벨을 등록하지만, co.kr처럼 국가 코드 도메인 정책에 따라 더 아래 레벨을 등록하는 경우도 있습니다.

  • 서브도메인(Subdomain): www, api, mail 등 도메인 소유자가 자유롭게 설정하는 부분입니다.

TLD 유형예시설명
gTLD (일반).com, .org, .net전 세계적으로 쓰이는 일반 TLD
ccTLD (국가).kr, .jp, .uk, .io국가/지역 코드
신규 gTLD.dev, .app, .blog2012년 이후 대거 추가된 TLD
sTLD (후원).edu, .gov특정 커뮤니티/기관 중심
인프라.arpa역방향 DNS 등 인프라용

이 계층 구조는 DNS 서버의 구조와 직접 대응됩니다.


DNS 서버 종류

DNS 질의를 처리하는 서버는 네 가지 유형으로 나뉩니다.

DNS 서버는 “답을 주는 서버”와 “다음 위치를 알려주는 서버”로 나뉜다

재귀 리졸버는 클라이언트 대신 찾아가고, root와 TLD는 다음 권한 서버를 알려주며, 권한 서버가 zone의 실제 답을 낸다.

  1. Stub resolver

    브라우저나 OS가 재귀 리졸버에게 질문을 보낸다.

  2. Recursive resolver

    캐시를 확인하고, 없으면 권한 서버들을 차례로 따라간다.

  3. Root / TLD

    최종 IP가 아니라 다음에 물어볼 NS 정보를 알려준다.

  4. Authoritative

    자신이 관리하는 zone의 레코드에 대해 권한 있는 답을 낸다.

  5. Authoritative answer

    해당 zone의 실제 레코드 또는 부정 응답을 반환한다.

  6. Referral

    최종 답은 없지만 다음 NS와 glue 정보를 알려준다.

  7. 질문

    클라이언트는 보통 재귀 리졸버 하나에게만 묻는다.

  8. 위임 추적

    리졸버가 root → TLD → authoritative 순서로 반복 질의한다.

  9. 최종 응답

    리졸버가 받은 답을 캐시에 저장하고 클라이언트에게 돌려준다.

DNS 리졸버(Recursive Resolver): 클라이언트의 stub resolver가 보낸 질의를 받아, 답을 찾을 때까지 다른 DNS 서버들에게 반복 질의를 수행하는 서버입니다.

ISP가 운영하거나, 8.8.8.8(Google), 1.1.1.1(Cloudflare) 같은 공개 리졸버를 사용할 수 있습니다.

"대리 조회자" 역할입니다.

루트 DNS 서버(Root Name Server): 도메인 계층의 최상위를 담당합니다.

.com이면 어디로, .kr이면 어디로 가야 하는지를 알려줍니다.

루트 서버는 A부터 M까지 13개의 이름을 가지며, 각 이름은 애니캐스트를 통해 여러 물리적 인스턴스로 전 세계에 분산됩니다.

루트 서버운영 기관비고
AVerisign루트 서버 식별자 중 하나
BUSC-ISI연구 기관 운영
FISCDNS 소프트웨어 생태계와도 관련
JVerisignVerisign 운영
KRIPE NCC유럽 인터넷 레지스트리
LICANNIANA 기능과 관련
MWIDE Project일본 연구 네트워크 기반

TLD DNS 서버: .com, .org, .kr 같은 최상위 도메인을 담당합니다.

example.com에 대한 질의를 받으면, example.com을 관리하는 권한 DNS 서버의 주소를 알려줍니다.

권한 DNS 서버(Authoritative Name Server): 특정 DNS zone의 내용을 알고 있는 서버입니다.

example.com의 IP 주소가 무엇인지, 메일 서버는 어디인지 등의 권한 있는 답변을 제공합니다.

도메인 소유자나 DNS 호스팅 사업자가 레코드를 관리합니다.


재귀 질의 vs 반복 질의

브라우저가 www.example.com의 IP 주소를 알아내는 전체 과정을 따라가 보겠습니다.

클라이언트는 한 번 묻고, 리졸버가 여러 서버를 반복해서 찾아간다

재귀 질의는 “끝까지 찾아와 달라”는 요청이고, 반복 질의는 “다음에 물어볼 곳을 알려 달라”는 요청이다.

  1. www.example.com의 IP는?

    클라이언트는 복잡한 위임 구조를 직접 돌지 않는다.

  2. 192.0.2.44

    리졸버가 최종 답을 돌려준다.

  3. 반복 질의: 리졸버가 권한 서버를 순회

    Root `.com` TLD 서버를 알려준다. 3 .com TLD `example.com` 권한 서버를 알려준다. 4 Authoritative `www.example.com`의 A/AAAA 레코드를 응답한다.

  4. Root

    `.com` TLD 서버를 알려준다.

  5. .com TLD

    `example.com` 권한 서버를 알려준다.

  6. Authoritative

    `www.example.com`의 A/AAAA 레코드를 응답한다.

1단계: 브라우저나 운영체제의 stub resolver가 재귀 리졸버에게 재귀 질의(Recursive Query)를 보냅니다.

"내 대신 끝까지 찾아 달라"는 요청이므로, 리졸버는 최종 답변, 부정 응답(NXDOMAIN 등), 또는 오류를 클라이언트에게 돌려줍니다.

2단계: 리졸버의 캐시에 답이 없으면, 루트 DNS 서버에 반복 질의(Iterative Query)를 보냅니다.

루트 서버는 "나는 모르지만, .com TLD 서버의 주소는 이것이다"라고 응답합니다.

3단계: 리졸버가 .com TLD 서버에 같은 질문을 합니다.

TLD 서버는 "example.com의 권한 DNS 서버 주소는 이것이다"라고 응답합니다.

4단계: 리졸버가 example.com의 권한 DNS 서버에 질의합니다.

권한 서버가 "www.example.com의 IP 주소는 192.0.2.44입니다"처럼 예시 주소를 포함한 최종 답변을 제공합니다.

5단계: 리졸버가 이 답을 레코드의 TTL(Time To Live) 범위 안에서 캐시에 저장하고, 클라이언트에게 전달합니다.

이후 같은 질의는 TTL이 남아 있는 동안 캐시에서 빠르게 응답할 수 있습니다.

재귀 리졸버는 캐시를 먼저 보고, 없으면 위임 사슬을 따라간다

클라이언트에게는 한 번의 질문처럼 보이지만, 리졸버 내부에서는 캐시 확인과 여러 번의 반복 질의가 일어난다.

  1. 1

    Stub → Resolver 클라이언트가 재귀 질의를 보낸다.

  2. 2

    Cache lookup TTL이 남은 답이 있으면 바로 응답한다.

  3. 3

    Root / TLD 다음 권한 서버 위치를 referral로 받는다.

  4. 4

    Authoritative zone의 실제 레코드 답을 얻는다.

  5. 5

    Cache + Return TTL과 함께 저장하고 클라이언트에 반환한다.

  6. Cache hit

    권한 서버까지 가지 않아도 같은 답을 빠르게 돌려준다.

  7. Cache miss

    root부터 위임 정보를 따라 실제 권한 서버까지 찾아간다.


DNS 캐시 계층

실제로는 매번 루트 서버부터 질의하지 않습니다.

브라우저나 애플리케이션, 운영체제 stub resolver, hosts 파일, 재귀 리졸버 등 여러 지점에서 캐시나 로컬 규칙이 개입할 수 있습니다.

정확한 순서는 운영체제와 애플리케이션 설정에 따라 달라집니다.

DNS 답은 여러 계층에서 캐시될 수 있다

브라우저, 운영체제, hosts 파일, 재귀 리졸버가 순서대로 개입한다. 어느 계층에서 답을 찾았는지에 따라 지연과 디버깅 위치가 달라진다.

  1. Application / Browser

    짧은 시간 같은 호스트 이름 조회를 재사용한다. 가장 가까움

  2. OS stub / hosts

    OS 캐시와 hosts 파일이 로컬 우선순위를 가질 수 있다. 로컬 정책

  3. Recursive resolver

    ISP나 공개 DNS가 TTL 동안 권한 서버 답을 캐시한다. 공유 캐시

  4. Authoritative server

    zone의 실제 레코드와 TTL 기준을 제공한다. 원본

dns_cache_check.sh
# Windows: OS DNS 캐시 확인
ipconfig /displaydns | findstr "Record Name"

# Windows: OS DNS 캐시 초기화
ipconfig /flushdns

# Linux: systemd-resolved 캐시 통계
resolvectl statistics

# macOS: DNS 캐시 초기화
sudo dscacheutil -flushcache
sudo killall -HUP mDNSResponder

# hosts 파일 확인 (로컬 DNS 오버라이드)
# Windows: type C:\Windows\System32\drivers\etc\hosts
# Linux/Mac: cat /etc/hosts
dns_resolver.py
import socket

def resolve_domain(domain):
    """도메인 이름을 IP 주소로 해석"""
    try:
        # getaddrinfo: IPv4 + IPv6 모두 조회
        results = socket.getaddrinfo(domain, None)

        seen = set()
        for family, _, _, _, sockaddr in results:
            ip = sockaddr[0]
            if ip not in seen:
                seen.add(ip)
                version = "IPv4" if family == socket.AF_INET else "IPv6"
                print(f"  {version}: {ip}")

        # gethostbyname: IPv4만 (간단한 조회)
        ipv4 = socket.gethostbyname(domain)
        print(f"\n  기본 IPv4: {ipv4}")

    except socket.gaierror as e:
        print(f"  해석 실패: {e}")

# 여러 도메인 조회
domains = ["google.com", "naver.com", "github.com"]
for domain in domains:
    print(f"\n{domain}:")
    resolve_domain(domain)

이 과정에서 재귀 리졸버가 대리 조회자로서 여러 권한 서버를 따라가며 답을 찾아오기 때문에, 클라이언트는 복잡한 위임 구조를 직접 순회하지 않고 하나의 질문만 던질 수 있습니다.


DNS 면접 포인트

질문핵심 답변
DNS란?도메인 이름을 IP 주소 등 DNS 데이터로 해석하는 분산 계층 데이터베이스
재귀 vs 반복 질의?재귀는 끝까지 찾아와, 반복은 다음에 물어볼 곳을 알려줘
루트 서버가 13개라는 뜻?13개의 루트 서버 이름(A~M)이 있고, 실제 인스턴스는 anycast로 다수 분산
DNS 캐시 순서?브라우저/앱, OS, hosts, 재귀 리졸버 등 여러 계층이 있으며 구현별로 다름
권한 서버 vs 리졸버?권한은 zone의 실제 답변을 보유, 리졸버는 대리 조회와 캐시를 담당

마지막으로 이번 절의 핵심인 도메인 계층, 서버 역할, 재귀/반복 질의, 캐시 계층을 조회 흐름으로 한 번 묶어 봅니다.

DNS 조회는 이름 계층, 서버 역할, 캐시 TTL이 함께 결정한다

도메인을 오른쪽부터 좁혀 가며 권한 서버를 찾고, 얻은 레코드는 TTL 동안 여러 캐시 계층에서 재사용된다.

  1. 위임 경로

    Root 어느 TLD 서버로 갈지 알려준다. TLD 등록 도메인의 권한 서버를 알려준다. Authoritative zone의 실제 레코드 답을 낸다.

  2. 리졸버의 책임

    Cache check TTL이 남은 답을 먼저 확인한다. Iterative query referral을 따라 권한 서버까지 간다. Return 최종 답과 TTL을 클라이언트에게 돌려준다.

다음 절에서는 DNS 서버가 저장하는 구체적인 레코드 유형과 실습 도구를 살펴보겠습니다.