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"
은 여기"
**전체 흐름 상세:**
1. 사용자가 브라우저에 `www.example.com` 입력
2. 브라우저 캐시 확인 → OS 캐시 확인 → hosts 파일 확인
3. OS가 설정된 재귀 리졸버(예: 8.8.8.8)에 재귀적 쿼리 전송
4. 재귀 리졸버가 캐시 확인 → 없으면 Root 서버에 반복적 쿼리
5. Root 서버: "`.com` TLD 서버는 `a.gtld-servers.net`이야"
6. 재귀 리졸버가 TLD 서버에 쿼리
7. TLD 서버: "`example.com`의 네임서버는 `ns1.example.com`이야"
8. 재귀 리졸버가 권한 있는 네임서버에 쿼리
9. 권한 있는 네임서버: "`www.example.com`의 IP는 `93.184.216.34`야"
10. 재귀 리졸버가 결과를 캐싱하고 클라이언트에 응답
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 관리 |
실전 퀴즈
**재귀적 쿼리:**
클라이언트가 재귀 리졸버에게 최종 답을 요청합니다. 리졸버가 모든 중간 과정을 대신 처리하고 최종 IP 주소를 돌려줍니다.
**반복적 쿼리:**
재귀 리졸버가 각 단계의 네임서버(Root, TLD, Authoritative)에게 순서대로 질의합니다. 각 서버는 최종 답 대신 "다음에 물어볼 서버"를 안내합니다.
일반적으로 클라이언트 → 리졸버는 재귀적, 리졸버 → 네임서버들은 반복적 쿼리를 사용합니다.
RFC에 따르면 CNAME은 해당 이름에 대한 유일한 레코드여야 합니다. 즉, CNAME이 있으면 같은 이름에 다른 레코드(A, MX, NS, SOA 등)가 존재할 수 없습니다.
하지만 루트 도메인에는 반드시 SOA와 NS 레코드가 있어야 하므로, CNAME과 공존할 수 없어 설정이 불가능합니다.
대안으로 Cloudflare의 CNAME Flattening이나 일부 DNS 제공자의 ALIAS/ANAME 레코드를 사용할 수 있습니다.
가능한 원인:
1. TTL을 낮추기 전의 캐시가 아직 남아있을 수 있습니다. TTL 변경 자체도 이전 TTL 시간만큼 전파가 필요합니다.
2. 일부 ISP DNS 서버는 자체적으로 최소 TTL을 강제합니다 (예: 최소 300초).
3. 클라이언트의 OS나 브라우저 캐시가 DNS를 자체적으로 캐시합니다.
4. 네임서버 자체를 변경한 경우, TLD 레벨에서 전파에 최대 48시간이 소요됩니다.
**해결:** DNS 변경 24시간 전에 TTL을 미리 낮춰두고, 변경 후에는 `ipconfig /flushdns` 등으로 로컬 캐시를 삭제합니다.
아닙니다. DNSSEC는 DNS 응답의 **무결성(Integrity)**과 **출처(Authenticity)**를 검증하는 기술이지, **암호화(Encryption)** 기술이 아닙니다.
DNSSEC으로 보호된 DNS 응답도 여전히 평문으로 전송됩니다. 즉, DNS 쿼리 내용은 네트워크에서 여전히 볼 수 있습니다.
DNS 쿼리의 암호화(프라이버시)를 원하면 DNS over HTTPS(DoH) 또는 DNS over TLS(DoT)를 사용해야 합니다.
정리하면:
- DNSSEC = 응답 위변조 방지 (무결성)
- DoH/DoT = 쿼리 암호화 (프라이버시)
- 둘 다 사용하면 최적의 보안
**원인:** Kubernetes의 기본 DNS 설정에서 ndots:5로 인해, 점(.)이 5개 미만인 도메인은 search 도메인을 먼저 추가하여 조회합니다.
`api.external.com`은 점이 2개이므로, 실제 쿼리 순서는:
1. `api.external.com.default.svc.cluster.local` (NXDOMAIN)
2. `api.external.com.svc.cluster.local` (NXDOMAIN)
3. `api.external.com.cluster.local` (NXDOMAIN)
4. `api.external.com.` (성공)
3번의 불필요한 쿼리 후에야 실제 해석이 됩니다.
**해결 방법:**
1. FQDN 사용: `api.external.com.` (마지막에 점 추가)
2. Pod의 dnsConfig에서 ndots를 낮은 값(예: 2)으로 설정
3. 자주 접근하는 외부 도메인은 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
현재 단락 (1/652)
DNS(Domain Name System)는 사람이 읽을 수 있는 도메인 이름(예: `www.example.com`)을 컴퓨터가 이해하는 IP 주소(예: `93.184.216.34...