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

카테고리:

업데이트: