브라우저에 www.google.com을 치면 가장 먼저 일어나는 일이 DNS 질의입니다. 도메인 이름을 IP 주소로 바꾸는 과정인데, 이게 없으면 매번 142.250.196.100 같은 숫자를 외워야 합니다.

DNS는 하나의 거대한 서버가 아니라, 계층 구조로 분산된 시스템입니다. 브라우저 캐시부터 Root DNS까지, 질의가 어떤 경로를 따라가는지 정리합니다.


DNS 계층 구조

DNS는 하나의 거대한 서버가 모든 도메인을 관리하는 게 아닙니다. 트리 형태의 계층 구조로 되어 있습니다.

PLAINTEXT
                    . (Root)
                   / | \
              .com  .kr  .org   ← TLD (Top-Level Domain)
              /       \
         google.com  naver.kr   ← Authoritative DNS
          /     \
       www    mail              ← 호스트

Root DNS 서버

전 세계에 13개의 루트 DNS 서버(a.root-servers.net ~ m.root-servers.net)가 있습니다. 정확히는 13개 주소고 실제 물리 서버는 Anycast로 수백 대가 분산되어 있습니다.

".com은 어디서 관리하는지" 정도만 알려줍니다.

TLD 서버

.com, .kr, .org 같은 최상위 도메인을 관리합니다. .com TLD 서버는 google.com의 권한 있는 네임서버가 어디인지 알려줍니다.

Authoritative DNS 서버

실제 도메인의 DNS 레코드를 가지고 있는 서버입니다. google.com의 A 레코드가 142.250.196.100이라는 최종 답을 줍니다.


DNS 질의 과정

www.google.com에 접속하면 이런 순서로 IP를 찾습니다.

1. 브라우저 캐시

브라우저가 이미 방문한 도메인의 IP를 캐싱하고 있습니다. 여기서 찾으면 끝입니다. 크롬이면 chrome://net-internals/#dns에서 확인할 수 있습니다.

2. OS 캐시

브라우저에 없으면 운영체제 레벨의 DNS 캐시를 확인합니다. 리눅스는 systemd-resolved, macOS는 mDNSResponder가 관리합니다.

그리고 여기서 /etc/hosts 파일도 확인합니다. 로컬에서 도메인을 IP로 직접 매핑할 수 있는 파일인데, DNS보다 우선순위가 높습니다.

3. Local DNS 서버 (리졸버)

OS 캐시에도 없으면 ISP(통신사)가 제공하는 Local DNS 서버에 질의합니다. 혹은 8.8.8.8(Google), 1.1.1.1(Cloudflare) 같은 퍼블릭 DNS를 쓸 수도 있습니다.

이 리졸버가 실제로 루트부터 차근차근 찾아가는 주체입니다.

4. Root → TLD → Authoritative

PLAINTEXT
클라이언트          Local DNS           Root DNS
    │                  │                  │
    │─ www.google.com? ─→│                  │
    │                  │─ www.google.com? ─→│
    │                  │←── .com은 여기 ────│
    │                  │
    │                  │       TLD (.com)
    │                  │─ www.google.com? ─→│
    │                  │←── google.com NS ──│
    │                  │
    │                  │    Authoritative
    │                  │─ www.google.com? ─→│
    │                  │←── 142.250.196.100 │
    │                  │
    │←── 142.250.196.100 ──│

재귀 질의 vs 반복 질의

이 차이를 이해하는 것이 중요합니다.

재귀 질의 (Recursive Query)

클라이언트가 Local DNS에 질의하면, Local DNS가 끝까지 책임지고 답을 찾아서 돌려줍니다. 클라이언트 입장에서는 한 번만 물어보면 되니까 편합니다.

클라이언트 → Local DNS 구간이 보통 재귀 질의입니다.

반복 질의 (Iterative Query)

Local DNS가 루트, TLD, Authoritative 서버에 차례로 물어보는데, 각 서버는 "나는 모르겠고, 여기 물어봐"라고 다음 서버 정보만 알려줍니다. Local DNS가 직접 돌아다니면서 물어보는 방식입니다.

Local DNS → Root/TLD/Authoritative 구간이 반복 질의입니다.

왜 이렇게 나눠놨나?

루트 DNS 서버가 재귀 질의를 다 처리하면 전 세계 DNS 요청이 루트에 집중됩니다. 루트는 "여기 물어봐"만 알려주고 빠지는 게 부하 분산에 유리합니다.


