- Published on
DNS 완전 정복: 네임서버, DDNS, nslookup 실전 가이드 — 도메인 등록부터 트러블슈팅까지
- Authors

- Name
- Youngju Kim
- @fjvbn20031
- 1. DNS 동작 원리 완전 이해
- 2. 네임서버 심화
- 3. DNS 레코드 타입 총정리
- 4. 도메인 등록/이전 실전 가이드
- 5. DDNS (Dynamic DNS) 완전 가이드
- 6. nslookup 완전 활용법
- 7. dig 명령어 마스터리
- 8. DNS 보안
- 9. 실전 트러블슈팅 10가지 시나리오
- 시나리오 1: 도메인 등록했는데 접속이 안 됨 (전파 지연)
- 시나리오 2: SSL 인증서 발급 실패 (CAA 레코드)
- 시나리오 3: 이메일이 스팸함으로 감 (SPF/DKIM/DMARC)
- 시나리오 4: 서브도메인이 작동하지 않음
- 시나리오 5: DNS 변경 후 일부 사용자만 접속 불가 (TTL 캐시)
- 시나리오 6: nslookup은 되는데 브라우저 접속 불가
- 시나리오 7: 도메인 이전 후 DNS 끊김
- 시나리오 8: K8s 내부 DNS 해석 실패 (CoreDNS, ndots)
- 시나리오 9: CDN 연동 후 원본 서버 IP 노출 (DNS Leak)
- 시나리오 10: DDNS 업데이트가 반영되지 않음
- 10. DNS 서비스 비교표
- 실전 퀴즈
- 참고 자료
1. DNS 동작 원리 완전 이해
DNS란? 인터넷의 전화번호부
DNS(Domain Name System)는 사람이 읽을 수 있는 도메인 이름(예: www.example.com)을 컴퓨터가 이해하는 IP 주소(예: 93.184.216.34)로 변환하는 시스템입니다. 1983년 Paul Mockapetris가 RFC 882, 883에서 처음 제안했고, 현재는 RFC 1034, 1035가 기본 명세입니다.
DNS가 없다면 우리는 모든 웹사이트에 접속할 때 IP 주소를 직접 입력해야 합니다. DNS는 인터넷 인프라의 가장 기본적이면서도 가장 중요한 구성 요소입니다.
사용자 입력: www.example.com
↓
DNS Resolution
↓
IP 주소: 93.184.216.34
↓
서버에 HTTP 요청
DNS 계층 구조: Root에서 Subdomain까지
DNS는 트리 구조의 계층적 분산 데이터베이스입니다. 최상위에서 하위로 내려가며:
. (Root)
/ \
com org net kr jp ... (TLD - Top Level Domain)
|
example (SLD - Second Level Domain)
/ \
www mail api (Subdomain)
계층별 역할:
| 계층 | 예시 | 관리 주체 |
|---|---|---|
| Root (.) | . | ICANN / IANA |
| TLD | .com, .kr, .org | 레지스트리 (Verisign, KISA 등) |
| SLD | example.com | 도메인 소유자 |
| Subdomain | www.example.com | 도메인 소유자 |
FQDN(Fully Qualified Domain Name)은 마지막에 점(.)을 포함합니다: www.example.com.
DNS 쿼리 흐름: 재귀적 vs 반복적
DNS 해석은 두 가지 방식이 조합되어 동작합니다.
재귀적 쿼리 (Recursive Query): 클라이언트가 재귀 리졸버에게 "최종 답을 알려줘"라고 요청합니다. 리졸버가 모든 일을 대신 처리합니다.
반복적 쿼리 (Iterative Query): 재귀 리졸버가 각 네임서버에게 "이 도메인 아는 사람 누구야?"라고 물어보면, 네임서버는 "나는 모르지만 저기 물어봐"라고 다음 서버를 안내합니다.
[사용자 PC] → 재귀적 쿼리 → [재귀 리졸버 (ISP/8.8.8.8)]
|
반복적 쿼리 시작
|
┌───────────────┼───────────────┐
↓ ↓ ↓
[Root Server] [TLD Server] [Authoritative NS]
"com은 여기" "example.com "IP는 93.x.x.x"
은 여기"
전체 흐름 상세:
- 사용자가 브라우저에
www.example.com입력 - 브라우저 캐시 확인 → OS 캐시 확인 → hosts 파일 확인
- OS가 설정된 재귀 리졸버(예: 8.8.8.8)에 재귀적 쿼리 전송
- 재귀 리졸버가 캐시 확인 → 없으면 Root 서버에 반복적 쿼리
- Root 서버: "
.comTLD 서버는a.gtld-servers.net이야" - 재귀 리졸버가 TLD 서버에 쿼리
- TLD 서버: "
example.com의 네임서버는ns1.example.com이야" - 재귀 리졸버가 권한 있는 네임서버에 쿼리
- 권한 있는 네임서버: "
www.example.com의 IP는93.184.216.34야" - 재귀 리졸버가 결과를 캐싱하고 클라이언트에 응답
13개 Root 서버와 Anycast
전 세계 DNS의 시작점인 Root 서버는 이름상 13개(A~M)이지만, Anycast 기술 덕분에 실제로는 1,700개 이상의 인스턴스가 전 세계에 분산되어 있습니다.
| Root 서버 | 운영 기관 | 인스턴스 수 (대략) |
|---|---|---|
| A | Verisign | 10+ |
| B | USC-ISI | 6+ |
| C | Cogent | 10+ |
| D | University of Maryland | 200+ |
| E | NASA | 300+ |
| F | ISC | 300+ |
| J | Verisign | 200+ |
| K | RIPE NCC | 100+ |
| L | ICANN | 200+ |
| M | WIDE Project | 10+ |
Anycast란? 같은 IP 주소를 여러 물리적 서버에 할당하는 기술입니다. 사용자의 쿼리는 BGP 라우팅을 통해 가장 가까운 인스턴스로 자동 전달됩니다. 이 덕분에 Root 서버 IP는 13개뿐이지만 전 세계 어디서나 빠른 응답이 가능합니다.
DNS 캐싱: 성능의 핵심
DNS 캐싱은 여러 레벨에서 이루어집니다:
[브라우저 캐시] → [OS 캐시] → [재귀 리졸버 캐시] → [각 네임서버 응답의 TTL]
Chrome: chrome://net-internals/#dns 에서 확인 가능
Windows: ipconfig /displaydns
Linux: systemd-resolve --statistics
macOS: sudo dscacheutil -flushcache
TTL (Time To Live) 이해:
example.com. 3600 IN A 93.184.216.34
↑
TTL = 3600초 (1시간)
TTL 값에 따른 전략:
| TTL 값 | 용도 | 장점 | 단점 |
|---|---|---|---|
| 60초 | DNS 변경 예정 시 | 빠른 전파 | 쿼리 증가, 응답 느림 |
| 300초 (5분) | 일반적인 서비스 | 균형 잡힌 선택 | - |
| 3600초 (1시간) | 안정적 서비스 | 빠른 응답, 쿼리 감소 | 변경 반영 느림 |
| 86400초 (1일) | 거의 변하지 않는 레코드 | 최고 성능 | 긴급 변경 어려움 |
실전 팁: DNS 변경 전에 TTL을 60초로 낮추고, 변경이 완전히 전파된 후 다시 올리세요.
2. 네임서버 심화
권한 있는(Authoritative) vs 재귀(Recursive) 네임서버
| 구분 | Authoritative NS | Recursive Resolver |
|---|---|---|
| 역할 | 특정 도메인의 최종 정보 보유 | 클라이언트 대신 DNS 트리 순회 |
| 데이터 | 존 파일의 원본 데이터 | 캐시된 데이터 |
| 예시 | ns1.cloudflare.com | 8.8.8.8 (Google DNS) |
| 운영 주체 | 도메인 소유자/호스팅 업체 | ISP, Google, Cloudflare |
| 응답 플래그 | AA (Authoritative Answer) 비트 설정 | AA 비트 없음 |
Primary(Master) vs Secondary(Slave) 네임서버
권한 있는 네임서버는 다시 Primary와 Secondary로 나뉩니다.
[Primary NS] ──Zone Transfer──→ [Secondary NS]
(읽기/쓰기) (읽기 전용)
원본 존 파일 관리 Primary 장애 시 백업
레코드 추가/수정/삭제 부하 분산 역할
왜 Secondary가 필요한가?
- 고가용성: Primary 장애 시 Secondary가 응답
- 부하 분산: 쿼리를 분산 처리
- 지리적 분산: 사용자와 가까운 곳에 배치
- RFC 2182 권장: 최소 2개의 네임서버 운영
존 전송 (Zone Transfer): AXFR vs IXFR
Primary에서 Secondary로 존 데이터를 복제하는 방식입니다.
| 방식 | 설명 | 용도 |
|---|---|---|
| AXFR | 전체 존 파일 전송 | 초기 동기화, 데이터 불일치 시 |
| IXFR | 변경분만 전송 | 일반적인 증분 업데이트 |
# AXFR 테스트 (보안상 외부에서는 차단되어야 함)
dig @ns1.example.com example.com AXFR
# SOA 레코드의 Serial로 동기화 여부 확인
dig @ns1.example.com example.com SOA +short
# 2024032301 ns1.example.com. admin.example.com. ...
SOA 레코드의 Serial 번호:
관례적으로 YYYYMMDDNN 형식을 사용합니다 (예: 2026032301). Serial이 증가하면 Secondary가 존 전송을 시작합니다.
글루 레코드(Glue Record)의 필요성
도메인 example.com의 네임서버가 ns1.example.com일 때 순환 참조 문제가 발생합니다:
Q: example.com의 IP는?
→ example.com의 네임서버는 ns1.example.com
→ ns1.example.com의 IP는?
→ example.com의 네임서버에게 물어봐야 하는데...
→ 순환 참조 발생!
해결: 글루 레코드
상위 TLD 서버에 네임서버의 IP를 직접 등록합니다:
;; .com TLD 서버의 위임 레코드
example.com. IN NS ns1.example.com.
example.com. IN NS ns2.example.com.
;; 글루 레코드 (Additional Section)
ns1.example.com. IN A 203.0.113.1
ns2.example.com. IN A 203.0.113.2
주요 DNS 소프트웨어
| 소프트웨어 | 유형 | 특징 |
|---|---|---|
| BIND9 | 권한/재귀 겸용 | 가장 오래된 DNS 서버. 전체 기능 지원 |
| PowerDNS | 권한 전용 | DB 백엔드 지원 (MySQL, PostgreSQL) |
| CoreDNS | 권한/재귀 | Go 기반, 플러그인 아키텍처, K8s 기본 DNS |
| Unbound | 재귀 전용 | 가볍고 보안 중심, DNSSEC 검증 기본 |
| Knot DNS | 권한 전용 | 고성능, 현대적 설계 |
| dnsmasq | 경량 캐싱 | 소규모 네트워크/홈 라우터용 |
CoreDNS in Kubernetes
Kubernetes 1.13부터 CoreDNS가 기본 DNS 서버입니다. Pod 내에서 서비스 이름으로 통신할 수 있는 것이 CoreDNS 덕분입니다.
# CoreDNS Corefile 예시
.:53 {
errors
health {
lameduck 5s
}
ready
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure
fallthrough in-addr.arpa ip6.arpa
ttl 30
}
prometheus :9153
forward . /etc/resolv.conf
cache 30
loop
reload
loadbalance
}
K8s DNS 해석 규칙:
# Pod에서 서비스 접근 시
my-service → my-service.default.svc.cluster.local
my-service.other-ns → my-service.other-ns.svc.cluster.local
my-service.other-ns.svc.cluster.local → 완전한 FQDN
# Pod의 /etc/resolv.conf
nameserver 10.96.0.10 # CoreDNS ClusterIP
search default.svc.cluster.local svc.cluster.local cluster.local
options ndots:5 # 점(.) 5개 미만이면 search 도메인 추가
ndots:5의 의미:
api.example.com은 점이 2개이므로(5 미만) K8s는 먼저 api.example.com.default.svc.cluster.local 등을 시도합니다. 이것이 외부 DNS 해석을 느리게 만들 수 있어, 외부 도메인은 FQDN(마지막에 . 추가)으로 지정하는 것이 좋습니다.
3. DNS 레코드 타입 총정리
핵심 레코드 타입
| 타입 | 용도 | 예시 |
|---|---|---|
| A | IPv4 주소 매핑 | example.com. IN A 93.184.216.34 |
| AAAA | IPv6 주소 매핑 | example.com. IN AAAA 2606:2800:220:1:: |
| CNAME | 별칭 (다른 도메인으로 포인팅) | www.example.com. IN CNAME example.com. |
| MX | 메일 서버 지정 | example.com. IN MX 10 mail.example.com. |
| TXT | 텍스트 정보 (SPF, DKIM 등) | example.com. IN TXT "v=spf1 ..." |
| NS | 네임서버 지정 | example.com. IN NS ns1.example.com. |
| SOA | 존 권한 정보 | 시리얼, 리프레시, 만료 등 |
| SRV | 서비스 위치 | _sip._tcp.example.com. IN SRV 10 60 5060 sip.example.com. |
| CAA | 인증서 발급 권한 | example.com. IN CAA 0 issue "letsencrypt.org" |
| PTR | 역방향 조회 (IP→도메인) | 34.216.184.93.in-addr.arpa. IN PTR example.com. |
| NAPTR | URI 변환 규칙 | SIP, ENUM에서 사용 |
CNAME의 제약사항
# OK - 서브도메인에 CNAME
www.example.com. IN CNAME example.com.
# BAD - 루트 도메인(Apex)에 CNAME 사용 불가!
# example.com. IN CNAME other.com. (RFC 위반)
# 해결: ALIAS/ANAME (비표준) 또는 Cloudflare의 CNAME Flattening
왜 Apex에 CNAME을 쓸 수 없는가? CNAME은 해당 이름의 다른 모든 레코드와 공존할 수 없습니다. 하지만 Apex 도메인에는 반드시 SOA, NS 레코드가 존재해야 하므로 CNAME과 충돌합니다.
이메일 인증 3총사: SPF, DKIM, DMARC
이메일 스팸과 피싱을 방지하기 위한 3가지 DNS 기반 인증 체계입니다.
SPF (Sender Policy Framework):
example.com. IN TXT "v=spf1 include:_spf.google.com include:sendgrid.net ip4:203.0.113.0/24 -all"
| 메커니즘 | 의미 |
|---|---|
include:domain | 해당 도메인의 SPF도 허용 |
ip4:CIDR | 해당 IP 대역 허용 |
a | 도메인의 A 레코드 IP 허용 |
mx | MX 레코드의 IP 허용 |
-all | 위 목록 외 모두 거부 |
~all | 위 목록 외 소프트 실패 |
DKIM (DomainKeys Identified Mail):
selector1._domainkey.example.com. IN TXT "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEB..."
메일 서버가 이메일에 전자 서명을 추가하고, 수신 서버가 DNS의 공개키로 검증합니다.
DMARC (Domain-based Message Authentication, Reporting, and Conformance):
_dmarc.example.com. IN TXT "v=DMARC1; p=reject; rua=mailto:dmarc-reports@example.com; pct=100"
| 정책 | 의미 |
|---|---|
p=none | 모니터링만 (보고서 수집) |
p=quarantine | 의심스러운 메일 스팸함으로 |
p=reject | 인증 실패 메일 거부 |
실전 존 파일 예시 (BIND 형식)
$TTL 3600
$ORIGIN example.com.
@ IN SOA ns1.example.com. admin.example.com. (
2026032301 ; Serial (YYYYMMDDNN)
3600 ; Refresh (1시간)
900 ; Retry (15분)
1209600 ; Expire (2주)
86400 ; Minimum TTL (1일)
)
; 네임서버
@ IN NS ns1.example.com.
@ IN NS ns2.example.com.
; A 레코드
@ IN A 203.0.113.10
www IN A 203.0.113.10
api IN A 203.0.113.20
; AAAA 레코드
@ IN AAAA 2001:db8::10
; CNAME
blog IN CNAME example.github.io.
docs IN CNAME readthedocs.io.
; MX 레코드 (우선순위 낮은 숫자가 높은 우선순위)
@ IN MX 10 mail.example.com.
@ IN MX 20 mail2.example.com.
mail IN A 203.0.113.30
; TXT 레코드
@ IN TXT "v=spf1 include:_spf.google.com -all"
_dmarc IN TXT "v=DMARC1; p=reject; rua=mailto:dmarc@example.com"
; SRV 레코드
_sip._tcp IN SRV 10 60 5060 sip.example.com.
; CAA 레코드
@ IN CAA 0 issue "letsencrypt.org"
@ IN CAA 0 issuewild "letsencrypt.org"
4. 도메인 등록/이전 실전 가이드
도메인 등록 구조
[ICANN] ──관리──→ [레지스트리] ──위임──→ [레지스트라] ──판매──→ [리셀러]
(Verisign 등) (가비아, Namecheap 등) (호스팅 업체 등)
레지스트리(Registry): TLD 전체를 관리 (예: .com은 Verisign)
레지스트라(Registrar): ICANN 인가를 받아 도메인 등록을 대행
리셀러(Reseller): 레지스트라의 재판매 파트너
한국 레지스트라 비교
| 레지스트라 | .com 연간 비용 | .kr 연간 비용 | 특징 |
|---|---|---|---|
| 가비아 | 약 16,500원 | 약 18,700원 | 국내 최대, 부가 서비스 풍부 |
| 후이즈 | 약 15,400원 | 약 17,600원 | 가격 경쟁력 |
| 카페24 | 약 14,300원 | 약 16,500원 | 호스팅 연동 편리 |
| Hosting.kr | 약 12,100원 | 약 14,300원 | 최저가 지향 |
해외 레지스트라 비교
| 레지스트라 | .com 연간 비용 | 특징 |
|---|---|---|
| Cloudflare Registrar | 약 10.11 USD | 원가 판매, 마크업 없음 |
| Namecheap | 약 8.88 USD (첫해) | 갱신가 상승 주의 |
| Porkbun | 약 9.73 USD | 가성비 좋음 |
| Google Domains | 서비스 종료 → Squarespace 이관 | 2023년 종료 |
Cloudflare Registrar를 추천하는 이유:
- 도매가(원가) 그대로 판매 (마크업 0)
- 갱신가도 동일
- 무료 DNSSEC, Whois Privacy
- Cloudflare CDN/보안 연동 용이
도메인 이전(Transfer) 절차
1. 현재 레지스트라에서 Transfer Lock(도메인 잠금) 해제
2. Auth Code(인증 코드 / EPP 코드) 발급
3. 새 레지스트라에서 Transfer 신청 + Auth Code 입력
4. 기존 레지스트라의 승인 메일 확인 (5~7일 대기)
5. 이전 완료 후 DNS 설정 확인
주의사항:
- 등록/이전 후 60일간 재이전 불가 (ICANN 60-Day Lock)
- 만료 15일 이내의 도메인은 이전 불가
- .kr 도메인은 별도 절차 (KISA 규정)
Whois와 RDAP
# Whois 조회
whois example.com
# RDAP (Whois 후속, JSON 기반)
curl -s "https://rdap.verisign.com/com/v1/domain/example.com" | jq .
RDAP(Registration Data Access Protocol)의 장점:
- 표준화된 JSON 응답
- HTTPS로 보안 전송
- 국제화(IDN) 지원
- 차등 접근 제어 가능
5. DDNS (Dynamic DNS) 완전 가이드
DDNS가 필요한 이유
가정용 인터넷은 대부분 유동 IP를 할당받습니다. ISP가 주기적으로(또는 라우터 재시작 시) IP를 변경하기 때문에, 고정 IP 없이는 집에서 서버를 운영하기 어렵습니다.
문제:
집 서버 IP: 211.xxx.xxx.100 (어제)
집 서버 IP: 211.xxx.xxx.200 (오늘) ← IP 변경됨!
DNS: myserver.example.com → 211.xxx.xxx.100 (어제 등록)
→ 접속 불가!
해결 (DDNS):
IP 변경 감지 → 자동으로 DNS 레코드 업데이트
myserver.example.com → 211.xxx.xxx.200 (자동 갱신)
DDNS 서비스 비교
| 서비스 | 무료 | 커스텀 도메인 | 업데이트 간격 | 특징 |
|---|---|---|---|---|
| DuckDNS | 무료 | X (*.duckdns.org만) | 실시간 | 완전 무료, 오픈소스 |
| No-IP | 무료(30일 갱신) | 유료 | 5분 | 3개 무료 호스트명 |
| Cloudflare DDNS | 무료 | O (자체 도메인) | 실시간 | API로 직접 구현 필요 |
| Synology DDNS | 무료 | X (*.synology.me) | 실시간 | Synology NAS 전용 |
| Dynu | 무료 | O (4개까지) | 실시간 | IPv6 지원 |
실전 셋업 1: ddclient (Linux)
# 설치
sudo apt install ddclient
# /etc/ddclient.conf 설정 (Cloudflare 예시)
protocol=cloudflare
use=web, web=https://api.ipify.org
zone=example.com
login=your-email@example.com
password=your-cloudflare-api-token
myserver.example.com
# 서비스 시작
sudo systemctl enable ddclient
sudo systemctl start ddclient
# 상태 확인
sudo systemctl status ddclient
sudo ddclient -query
실전 셋업 2: Cloudflare API로 DDNS 직접 구현
#!/bin/bash
# cloudflare-ddns.sh
# 설정
CF_API_TOKEN="your-api-token-here"
CF_ZONE_ID="your-zone-id-here"
CF_RECORD_NAME="myserver.example.com"
CF_RECORD_ID="your-record-id-here"
# 현재 공인 IP 확인
CURRENT_IP=$(curl -s https://api.ipify.org)
# DNS에 등록된 IP 확인
DNS_IP=$(dig +short "$CF_RECORD_NAME" @1.1.1.1)
# IP가 변경되었으면 업데이트
if [ "$CURRENT_IP" != "$DNS_IP" ]; then
echo "IP changed: $DNS_IP -> $CURRENT_IP"
curl -s -X PUT \
"https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/dns_records/$CF_RECORD_ID" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-H "Content-Type: application/json" \
--data "{\"type\":\"A\",\"name\":\"$CF_RECORD_NAME\",\"content\":\"$CURRENT_IP\",\"ttl\":60,\"proxied\":false}"
echo "DNS updated successfully"
else
echo "IP unchanged: $CURRENT_IP"
fi
# crontab에 등록 (5분마다 실행)
crontab -e
# */5 * * * * /home/user/cloudflare-ddns.sh >> /var/log/ddns.log 2>&1
실전 셋업 3: Docker + DDNS 자동 업데이트
# docker-compose.yml
version: '3'
services:
cloudflare-ddns:
image: oznu/cloudflare-ddns:latest
restart: always
environment:
- API_KEY=your-cloudflare-api-token
- ZONE=example.com
- SUBDOMAIN=myserver
- PROXIED=false
- RRTYPE=A
- DELETE_ON_STOP=false
- DNS_SERVER=1.1.1.1
docker-compose up -d
홈서버 운영: DDNS + Let's Encrypt + Nginx Proxy Manager
[인터넷] → [공유기 포트포워딩] → [Nginx Proxy Manager] → [서비스들]
|
Let's Encrypt
자동 SSL 발급
# docker-compose.yml - 홈서버 스택
version: '3'
services:
nginx-proxy-manager:
image: jc21/nginx-proxy-manager:latest
restart: unless-stopped
ports:
- '80:80'
- '443:443'
- '81:81' # 관리 패널
volumes:
- ./npm-data:/data
- ./npm-letsencrypt:/etc/letsencrypt
cloudflare-ddns:
image: oznu/cloudflare-ddns:latest
restart: always
environment:
- API_KEY=your-cf-token
- ZONE=example.com
- SUBDOMAIN=home
포트포워딩 + 방화벽 설정
공유기 설정:
외부 80 → 내부 192.168.1.100:80
외부 443 → 내부 192.168.1.100:443
Linux 방화벽 (UFW):
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
보안 주의사항:
- 22번(SSH) 포트는 외부에 절대 개방하지 마세요 (VPN 또는 Tailscale 사용)
- 관리 패널(81번)도 외부 차단
- fail2ban으로 브루트포스 방어
- Cloudflare Proxy를 켜면 원본 IP 노출 방지
6. nslookup 완전 활용법
기본 사용법
# 기본 조회
nslookup example.com
# Server: 8.8.8.8
# Address: 8.8.8.8#53
#
# Non-authoritative answer:
# Name: example.com
# Address: 93.184.216.34
# 특정 DNS 서버로 조회
nslookup example.com 1.1.1.1
레코드 타입별 조회
# MX 레코드 (메일 서버)
nslookup -type=mx gmail.com
# gmail.com mail exchanger = 5 gmail-smtp-in.l.google.com.
# gmail.com mail exchanger = 10 alt1.gmail-smtp-in.l.google.com.
# AAAA 레코드 (IPv6)
nslookup -type=aaaa google.com
# TXT 레코드 (SPF, DKIM 등)
nslookup -type=txt example.com
# NS 레코드 (네임서버)
nslookup -type=ns example.com
# SOA 레코드 (존 정보)
nslookup -type=soa example.com
# CAA 레코드 (인증서 발급 권한)
nslookup -type=caa example.com
# SRV 레코드 (서비스 위치)
nslookup -type=srv _sip._tcp.example.com
# ANY (모든 레코드 - 일부 서버는 차단)
nslookup -type=any example.com
대화형 모드
nslookup
> server 8.8.8.8 # DNS 서버 변경
> set type=mx # 레코드 타입 설정
> gmail.com # 조회
> set type=txt
> example.com
> set debug # 디버그 모드 ON
> example.com # 상세 정보 출력
> set d2 # 더 상세한 디버그
> exit
역방향 조회 (PTR)
# IP → 도메인 조회
nslookup 8.8.8.8
# 8.8.8.8.in-addr.arpa name = dns.google.
nslookup 1.1.1.1
# 1.1.1.1.in-addr.arpa name = one.one.one.one.
실전 예제 10가지
# 1. 특정 도메인의 네임서버 확인
nslookup -type=ns example.com
# 2. 메일 서버 확인 (이메일 문제 디버깅)
nslookup -type=mx company.com
# 3. SPF 레코드 확인 (이메일 스팸 문제)
nslookup -type=txt example.com
# 4. Google DNS vs Cloudflare DNS 비교
nslookup example.com 8.8.8.8
nslookup example.com 1.1.1.1
# 5. IPv6 주소 확인
nslookup -type=aaaa facebook.com
# 6. 와일드카드 서브도메인 테스트
nslookup nonexistent-sub.example.com
# 7. CAA 레코드 확인 (SSL 인증서 발급 전)
nslookup -type=caa example.com
# 8. 역방향 DNS 확인 (IP 소유자 파악)
nslookup 203.0.113.1
# 9. CNAME 체인 추적
nslookup -type=cname www.example.com
# 10. SOA 레코드로 DNS 관리자 확인
nslookup -type=soa example.com
7. dig 명령어 마스터리
dig vs nslookup 차이점
| 항목 | dig | nslookup |
|---|---|---|
| 출력 | 상세 (섹션별 구분) | 간략 |
| DNSSEC | 지원 (+dnssec) | 미지원 |
| 추적 | 지원 (+trace) | 미지원 |
| 배치 모드 | 지원 (-f) | 미지원 |
| 설치 | bind-utils/dnsutils | 대부분 기본 설치 |
| 권장 | DevOps/SRE | 간단한 확인 |
기본 사용법
# 기본 조회
dig example.com
# 출력 구조:
# ;; QUESTION SECTION: ← 질문
# ;example.com. IN A
#
# ;; ANSWER SECTION: ← 응답
# example.com. 3600 IN A 93.184.216.34
#
# ;; AUTHORITY SECTION: ← 권한 있는 네임서버
# example.com. 3600 IN NS a.iana-servers.net.
#
# ;; ADDITIONAL SECTION: ← 추가 정보
# a.iana-servers.net. 3600 IN A 199.43.135.53
#
# ;; Query time: 23 msec
# ;; SERVER: 8.8.8.8#53(8.8.8.8)
자주 쓰는 옵션
# 짧은 출력 (IP만)
dig +short example.com
# 93.184.216.34
# 특정 레코드 타입
dig example.com MX
dig example.com AAAA
dig example.com TXT
dig example.com NS
dig example.com SOA
dig example.com CAA
# 특정 DNS 서버 지정
dig @8.8.8.8 example.com
dig @1.1.1.1 example.com
# 응답 시간만 확인
dig example.com | grep "Query time"
# ;; Query time: 23 msec
Root부터 추적: +trace
# DNS 해석 전체 과정을 Root부터 추적
dig +trace example.com
# 출력 (요약):
# . 518400 IN NS a.root-servers.net. ← Root
# com. 172800 IN NS a.gtld-servers.net. ← TLD
# example.com. 86400 IN NS a.iana-servers.net. ← Authoritative
# example.com. 3600 IN A 93.184.216.34 ← 최종 답
이것은 DNS 트러블슈팅에서 가장 유용한 명령 중 하나입니다. 어느 단계에서 문제가 발생하는지 정확히 알 수 있습니다.
DNSSEC 검증
# DNSSEC 서명 정보 확인
dig +dnssec example.com
# DNSSEC 유효성 검증
dig +sigchase +trusted-key=/etc/trusted-key.key example.com
# DNSSEC 관련 레코드 직접 조회
dig example.com DNSKEY
dig example.com DS
dig example.com RRSIG
dig example.com NSEC
배치 조회
# domains.txt 파일의 모든 도메인 한 번에 조회
cat domains.txt
# example.com
# google.com
# github.com
dig -f domains.txt +short
# 특정 레코드 타입으로 배치 조회
dig -f domains.txt MX +short
고급 옵션
# TCP 모드로 조회 (UDP 대신)
dig +tcp example.com
# 응답의 특정 섹션만 출력
dig +noall +answer example.com # 응답만
dig +noall +authority example.com # 권한 섹션만
dig +noall +stats example.com # 통계만
# TTL 포함 축약 출력
dig +nocmd +noall +answer +ttlid example.com
# 역방향 조회
dig -x 8.8.8.8
# 8.8.8.8.in-addr.arpa. IN PTR dns.google.
# CHAOS 클래스로 DNS 서버 버전 확인
dig @ns1.example.com version.bind CHAOS TXT
# EDNS Client Subnet 테스트
dig +subnet=203.0.113.0/24 example.com @8.8.8.8
실전 예제 15가지
# 1. 특정 네임서버에서 권한 있는 응답 확인
dig @ns1.example.com example.com +norecurse
# 2. DNS 전파 확인 (여러 DNS 서버 비교)
for dns in 8.8.8.8 1.1.1.1 9.9.9.9 208.67.222.222; do
echo "=== $dns ==="
dig @$dns example.com +short
done
# 3. CNAME 체인 전체 추적
dig +trace +nodnssec www.example.com CNAME
# 4. MX 레코드 우선순위 확인
dig example.com MX +short | sort -n
# 5. SPF 레코드 확인
dig example.com TXT +short | grep spf
# 6. DKIM 레코드 확인
dig selector1._domainkey.example.com TXT +short
# 7. DMARC 정책 확인
dig _dmarc.example.com TXT +short
# 8. CAA 레코드 확인 (SSL 발급 전)
dig example.com CAA +short
# 9. SOA 레코드의 시리얼 번호 확인 (존 전송 동기화)
dig example.com SOA +short
# 10. 응답 시간 비교 (DNS 성능 테스트)
for i in $(seq 1 10); do
dig example.com @8.8.8.8 | grep "Query time"
done
# 11. IPv6 레코드 확인
dig example.com AAAA +short
# 12. 와일드카드 DNS 확인
dig random-subdomain.example.com +short
# 13. NSEC/NSEC3 레코드로 DNSSEC 부정 존재 증명
dig nonexistent.example.com NSEC
# 14. DNS 응답 크기 확인 (DDoS 증폭 테스트)
dig example.com ANY +bufsize=4096
# 15. 전체 존 내보내기 시도 (보안 감사)
dig @ns1.example.com example.com AXFR
8. DNS 보안
DNS 공격 유형
1. DNS Cache Poisoning (캐시 오염)
정상: 리졸버 → Authoritative NS → 정확한 IP
공격: 공격자가 가짜 응답을 리졸버 캐시에 주입
결과: 사용자가 피싱 사이트로 유도됨
방어: DNSSEC, 랜덤 소스 포트, 0x20 인코딩
2. DNS Amplification DDoS
공격 방식:
1. 공격자가 피해자 IP로 소스 주소를 위조 (IP Spoofing)
2. 오픈 리졸버에 큰 응답을 유발하는 쿼리 전송 (ANY 타입)
3. 작은 쿼리 → 큰 응답 = 증폭 효과 (50~70배)
4. 모든 응답이 피해자에게 집중
방어: BCP38(소스 주소 검증), RRL(Response Rate Limiting)
3. DNS Hijacking
방식 1: 라우터/ISP 수준에서 DNS 응답 변조
방식 2: 레지스트라 계정 탈취 → 네임서버 변경
방식 3: 악성코드가 시스템 DNS 설정 변경
방어: DNSSEC, 레지스트라 계정 2FA, DNS 모니터링
4. DNS Tunneling
목적: DNS 프로토콜을 악용하여 데이터 유출/원격 제어
방식: DNS 쿼리/응답에 인코딩된 데이터를 숨김
예: malicious-data.encoded.evil.com 으로 TXT 쿼리
→ 방화벽은 정상 DNS 트래픽으로 인식
방어: DNS 쿼리 길이/빈도 모니터링, DNS 방화벽
DNSSEC 동작 원리
DNSSEC은 DNS 응답의 무결성과 출처를 암호학적으로 검증합니다.
신뢰의 체인 (Chain of Trust):
Root (.) → .com → example.com
각 레벨에서:
1. DNSKEY: 존의 공개키
2. RRSIG: 각 레코드의 전자 서명
3. DS: 하위 존의 공개키 해시 (상위 존에 저장)
4. NSEC/NSEC3: "이 이름은 존재하지 않음"의 증명
# DNSSEC 검증 확인
dig +dnssec example.com
# 응답에 'ad' 플래그가 있으면 DNSSEC 검증 성공
# flags: qr rd ra ad; QUERY: 1, ANSWER: 2
# DNSKEY 조회
dig example.com DNSKEY +short
# DS 레코드 조회 (상위 존에서)
dig example.com DS +short
DNS over HTTPS (DoH) / DNS over TLS (DoT)
기존 DNS는 평문 UDP/TCP로 전송되어 ISP나 네트워크 관리자가 DNS 쿼리를 열람/조작할 수 있습니다.
| 프로토콜 | 포트 | 암호화 | 특징 |
|---|---|---|---|
| 일반 DNS | 53 (UDP/TCP) | 없음 | 도청/조작 가능 |
| DoT | 853 (TCP) | TLS | 전용 포트로 차단 가능 |
| DoH | 443 (HTTPS) | HTTPS | HTTPS 트래픽에 숨어 차단 어려움 |
| DoQ | 853 (QUIC) | QUIC | 최신, 낮은 지연 |
# DoH로 DNS 조회 (curl)
curl -s -H "accept: application/dns-json" \
"https://1.1.1.1/dns-query?name=example.com&type=A" | jq .
# DoH 서비스
# Cloudflare: https://1.1.1.1/dns-query
# Google: https://dns.google/dns-query
# Quad9: https://dns.quad9.net/dns-query
# DoT 테스트 (kdig 사용)
kdig -d @1.1.1.1 +tls-ca +tls-host=cloudflare-dns.com example.com
DNS Filtering: Pi-hole, NextDNS, AdGuard Home
[디바이스] → [DNS 필터] → [허용된 쿼리만 통과] → [인터넷]
|
광고/악성 도메인 차단
트래커 차단
성인 콘텐츠 필터링
| 솔루션 | 유형 | 특징 |
|---|---|---|
| Pi-hole | 자체 호스팅 | Raspberry Pi에서 운영, 네트워크 전체 적용 |
| NextDNS | 클라우드 | 월 30만 쿼리 무료, 설정 간편 |
| AdGuard Home | 자체 호스팅 | DoH/DoT 지원, 웹 UI |
기업용: DNS Firewall과 RPZ
RPZ (Response Policy Zone):
DNS 방화벽에서 특정 도메인에 대한 응답을 재정의하는 기술
예시 (BIND RPZ):
; rpz.db
evil-domain.com CNAME . ; NXDOMAIN 응답
malware-c2.com CNAME . ; 차단
phishing-site.com A 10.0.0.1 ; 경고 페이지로 리다이렉트
9. 실전 트러블슈팅 10가지 시나리오
시나리오 1: 도메인 등록했는데 접속이 안 됨 (전파 지연)
증상: 도메인을 등록하고 A 레코드를 설정했는데 브라우저에서 접속이 안 됩니다.
원인: DNS 전파(Propagation)는 전 세계 DNS 서버의 캐시가 갱신되는 데 최대 48시간이 소요됩니다.
# 진단
# 1. 권한 있는 네임서버에서 직접 확인 (이것이 되면 설정은 정상)
dig @ns1.your-dns-provider.com yourdomain.com A +short
# 2. 여러 공개 DNS로 전파 상태 확인
dig @8.8.8.8 yourdomain.com +short
dig @1.1.1.1 yourdomain.com +short
dig @9.9.9.9 yourdomain.com +short
# 3. 온라인 도구로 전 세계 전파 확인
# https://www.whatsmydns.net/
해결:
- 기다립니다 (최대 48시간, 보통 1~4시간)
- 로컬 DNS 캐시 강제 삭제:
ipconfig /flushdns(Windows) 또는sudo dscacheutil -flushcache(macOS) - 사전에 TTL을 낮게 설정했다면 더 빠르게 전파됩니다
시나리오 2: SSL 인증서 발급 실패 (CAA 레코드)
증상: Let's Encrypt로 SSL 인증서를 발급하려는데 실패합니다.
# 진단: CAA 레코드 확인
dig yourdomain.com CAA +short
# 0 issue "digicert.com" ← Let's Encrypt가 허용 목록에 없음!
# 해결: CAA 레코드 추가 또는 수정
# yourdomain.com. IN CAA 0 issue "letsencrypt.org"
# yourdomain.com. IN CAA 0 issuewild "letsencrypt.org"
# CAA 레코드가 없으면 모든 CA가 발급 가능 (기본값)
dig yourdomain.com CAA +short
# (빈 응답 = 제한 없음)
시나리오 3: 이메일이 스팸함으로 감 (SPF/DKIM/DMARC)
증상: 발송한 이메일이 수신자의 스팸함으로 들어갑니다.
# 진단 1: SPF 레코드 확인
dig yourdomain.com TXT +short | grep spf
# "v=spf1 include:_spf.google.com -all"
# 진단 2: DKIM 레코드 확인 (selector는 이메일 헤더에서 확인)
dig google._domainkey.yourdomain.com TXT +short
# 진단 3: DMARC 정책 확인
dig _dmarc.yourdomain.com TXT +short
# "v=DMARC1; p=none; rua=mailto:dmarc@yourdomain.com"
# 해결 체크리스트:
# 1. SPF에 메일 발송 서버 IP/도메인 포함 확인
# 2. DKIM 서명 키 등록 확인
# 3. DMARC 정책 설정 (처음엔 p=none으로 모니터링)
# 4. DMARC 보고서 분석 후 p=quarantine → p=reject 순서로 강화
시나리오 4: 서브도메인이 작동하지 않음
증상: api.example.com은 되는데 staging.example.com은 안 됩니다.
# 진단: 해당 서브도메인 레코드 존재 여부 확인
dig staging.example.com A +short
# (빈 응답 = 레코드 없음)
dig api.example.com A +short
# 203.0.113.20 (정상)
# 와일드카드 레코드 확인
dig *.example.com A +short
해결:
- 해당 서브도메인의 A/CNAME 레코드를 명시적으로 추가
- 또는 와일드카드(
*.example.com) 레코드 설정 - 와일드카드는 명시적 레코드보다 우선순위가 낮음을 기억하세요
시나리오 5: DNS 변경 후 일부 사용자만 접속 불가 (TTL 캐시)
증상: DNS 레코드를 변경했는데, 어떤 사용자는 새 서버로 접속하고 어떤 사용자는 이전 서버로 접속합니다.
# 진단: 각 DNS 서버의 캐시 상태 확인
dig @8.8.8.8 example.com +short # Google DNS
dig @1.1.1.1 example.com +short # Cloudflare DNS
dig @168.126.63.1 example.com +short # KT DNS
# TTL 확인
dig example.com | grep -A1 "ANSWER SECTION"
# example.com. 1800 IN A 203.0.113.10
# ↑ 남은 TTL이 아직 높음
해결:
- TTL 시간만큼 기다립니다
- 다음부터는 DNS 변경 24시간 전에 TTL을 60초로 낮추세요
- 변경 완료 후 TTL을 원래 값으로 복구
시나리오 6: nslookup은 되는데 브라우저 접속 불가
증상: nslookup example.com은 정상 응답하는데 Chrome에서 접속이 안 됩니다.
# 진단 1: hosts 파일 확인
cat /etc/hosts # Linux/macOS
type C:\Windows\System32\drivers\etc\hosts # Windows
# 진단 2: 브라우저 DNS 캐시 확인
# Chrome: chrome://net-internals/#dns → Clear host cache
# 진단 3: HSTS 문제 확인
# Chrome: chrome://net-internals/#hsts
# 도메인 삭제 후 재시도
# 진단 4: 프록시/VPN 설정 확인
# 브라우저 프록시 설정이 DNS를 우회할 수 있음
# 진단 5: DNS over HTTPS 설정 확인
# Chrome 설정 → 개인 정보 보호 및 보안 → 보안 DNS 사용
시나리오 7: 도메인 이전 후 DNS 끊김
증상: 도메인을 다른 레지스트라로 이전한 후 사이트가 다운되었습니다.
# 진단: 현재 네임서버 확인
dig example.com NS +short
# 이전 레지스트라의 네임서버가 보이면 아직 업데이트 안 됨
# 해결 순서:
# 1. 새 레지스트라에서 DNS 레코드를 먼저 설정
# 2. 이전 전에 모든 레코드를 새 곳에 복제
# 3. 네임서버 변경
# 4. 이전 네임서버는 최소 48시간 유지
예방법: 이전 전에 반드시 새 레지스트라에 모든 DNS 레코드를 먼저 설정하세요.
시나리오 8: K8s 내부 DNS 해석 실패 (CoreDNS, ndots)
증상: Pod에서 외부 도메인(api.external.com)에 접속이 안 되거나 매우 느립니다.
# 진단 1: Pod 내에서 DNS 해석 테스트
kubectl exec -it debug-pod -- nslookup api.external.com
# 진단 2: resolv.conf 확인
kubectl exec -it debug-pod -- cat /etc/resolv.conf
# nameserver 10.96.0.10
# search default.svc.cluster.local svc.cluster.local cluster.local
# options ndots:5
# 진단 3: CoreDNS 로그 확인
kubectl logs -n kube-system -l k8s-app=kube-dns
# 문제: ndots:5 때문에 api.external.com (점 2개)이
# api.external.com.default.svc.cluster.local 등을 먼저 시도
해결:
# 방법 1: FQDN 사용 (마지막에 점 추가)
# 코드에서 api.external.com. 으로 호출
# 방법 2: Pod의 dnsConfig 설정
apiVersion: v1
kind: Pod
spec:
dnsConfig:
options:
- name: ndots
value: '2'
시나리오 9: CDN 연동 후 원본 서버 IP 노출 (DNS Leak)
증상: Cloudflare를 사용 중인데 원본 서버 IP가 노출되어 DDoS 공격을 직접 받습니다.
# 진단: 프록시되지 않는 레코드 확인
# Cloudflare 대시보드에서 주황색 구름(프록시 활성)이 아닌
# 회색 구름(DNS Only) 레코드가 있는지 확인
# 서브도메인 스캔으로 노출 여부 확인
dig direct.example.com +short # 원본 IP 노출?
dig mail.example.com +short # MX용 A레코드에 원본 IP?
dig ftp.example.com +short # FTP 서브도메인에 원본 IP?
해결:
- 모든 A/AAAA 레코드에 Cloudflare 프록시 활성화
- MX에 필요한 A 레코드는 별도 IP 사용
- 원본 IP가 이미 노출되었다면 서버 IP를 변경
- 과거 DNS 기록 확인: SecurityTrails, DNS History 등에 원본 IP가 남아있을 수 있음
시나리오 10: DDNS 업데이트가 반영되지 않음
증상: DDNS 서비스를 설정했는데 IP가 변경되어도 DNS가 업데이트되지 않습니다.
# 진단 1: 현재 공인 IP 확인
curl -s https://api.ipify.org
# 진단 2: DNS에 등록된 IP 확인
dig myserver.example.com +short
# 진단 3: DDNS 클라이언트 로그 확인
sudo journalctl -u ddclient -n 50
# 진단 4: API 토큰 유효성 확인
curl -s -X GET "https://api.cloudflare.com/client/v4/user/tokens/verify" \
-H "Authorization: Bearer YOUR_TOKEN" | jq .
# 일반적인 원인:
# 1. API 토큰 만료 또는 권한 부족
# 2. Zone ID 또는 Record ID 오류
# 3. 방화벽이 DDNS 클라이언트의 외부 통신 차단
# 4. cron 작업이 비활성화됨
# 5. IP 확인 서비스(ipify 등) 접속 불가
10. DNS 서비스 비교표
관리형 DNS 서비스
| 서비스 | 무료 플랜 | 관리 DNS | DDNS | DNSSEC | DDoS 방어 | 가격 (유료) |
|---|---|---|---|---|---|---|
| Cloudflare | O (무제한) | O | API로 구현 | O (무료) | O | 무료~엔터프라이즈 |
| AWS Route 53 | X | O | X | O | O (Shield) | 월 0.50 USD/존 |
| Google Cloud DNS | X | O | X | O | O | 월 0.20 USD/존 |
| Azure DNS | X | O | X | O (프리뷰) | O | 월 0.50 USD/존 |
| NS1 | 무료 티어 | O | O | O | O | 커스텀 |
| Dyn (Oracle) | X | O | O | O | O | 커스텀 |
퍼블릭 DNS 리졸버
| 서비스 | Primary | Secondary | DoH | DoT | DNSSEC 검증 | 특징 |
|---|---|---|---|---|---|---|
| Google DNS | 8.8.8.8 | 8.8.4.4 | O | O | O | 가장 널리 사용 |
| Cloudflare | 1.1.1.1 | 1.0.0.1 | O | O | O | 가장 빠름 |
| Quad9 | 9.9.9.9 | 149.112.112.112 | O | O | O | 악성 도메인 차단 |
| OpenDNS | 208.67.222.222 | 208.67.220.220 | O | X | O | 필터링 옵션 |
| AdGuard DNS | 94.140.14.14 | 94.140.15.15 | O | O | O | 광고 차단 |
추천 시나리오별 선택
| 시나리오 | 추천 서비스 | 이유 |
|---|---|---|
| 개인 블로그/사이트 | Cloudflare (무료) | 무료 DNS + CDN + SSL |
| 스타트업 | Cloudflare Pro 또는 Route 53 | 확장성 + 안정성 |
| 대기업 | Route 53 + Cloudflare | 멀티 DNS + 지연 기반 라우팅 |
| 홈서버 | Cloudflare + DDNS | 무료 + 동적 IP 지원 |
| K8s 클러스터 | CoreDNS + External-DNS | 자동화된 DNS 관리 |
실전 퀴즈
Q1: DNS 쿼리에서 재귀적(Recursive) 쿼리와 반복적(Iterative) 쿼리의 차이는?
재귀적 쿼리: 클라이언트가 재귀 리졸버에게 최종 답을 요청합니다. 리졸버가 모든 중간 과정을 대신 처리하고 최종 IP 주소를 돌려줍니다.
반복적 쿼리: 재귀 리졸버가 각 단계의 네임서버(Root, TLD, Authoritative)에게 순서대로 질의합니다. 각 서버는 최종 답 대신 "다음에 물어볼 서버"를 안내합니다.
일반적으로 클라이언트 → 리졸버는 재귀적, 리졸버 → 네임서버들은 반복적 쿼리를 사용합니다.
Q2: 루트 도메인(Apex)에 CNAME 레코드를 설정할 수 없는 이유는?
RFC에 따르면 CNAME은 해당 이름에 대한 유일한 레코드여야 합니다. 즉, CNAME이 있으면 같은 이름에 다른 레코드(A, MX, NS, SOA 등)가 존재할 수 없습니다.
하지만 루트 도메인에는 반드시 SOA와 NS 레코드가 있어야 하므로, CNAME과 공존할 수 없어 설정이 불가능합니다.
대안으로 Cloudflare의 CNAME Flattening이나 일부 DNS 제공자의 ALIAS/ANAME 레코드를 사용할 수 있습니다.
Q3: TTL을 60초로 설정했는데 DNS 변경이 48시간이 지나도 반영되지 않는 이유는?
가능한 원인:
- TTL을 낮추기 전의 캐시가 아직 남아있을 수 있습니다. TTL 변경 자체도 이전 TTL 시간만큼 전파가 필요합니다.
- 일부 ISP DNS 서버는 자체적으로 최소 TTL을 강제합니다 (예: 최소 300초).
- 클라이언트의 OS나 브라우저 캐시가 DNS를 자체적으로 캐시합니다.
- 네임서버 자체를 변경한 경우, TLD 레벨에서 전파에 최대 48시간이 소요됩니다.
해결: DNS 변경 24시간 전에 TTL을 미리 낮춰두고, 변경 후에는 ipconfig /flushdns 등으로 로컬 캐시를 삭제합니다.
Q4: DNSSEC는 DNS 쿼리를 암호화하는 기술인가?
아닙니다. DNSSEC는 DNS 응답의 **무결성(Integrity)**과 **출처(Authenticity)**를 검증하는 기술이지, 암호화(Encryption) 기술이 아닙니다.
DNSSEC으로 보호된 DNS 응답도 여전히 평문으로 전송됩니다. 즉, DNS 쿼리 내용은 네트워크에서 여전히 볼 수 있습니다.
DNS 쿼리의 암호화(프라이버시)를 원하면 DNS over HTTPS(DoH) 또는 DNS over TLS(DoT)를 사용해야 합니다.
정리하면:
- DNSSEC = 응답 위변조 방지 (무결성)
- DoH/DoT = 쿼리 암호화 (프라이버시)
- 둘 다 사용하면 최적의 보안
Q5: K8s Pod에서 외부 도메인 api.external.com에 접속이 느린 이유와 해결 방법은?
원인: Kubernetes의 기본 DNS 설정에서 ndots:5로 인해, 점(.)이 5개 미만인 도메인은 search 도메인을 먼저 추가하여 조회합니다.
api.external.com은 점이 2개이므로, 실제 쿼리 순서는:
api.external.com.default.svc.cluster.local(NXDOMAIN)api.external.com.svc.cluster.local(NXDOMAIN)api.external.com.cluster.local(NXDOMAIN)api.external.com.(성공)
3번의 불필요한 쿼리 후에야 실제 해석이 됩니다.
해결 방법:
- FQDN 사용:
api.external.com.(마지막에 점 추가) - Pod의 dnsConfig에서 ndots를 낮은 값(예: 2)으로 설정
- 자주 접근하는 외부 도메인은 CoreDNS에 캐싱 규칙 추가
참고 자료
RFC 문서
- RFC 1034 - Domain Names - Concepts and Facilities
- RFC 1035 - Domain Names - Implementation and Specification
- RFC 2136 - Dynamic Updates in the DNS (DDNS)
- RFC 2181 - Clarifications to the DNS Specification
- RFC 2308 - Negative Caching of DNS Queries
- RFC 4033, 4034, 4035 - DNS Security Extensions (DNSSEC)
- RFC 6698 - DNS-Based Authentication (DANE/TLSA)
- RFC 7208 - SPF (Sender Policy Framework)
- RFC 7489 - DMARC
- RFC 8484 - DNS over HTTPS (DoH)
- RFC 7858 - DNS over TLS (DoT)
- RFC 8659 - DNS Certification Authority Authorization (CAA)
도구 및 서비스
- dig / nslookup - DNS 조회 명령줄 도구
- whatsmydns.net - 글로벌 DNS 전파 확인
- dnschecker.org - DNS 레코드 확인
- mxtoolbox.com - 이메일 DNS 진단 (SPF, DKIM, DMARC)
- securitytrails.com - DNS 히스토리 조회
- dnsviz.net - DNSSEC 시각화 및 검증
DNS 소프트웨어
- BIND9 - https://www.isc.org/bind/
- CoreDNS - https://coredns.io/
- PowerDNS - https://www.powerdns.com/
- Unbound - https://nlnetlabs.nl/projects/unbound/
- Knot DNS - https://www.knot-dns.cz/
학습 자료
- Cloudflare Learning Center - DNS 개념 (learning.cloudflare.com)
- howdns.works - DNS 동작 시각적 설명
- messwithdns.net - DNS 실습 환경
- Julia Evans - DNS 관련 블로그 및 zines