브라우저에 github.com 친다 — 몇 ms 안에 IP 주소140.82.114.4 가 돌아온다. 사이에서 무엇이 일어나나? DNS query 는 root server → TLD → authoritative server → resolver 4 단계 hierarchical lookup. caching, TTL, 그리고 ISP 의 옛 DNS spoofing 문제를 풀어내는 DoH (DNS-over-HTTPS) 까지. 이 가이드는 DNS 의 내부를 정리한다.
DNS 의 hierarchy
. ← root (점, 보통 생략)
├── com. ← TLD (top-level domain)
│ ├── github. ← 2nd-level
│ │ └── (A 레코드: 140.82.114.4)
│ ├── google.
│ └── ...
├── kr.
│ ├── co.kr.
│ │ └── naver.co.kr.
│ ├── or.kr.
│ └── go.kr.
├── org.
│ ├── wikipedia.
│ └── ...
└── ...도메인은 트리. 오른쪽에서 왼쪽으로 읽음 — www.github.com. 의 점은 root, com 은 TLD, github 는 2nd-level, www 는 host (자식).
한 번의 query — 4 단계
사용자: github.com 의 IP 가 뭐냐?
↓
브라우저 → OS resolver (/etc/resolv.conf)
↓
OS → ISP recursive resolver (예: 168.126.63.1 KT)
↓
recursive resolver 의 작업:
1. Root server 에 묻기
"com 의 nameserver 가 누구냐?"
↓
13 개 root server 중 하나 (a-m.root-servers.net)
↓
응답: "com 의 nameserver = a.gtld-servers.net"
2. TLD server (.com) 에 묻기
"github.com 의 nameserver 가 누구냐?"
↓
응답: "github.com 의 nameserver = ns-1283.awsdns-32.org"
3. Authoritative server 에 묻기
"github.com 의 A record 가 뭐냐?"
↓
응답: "A 140.82.114.4 TTL=60"
4. Recursive resolver 가 사용자에게 응답
"140.82.114.4"Recursive resolver 가 모든 lookup 처리. Client 는 한 번만 묻는다. 이 분리가 caching 의 핵심.
Recursive vs Authoritative
- Authoritative — 특정 zone (예: github.com) 의 "공식" 답변. zone owner 가 설정·운영.
- Recursive resolver — client 의 query 를 받아 authoritative 까지 추적. ISP / Cloudflare 1.1.1.1 / Google 8.8.8.8 / 회사 내부.
Recursive resolver 가 답을 cache. 두 번째 query 는 즉시 응답 (네트워크 부담 없음).
레코드 타입 — 7 가지 핵심
| 타입 | 용도 | 예시 |
|---|---|---|
A | IPv4 주소 | github.com → 140.82.114.4 |
AAAA | IPv6 주소 ("quad-A") | github.com → 2a01:4f8::1 |
CNAME | alias (다른 이름으로 redirect) | www.example.com → example.com |
MX | 메일 서버 | example.com → mail.example.com (priority 10) |
TXT | 임의 텍스트 (SPF, DKIM, domain verification) | "v=spf1 include:_spf.google.com ~all" |
NS | 이 zone 의 nameserver | example.com NS ns1.example.com |
SOA | zone 의 메타데이터 (serial, TTL 등) | example.com SOA ns1.example.com hostmaster... 2024010101 |
SRV | service location (port·priority·weight) | _sip._tcp.example.com → 10 60 5060 sip.example.com |
CAA | 이 도메인의 cert 발급 허용 CA | example.com CAA 0 issue "letsencrypt.org" |
PTR | IP → 도메인 reverse lookup | 4.114.82.140.in-addr.arpa → github.com |
TTL — caching 의 핵심
모든 레코드에 TTL (Time To Live, 초 단위) — 이 답을 얼마나 cache 할지:
github.com. 60 IN A 140.82.114.4
│
└─ TTL 60 초 = 1 분만 cache, 그 후 다시 queryTrade-off:
- 짧은 TTL (60) — 변경 빠르게 반영. 그러나 query 부하 ↑
- 긴 TTL (86400 = 24 시간) — query 부하 ↓. 그러나 변경 후 propagation 오래 걸림
실무 패턴:
- 일반 A record: 300-3600 초 (5분-1시간)
- migration / failover 위해 미리 줄여 둠: 60 초
- 거의 안 바뀌는 record (NS): 86400 초
CNAME 의 함정
www.example.com. CNAME example.com.
example.com. A 203.0.113.5
이게 가능 (www → example.com → 실제 IP)제약:
- root domain (apex) 에 CNAME X — example.com 자체 는 CNAME 불가. 다른 records (MX, NS, SOA) 와 충돌.
- AWS Route53 / Cloudflare 의 ALIAS / ANAME — root 에 CNAME 같은 기능 제공 (서비스 측 trick)
- chain 가능하지만 1-2 단계 권장 (lookup 부하)
MX record — 이메일 라우팅
example.com. MX 10 mail1.example.com.
example.com. MX 20 mail2.example.com.
│
└─ priority. 낮을수록 먼저 시도.
mail1 다운 → mail2 시도. failover 자동.SPF / DKIM / DMARC 도 TXT record 로:
SPF: "v=spf1 include:_spf.google.com ~all"
DKIM: selector._domainkey.example.com TXT "v=DKIM1; p=...."
DMARC: _dmarc.example.com TXT "v=DMARC1; p=reject"DNS over UDP vs TCP
- 기본 UDP port 53 — query 가 작으니 connection 오버헤드 X.
- 응답 > 512 byte 면 TCP fallback — UDP 패킷 크기 제한. DNSSEC 같은 큰 응답.
- DNS-over-HTTPS (DoH, RFC 8484) — HTTPS 위. plaintext UDP 의 도청·spoofing 방지. Firefox / Chrome / 1.1.1.1 / 8.8.8.8 지원.
- DNS-over-TLS (DoT, port 853) — TLS 위. DoH 와 유사하지만 별도 port.
DNSSEC — DNS spoofing 방지
평문 DNS = ISP / 카페 Wi-Fi 가 응답 위조 가능. github.com 묻는데 attacker 의 IP 응답. fake site 접속.
DNSSEC = 각 응답에 디지털 서명:
github.com. A 140.82.114.4
github.com. RRSIG A 13 2 60 ...signature...
resolver 가 서명 검증:
github.com 의 public key (DNSKEY) 가져옴
서명 verify
실패면 응답 거부 (SERVFAIL)도입 느림 — 복잡, 운영 부담. .gov / .mil / 일부 EU 강제. 일반 도메인 보급률 ~10%.
DNS 디버깅 도구
dig github.com # default A record
dig github.com AAAA # IPv6
dig github.com MX # mail server
dig +trace github.com # 전체 hierarchy trace
dig @8.8.8.8 github.com # 특정 resolver 에 물음
# Windows
nslookup github.com
nslookup -type=MX example.com
# online tools
https://www.whatsmydns.net/ ← 글로벌 propagation 확인도메인 변경 후 propagation 확인 — TTL 만큼 기다린 후 여러 region 에서 query. whatsmydns.net 이 50+ region 동시 query.
흔한 함정
1. 옛 DNS cache
OS / 브라우저 / ISP 가 각자 cache. TTL 만큼 기다려도 일부 cache 가 stale. ipconfig /flushdns (Win), sudo dscacheutil -flushcache (Mac).
2. CNAME at apex
example.com 의 root 에 CNAME 박으려 함 → DNS spec 위반. Route53 ALIAS / Cloudflare CNAME flattening 으로 우회.
3. NS 와 A 의 mismatch
# Registrar 에서 NS 설정
example.com NS ns1.cloudflare.com.
# 그러나 cloudflare 의 zone 에 example.com A record 없음
→ "DNS resolution failed"Domain registrar 의 NS 설정과 nameserver 의 zone data 가 일치해야. 도메인 이전 시 자주.
4. TTL 의 함정
production migration 전 TTL 60 으로 줄였지만, 자식 도메인 / 옛 cache 가 더 긴 옛 TTL 보유 → 일부 사용자가 옛 IP 로 며칠 라우팅. TTL 변경 자체도 propagation 필요.
5. SPF 누락 / 잘못된 record
이메일 server 가 SPF 검증 → 누락 시 spam folder 직행. SPF record 는 max 10 lookup (include 깊이 제한). 많이 박으면 PermError.
참고 자료
- RFC 1034 / 1035 (DNS 기초) — datatracker
- RFC 8484 (DoH) — datatracker
- DNS visualization — howdns.works (comic)
- DNSSEC quick reference — Internet Society
요약
- DNS = 도메인 → IP 변환의 hierarchy. root → TLD → authoritative → resolver 4 단계.
- Recursive resolver 가 모든 lookup 처리 + 결과 cache. Authoritative 는 zone owner 가 운영.
- 핵심 레코드 — A / AAAA / CNAME / MX / TXT / NS / SOA / SRV / CAA. 용도 다 다름.
- TTL = caching 시간. 짧을수록 변경 빠름·query 부하 ↑.
- CNAME 은 apex 에 X. ALIAS / CNAME flattening 으로 우회.
- UDP 53 default. 큰 응답은 TCP. DoH/DoT 가 암호화 미래.
- DNSSEC 가 spoofing 방지. 도입 ~10% 느림.
- 디버깅 — dig / nslookup / whatsmydns.net. DNS 변경 시 TTL 만큼 기다림.
- 실험 — IP / CIDR 계산기 가 IP 결과 해석. URL 파서 가 URL host part 추출.