DNS 레코드 종류

레코드설명예시
A도메인 → IPv4google.com → 142.250.196.100
AAAA도메인 → IPv6google.com → 2404:6800:400a:80b::200e
CNAME도메인 → 다른 도메인 (별칭)www.google.com → google.com
MX메일 서버 지정google.com → smtp.google.com (priority 10)
NS네임서버 지정google.com → ns1.google.com
TXT텍스트 데이터SPF, DKIM 인증, 도메인 소유권 확인 등
SOA영역의 권한 시작점시리얼 번호, 갱신 주기, TTL 기본값 등

CNAME의 함정

CNAME은 편리하지만 한 번 더 DNS 질의가 발생합니다. www.google.com이 CNAME으로 google.com을 가리키면, google.com의 A 레코드를 다시 조회해야 합니다.

그래서 루트 도메인(google.com 자체)에는 CNAME을 쓸 수 없습니다. NS, MX 레코드와 충돌하기 때문입니다. AWS Route 53의 Alias 레코드 같은 건 이 제한을 우회하기 위한 것입니다.


TTL과 DNS 캐싱

TTL (Time To Live)

DNS 레코드에 설정하는 캐시 유효 시간입니다. 초 단위로 지정합니다.

PLAINTEXT
google.com.    300    IN    A    142.250.196.100

              TTL 300초 (5분)

300초 동안은 이 응답을 캐시해도 된다는 뜻입니다. TTL이 지나면 다시 질의합니다.

캐시 계층

DNS 응답은 여러 곳에 캐싱됩니다.

  1. ** 브라우저 캐시** — 가장 먼저 확인, 가장 빨리 만료
  2. OS 캐시 — systemd-resolved, mDNSResponder
  3. Local DNS(ISP) 캐시 — 같은 ISP 사용자가 공유
  4. ** 중간 DNS 서버 캐시** — CDN이나 기업 내부 DNS

TTL 설정 전략

  • ** 긴 TTL (86400초 = 24시간)**: 변경이 거의 없는 레코드. 쿼리 수가 줄어듦
  • ** 짧은 TTL (60~300초)**: 서버 이전이나 장애 대응 시. 변경 사항이 빠르게 반영
  • ** 마이그레이션 전 패턴 **: 평소 TTL을 24시간으로 유지하다가, 서버 이전 하루 전에 TTL을 60초로 낮추고, 이전 완료 후 다시 올림

실무에서 서버 IP를 바꿨는데 반영이 안 된다면, 대부분 TTL 때문입니다.


DNS 라운드 로빈

하나의 도메인에 여러 개의 A 레코드를 등록하는 방식입니다.

PLAINTEXT
example.com    300    IN    A    1.1.1.1
example.com    300    IN    A    2.2.2.2
example.com    300    IN    A    3.3.3.3

질의할 때마다 순서를 돌려가며 응답합니다. 가장 단순한 로드 밸런싱입니다.

근데 문제가 있습니다:

  • 서버가 죽었는지 ** 헬스 체크를 못 합니다 **. 죽은 서버 IP를 계속 응답함
  • 클라이언트가 DNS 응답을 캐시하면 ** 균등 분배가 안 됩니다**
  • 서버별 부하 상태를 ** 고려하지 않습니다**

그래서 프로덕션에서는 DNS 라운드 로빈 단독으로 쓰기보다 L4/L7 로드 밸런서와 조합합니다.


GSLB (Global Server Load Balancing)

DNS 라운드 로빈의 한계를 넘어선 방식입니다. 지리적 분산과 헬스 체크를 지원합니다.

동작 방식

  1. 클라이언트가 DNS 질의
  2. GSLB가 클라이언트의 ** 위치(IP 기반)**를 파악
  3. 가장 가까운 서버, 혹은 가장 여유 있는 서버의 IP를 응답

한국에서 접속하면 서울 리전의 IP를, 미국에서 접속하면 버지니아 리전의 IP를 줍니다.

DNS 라운드 로빈과 차이

DNS 라운드 로빈GSLB
헬스 체크XO
지리적 라우팅XO
부하 기반 라우팅XO
비용무료비쌈

AWS Route 53의 지리적 라우팅, Cloudflare의 Load Balancing이 GSLB 구현체입니다. CDN도 이 원리로 가까운 엣지 서버를 찾아줍니다.


