DNS
DNS란?
DNS(Domain Name System)는 사람이 읽을 수 있는 도메인 이름(www.example.com)을 컴퓨터가 사용하는 IP 주소(93.184.216.34)로 변환하는 분산 계층 데이터베이스 시스템이다.
사용자 입력: www.example.com
DNS 해석 결과: 93.184.216.34
브라우저가 실제 접속: 93.184.216.34:443
DNS 계층 구조
DNS는 전 세계에 분산된 계층 구조를 이룬다.
Root DNS Servers (13개 논리적 서버군)
.
/ \
/ \
.com .org .net .kr ...
(TLD) (TLD) (TLD)
/ \
/ \
example google
|
www.example.com → Authoritative Name Server
계층별 역할
| 계층 | 이름 | 역할 | 예시 |
|---|---|---|---|
| Root | 루트 DNS | TLD 서버 주소 알려줌 | 13개 클러스터 (a.root-servers.net 등) |
| TLD | 최상위 도메인 DNS | Authoritative 서버 주소 알려줌 | .com, .org, .kr, .io |
| Authoritative | 권한 있는 DNS | 실제 레코드 보유 | example.com의 실제 IP |
| Local/Recursive | 재귀 리졸버 | 클라이언트 대신 질의 대행 | ISP DNS, 8.8.8.8, 1.1.1.1 |
DNS 동작원리
질의 흐름
Client Local Resolver Root DNS
│ │ │
│── "www.example.com?" ──→│ │
│ │─── "www.example.com?" ──→│
│ │←── ".com TLD 서버: a.gtld-servers.net" ──│
│ │ │
│ TLD DNS (.com) Authoritative DNS
│ │─── "www.example.com?" ──────────────→│
│ │←── "example.com NS: ns1.example.com" ─│
│ │ │
│ │─── "www.example.com?" ──────────────────→│
│ │←── "93.184.216.34" ──────────────────────│
│ │ │
│←── "93.184.216.34" ────│
│
│ (결과 캐시 저장 후 이후 요청은 캐시 응답)
재귀 질의 vs 반복 질의
재귀 질의 (Recursive Query)
클라이언트가 Local Resolver(재귀 리졸버)에 질의하면 리졸버가 최종 답을 찾아 반환한다. 클라이언트 입장에서는 한 번의 질의로 완전한 답을 받는다.
Client → Local Resolver: "www.example.com 알려줘"
Local Resolver가 Root → TLD → Authoritative 모두 질의
Local Resolver → Client: "93.184.216.34"
클라이언트는 내부 동작을 모른다.
사용: 클라이언트↔리졸버 사이
반복 질의 (Iterative Query)
각 DNS 서버가 최종 답을 모르면 다음에 물어볼 서버의 주소를 알려준다. 질의자가 스스로 단계를 밟아 나간다.
Local Resolver → Root: "www.example.com?"
Root → Local Resolver: "모르지만 .com TLD에 물어봐: a.gtld-servers.net"
Local Resolver → TLD: "www.example.com?"
TLD → Local Resolver: "모르지만 Authoritative에 물어봐: ns1.example.com"
Local Resolver → Authoritative: "www.example.com?"
Authoritative → Local Resolver: "93.184.216.34"
사용: 리졸버↔각 DNS 서버 사이
DNS 레코드 타입
A 레코드
도메인을 IPv4 주소로 매핑한다.
도메인 TTL 클래스 타입 값
www.example.com. 3600 IN A 93.184.216.34
mail.example.com. 3600 IN A 192.0.2.1
AAAA 레코드
도메인을 IPv6 주소로 매핑한다.
www.example.com. 3600 IN AAAA 2606:2800:220:1:248:1893:25c8:1946
CNAME 레코드
도메인을 다른 도메인(별칭)으로 매핑한다. 최종적으로 A/AAAA 레코드를 찾을 때까지 체인을 따라간다.
www.example.com. 3600 IN CNAME example.com.
blog.example.com. 3600 IN CNAME mysite.netlify.app.
주의:
- CNAME 대상 도메인(example.com)에는 다른 레코드와 공존 불가
- 루트 도메인(@, apex)에는 CNAME 사용 불가 (ALIAS/ANAME 레코드로 대체)
- 체인이 길어지면 조회 지연 증가
MX 레코드
도메인의 이메일 서버를 지정한다. 우선순위(낮을수록 높음)를 가진다.
example.com. 3600 IN MX 10 mail1.example.com.
example.com. 3600 IN MX 20 mail2.example.com.
이메일 전송 시:
→ MX 10 (mail1) 시도 → 실패 시 MX 20 (mail2) 시도
TXT 레코드
도메인에 텍스트 정보를 저장한다. 주로 도메인 소유권 확인, 이메일 인증, 보안 정책에 사용한다.
example.com. 3600 IN TXT "v=spf1 include:_spf.google.com ~all"
(SPF: 이메일 스팸 방지)
_dmarc.example.com. IN TXT "v=DMARC1; p=reject; rua=mailto:dmarc@example.com"
(DMARC: 이메일 인증 정책)
google._domainkey.example.com. IN TXT "v=DKIM1; k=rsa; p=MIIBIjAN..."
(DKIM: 이메일 서명 공개키)
example.com. IN TXT "google-site-verification=abc123..."
(Google 소유권 확인)
NS 레코드
도메인의 권한 있는 DNS 서버를 지정한다.
example.com. 3600 IN NS ns1.example.com.
example.com. 3600 IN NS ns2.example.com.
도메인 등록기관에 NS 레코드 설정 → 이 서버가 도메인의 권한 있는 서버
SOA 레코드
DNS 존(Zone)의 시작 권한 정보를 담는다. 각 존당 반드시 1개 존재한다.
example.com. IN SOA ns1.example.com. admin.example.com. (
2026050101 ; Serial (존 버전, 날짜+순번)
3600 ; Refresh (Secondary가 Primary에서 갱신 주기)
900 ; Retry (갱신 실패 시 재시도 간격)
604800 ; Expire (갱신 실패 시 Secondary가 존 삭제하는 시간)
3600 ; Minimum TTL
)
PTR 레코드
IP 주소를 도메인 이름으로 역방향 조회한다. 이메일 서버 신뢰도 확인 등에 사용한다.
34.216.184.93.in-addr.arpa. IN PTR www.example.com.
# IPv4 역방향: 옥텟을 뒤집고 .in-addr.arpa. 붙임
역방향 조회:
nslookup 93.184.216.34
→ www.example.com
SRV 레코드
특정 서비스의 서버 위치(호스트, 포트)를 지정한다.
_xmpp-client._tcp.example.com. IN SRV 10 5 5222 xmpp.example.com.
우선순위 가중치 포트 대상
Kubernetes 서비스 디스커버리에서 내부적으로 활용됨
DNS 캐싱
캐싱 동작
각 DNS 응답에는 TTL(Time To Live)이 포함되며, TTL 동안 Local Resolver와 OS, 브라우저가 결과를 캐시한다.
캐싱 계층:
1. 브라우저 DNS 캐시 (chrome://net-internals/#dns)
2. OS DNS 캐시 (hosts 파일 포함)
3. Local Resolver 캐시 (ISP DNS, 8.8.8.8 등)
4. 각 계층별 DNS 서버 캐시
캐시 확인 순서:
브라우저 캐시 → OS 캐시 → Local Resolver 캐시 → 실제 DNS 조회
TTL 설정 전략
TTL이 낮은 경우 (60~300초):
장점: IP 변경 시 빠르게 전파
단점: DNS 서버에 빈번한 쿼리 → 부하 증가, 지연 증가
TTL이 높은 경우 (3600~86400초):
장점: 캐싱 효율 높음, DNS 서버 부하 낮음
단점: IP 변경 시 전파까지 최대 TTL만큼 소요
권장:
일반 운영: 3600 (1시간)
마이그레이션/장애 대응 전: 300 이하로 미리 낮춤
마이그레이션 완료 후: 다시 3600으로 복귀
OS DNS 캐시 초기화
# Windows
ipconfig /flushdns
# macOS
sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder
# Linux (systemd-resolved)
sudo systemd-resolve --flush-caches
# Linux (nscd)
sudo nscd -i hosts
DNSSEC
DNSSEC란?
DNS 응답의 무결성을 보장하는 보안 확장이다. DNS 스푸핑(위변조)과 캐시 포이즈닝 공격을 방지한다.
일반 DNS:
Client → Resolver: "example.com의 IP?"
(중간자 공격) 악의적 응답 삽입 가능 → 피싱 사이트로 유도
DNSSEC:
각 DNS 응답에 디지털 서명 포함
Client(또는 Resolver)가 서명 검증
서명 불일치 시 응답 거부
DNSSEC 레코드
| 레코드 | 역할 |
|---|---|
| RRSIG | 각 리소스 레코드에 대한 디지털 서명 |
| DNSKEY | 서명 검증에 사용하는 공개키 |
| DS | 상위 존이 하위 존의 DNSKEY를 신뢰함을 증명 |
| NSEC/NSEC3 | 존재하지 않는 레코드 증명 (음성 응답 보호) |
신뢰 체인 (Chain of Trust)
Root Zone (.) → .com TLD → example.com → www.example.com
각 단계에서 DS 레코드로 하위 존의 DNSKEY 서명 검증
DNS 장애 시나리오
시나리오 1: DNS 서버 장애
증상: 특정 도메인 해석 불가, 브라우저에 "서버를 찾을 수 없습니다"
원인:
- Authoritative DNS 서버 다운
- ISP DNS(Local Resolver) 장애
진단:
nslookup www.example.com # 현재 DNS로 조회
nslookup www.example.com 8.8.8.8 # Google DNS로 직접 조회
dig @1.1.1.1 www.example.com # Cloudflare DNS로 조회
대응:
- Primary DNS 장애: Secondary DNS가 자동 응답 (NS 레코드 2개 이상 필수)
- ISP DNS 장애: 8.8.8.8, 1.1.1.1로 변경
시나리오 2: DNS 전파 지연 (Propagation Delay)
증상: A는 새 IP로 접속되는데 B는 아직 구 IP로 접속됨
원인:
- TTL 남아있는 동안 각 리졸버가 캐시된 구 IP 반환
- 전 세계 수천 개 리졸버가 각자 다른 TTL 상태
해결:
- 마이그레이션 전 TTL을 300으로 낮추고 기존 TTL만큼 대기
- 구 IP → 새 IP로 리다이렉트 설정으로 전환 기간 커버
- dig +trace www.example.com 으로 각 단계 조회 경로 확인
시나리오 3: DNS 캐시 포이즈닝
공격:
1. 공격자가 재귀 리졸버에 다량의 위조 DNS 응답 주입
2. 합법적 응답보다 먼저 위조 응답이 캐시에 저장
3. 이후 질의는 위조된 IP 반환 → 사용자가 피싱 사이트로 유도
방어:
- DNSSEC 적용 (서명 검증으로 위조 차단)
- DNS over HTTPS (DoH) 또는 DNS over TLS (DoT) 사용
- Source Port Randomization (0.9.8 이후 대부분 리졸버 기본 적용)
시나리오 4: DNS 레코드 오설정
증상:
- MX 레코드 오류 → 이메일 수신 불가
- CNAME 체인 순환 → 무한 루프
- NS 레코드 오류 → 도메인 완전 해석 불가
진단 도구:
dig example.com MX # MX 레코드 확인
dig example.com NS # NS 레코드 확인
dig +trace example.com # 전체 해석 경로 추적
nslookup -type=SOA example.com # SOA 확인
whois example.com # 등록기관 NS 확인
온라인 도구:
https://mxtoolbox.com # MX, SPF, DKIM, DMARC 확인
https://dnschecker.org # 전 세계 DNS 전파 상태 확인
DNS 관련 보안 기술
DoH (DNS over HTTPS)
기존 DNS: 평문으로 쿼리 전송 → 중간자가 쿼리 내용 볼 수 있음
DoH: HTTPS로 DNS 쿼리 암호화 → 쿼리 내용 보호
포트: 443
설정: 브라우저 레벨(Firefox, Chrome) 또는 OS 레벨
지원: 8.8.8.8, 1.1.1.1, 9.9.9.9
# curl로 DoH 쿼리 예시
curl -H 'accept: application/dns-json' \
'https://1.1.1.1/dns-query?name=example.com&type=A'
DoT (DNS over TLS)
DoH와 유사하지만 TLS만 사용 (HTTP 없음)
포트: 853
장점: 전용 포트로 DoH보다 네트워크 정책 적용 쉬움
단점: 별도 포트로 일부 방화벽에서 차단될 수 있음
SPF, DKIM, DMARC (이메일 인증)
SPF (Sender Policy Framework):
TXT 레코드에 허가된 이메일 발송 서버 목록 정의
"v=spf1 ip4:192.0.2.0/24 include:_spf.google.com -all"
DKIM (DomainKeys Identified Mail):
이메일 서버가 보내는 메일에 디지털 서명 추가
수신 서버가 DNS의 공개키로 서명 검증
DMARC (Domain-based Message Authentication):
SPF, DKIM 검증 실패 시 처리 정책 정의
"v=DMARC1; p=reject; rua=mailto:dmarc@example.com"
p=none/quarantine/reject
주요 진단 명령어
# 기본 조회
nslookup www.example.com
dig www.example.com
# 특정 DNS 서버로 조회
dig @8.8.8.8 www.example.com
dig @1.1.1.1 example.com MX
# 레코드 타입별 조회
dig example.com A
dig example.com AAAA
dig example.com MX
dig example.com TXT
dig example.com NS
dig example.com SOA
# 전체 해석 경로 추적 (Root → TLD → Authoritative)
dig +trace www.example.com
# 역방향 조회 (IP → 도메인)
dig -x 93.184.216.34
nslookup 93.184.216.34
# TTL 확인
dig www.example.com | grep -i ttl
# DNSSEC 검증
dig +dnssec www.example.com