DNS 보안 — DoH와 DoT

기본 DNS 질의는 UDP 53번 포트로 ** 평문** 전송됩니다. 누가 어떤 사이트에 접속하는지 ISP나 네트워크 관리자가 다 볼 수 있습니다.

DNS over HTTPS (DoH)

DNS 질의를 HTTPS(443)로 암호화합니다. 일반 HTTPS 트래픽과 구분이 안 되기 때문에 네트워크 관리자가 DNS 질의를 필터링하기 어렵습니다.

PLAINTEXT
기존: 클라이언트 ──UDP 53──→ DNS 서버
DoH:  클라이언트 ──HTTPS 443──→ DNS 서버 (예: https://dns.google/dns-query)

Firefox, Chrome에서 설정할 수 있고, 1.1.1.1이나 8.8.8.8이 DoH를 지원합니다.

DNS over TLS (DoT)

DNS 질의를 TLS로 감싸서 853번 포트로 보냅니다. DoH와 목적은 같지만, 전용 포트를 쓰기 때문에 네트워크에서 식별 가능합니다.

DoH vs DoT

DoHDoT
포트443 (HTTPS와 동일)853 (전용)
트래픽 식별어려움가능
네트워크 차단어려움포트 차단으로 가능
지지 진영브라우저 벤더 (Mozilla, Google)ISP, 네트워크 관리자

기업 네트워크에서는 DoT를 선호합니다. DNS 트래픽을 제어할 수 있으니까요. 반면 프라이버시를 중시하면 DoH가 유리합니다.


심화 개념

"DNS는 왜 UDP를 쓰나요?"

DNS 질의와 응답은 보통 하나의 패킷으로 끝납니다. TCP처럼 3-way handshake를 거칠 필요가 없어서 훨씬 빠릅니다. 도메인 하나 조회하는데 왕복 3번은 낭비입니다.

단, ** 응답이 512바이트를 초과 **하거나 Zone Transfer(마스터-슬레이브 간 레코드 동기화)에는 TCP를 사용합니다. EDNS(Extension Mechanisms for DNS)를 쓰면 UDP에서도 4096바이트까지 가능합니다.

TCP/UDP에 대한 자세한 내용은 TCP vs UDP 글을 참고하세요.

"DNS Spoofing이 뭔가요?"

공격자가 위조된 DNS 응답을 클라이언트에 먼저 보내서, 사용자를 가짜 사이트로 유도하는 공격입니다.

예를 들어 bank.com을 조회했는데 공격자가 자기 서버 IP를 담은 응답을 먼저 보내면, 피싱 사이트에 접속하게 됩니다.

캐시 포이즈닝(Cache Poisoning)은 Local DNS 서버의 캐시를 오염시키는 변종입니다. 한 번 성공하면 해당 ISP의 모든 사용자가 영향을 받습니다.

"DNSSEC은 뭔가요?"

DNS 응답에 ** 전자 서명 **을 추가해서 응답이 변조되지 않았음을 검증하는 확장입니다. 공개키 기반으로 각 DNS 계층의 응답에 서명하고, 상위 계층이 하위 계층의 공개키를 보증하는 신뢰 체인(Chain of Trust)을 구성합니다.

DNS 응답 자체를 암호화하지는 않습니다. 그건 DoH/DoT의 영역입니다. DNSSEC은 "이 응답이 진짜인지" 검증하는 것이고, DoH/DoT는 "질의/응답을 엿볼 수 없게" 하는 것입니다.

"hosts 파일이 뭔가요?"

DNS 질의 전에 로컬에서 도메인-IP 매핑을 확인하는 파일입니다. 리눅스/macOS는 /etc/hosts, 윈도우는 C:\Windows\System32\drivers\etc\hosts에 있습니다.

PLAINTEXT
127.0.0.1    localhost
192.168.1.10 dev.myapp.com

개발할 때 로컬 서버에 도메인을 매핑하는 용도로 자주 씁니다. 하지만 악성코드가 hosts 파일을 변조해서 피싱에 활용하기도 합니다.


파생되는 개념들

  • TCP vs UDP — DNS가 UDP를 쓰는 이유
  • CDN — GSLB와 DNS 기반 라우팅
  • ** 시스템 설계** — 대규모 트래픽에서의 DNS 활용
댓글 로딩 중...