DNS 레코드와 실습
DNS 서버가 도메인에 대한 정보를 저장한다는 것을 알았습니다. 이제 그 정보가 어떤 리소스 레코드(Resource Record) 형태로 표현되는지, 그리고 nslookup과 dig으로 직접 확인하는 방법을 살펴보겠습니다.
주요 DNS 레코드 유형
DNS 레코드는 “도메인 이름에 연결된 데이터”입니다. 표준적인 리소스 레코드는 보통 이름, TTL, 클래스, 타입, 데이터로 읽습니다. 예를 들어 example.com. 3600 IN A 93.184.216.34는 example.com 이름의 IPv4 주소를 3600초 동안 캐시할 수 있다는 뜻입니다.
가장 자주 만나는 레코드 유형은 아래와 같습니다.
| 레코드 | 용도 | 예시 | 읽을 때 주의할 점 |
|---|---|---|---|
| A | 이름 → IPv4 주소 | example.com. A 93.184.216.34 | 하나의 이름에 여러 A가 있을 수 있음 |
| AAAA | 이름 → IPv6 주소 | example.com. AAAA 2606:2800:220:1:: | IPv6 주소용 레코드 |
| CNAME | 별칭 이름 → canonical name | www CNAME example.com. | 같은 이름에 일반 레코드와 공존 불가 |
| MX | 메일 교환 서버 지정 | example.com. MX 10 mail.example.com. | 숫자가 낮을수록 우선순위가 높음 |
| NS | 영역의 권한 네임서버 지정 | example.com. NS ns1.example.com. | 위임과 권한 서버 확인에 사용 |
| TXT | 텍스트 기반 정책/검증 정보 | v=spf1 include:_spf.example.net -all | SPF, DKIM, DMARC 등 형식별 규칙 확인 필요 |
| SRV | 서비스 위치와 포트 지정 | _sip._tcp.example.com. SRV 10 60 5060 host | 지원하는 프로토콜에서만 의미가 있음 |
| SOA | 영역 시작과 관리 메타데이터 | ns1.example.com. hostmaster.example.com. | serial, refresh, retry, expire 포함 |
| PTR | 역방향 이름 → canonical name | 34.216.184.93.in-addr.arpa. PTR ... | IP 소유자가 관리하는 역방향 영역 필요 |
| CAA | 인증서 발급 가능한 CA 제한 | example.com. CAA 0 issue "letsencrypt.org" | CA의 오발급 위험을 줄이는 정책 |
CNAME의 제약과 대안
CNAME은 별칭을 만들 때 편하지만, 같은 이름에 다른 일반 레코드와 함께 둘 수 없습니다. 예를 들어 zone apex인 example.com에는 보통 SOA와 NS가 반드시 필요하므로 표준 DNS 관점에서 example.com CNAME ... 형태는 맞지 않습니다.
클라우드 DNS 서비스의 ALIAS, ANAME, CNAME flattening, Route 53 Alias 같은 기능은 이 제약을 우회하기 위한 제공자별 기능입니다. 이것들은 표준 CNAME 레코드라기보다 권한 DNS 서버가 대상 이름을 해석한 뒤 A/AAAA 응답처럼 돌려주는 방식에 가깝습니다.
MX 레코드와 이메일 보안 레코드
MX 레코드는 메일을 어느 서버로 전달할지 알려줍니다. MX의 숫자는 “선호도(preference)”이며, 낮은 숫자가 먼저 시도됩니다. 같은 선호도의 MX가 여러 개라면 메일 전송 서버는 그 후보들을 나누어 시도할 수 있습니다.
이메일 보안에서는 TXT 레코드를 정책 저장소처럼 많이 사용합니다. 단, TXT는 단순한 문자열 컨테이너일 뿐이고, SPF/DKIM/DMARC는 각각 별도 규칙을 가진 프로토콜입니다.
| 항목 | DNS 위치 예시 | 하는 일 | 자주 나는 실수 |
|---|---|---|---|
| SPF | example.com TXT "v=spf1 ..." | envelope sender 도메인의 허용 발신원 선언 | 같은 이름에 SPF 레코드를 여러 개 게시 |
| DKIM | selector._domainkey.example.com | 공개키로 메일 서명 검증 | selector 이름이나 긴 TXT 문자열 오류 |
| DMARC | _dmarc.example.com TXT "v=DMARC1" | SPF/DKIM alignment와 정책, 리포트 주소 선언 | SPF/DKIM과 From 도메인 alignment 혼동 |
nslookup과 dig 실습
DNS 레코드를 직접 조회할 때는 nslookup과 dig을 많이 사용합니다. nslookup은 기본 확인에 편하고, dig은 응답 섹션, 플래그, TTL, 권한 서버 추적을 더 자세히 보여줍니다.
# 기본 A 레코드 조회
nslookup example.com
# 특정 레코드 유형 조회
nslookup -type=MX example.com
nslookup -type=TXT example.com
nslookup -type=NS example.com
nslookup -type=AAAA example.com
# 특정 DNS 서버를 지정하여 조회
nslookup example.com 1.1.1.1
# 역방향 DNS 조회
nslookup 93.184.216.34# A 레코드 조회
dig example.com A
# 특정 레코드 유형 조회
dig example.com MX
dig example.com NS
dig example.com TXT
dig example.com AAAA
# 간결한 출력
dig +short example.com A
# 특정 리졸버 지정
dig @1.1.1.1 example.com A
# 권한 서버 경로 추적
dig +trace example.com
# 역방향 DNS
dig -x 93.184.216.34Non-authoritative answer는 응답이 해당 영역의 권한 서버에서 직접 온 것이 아니라 재귀 리졸버를 통해 온 응답이라는 뜻입니다. 꼭 “오래된 캐시”라는 뜻은 아니므로, 원본 상태를 확인하려면 dig +trace나 권한 NS 직접 조회를 함께 봐야 합니다.
TTL과 DNS 캐시 동작
DNS 응답의 TTL(Time To Live)은 해당 레코드를 캐시에 얼마나 오래 보관할 수 있는지 초 단위로 나타냅니다. TTL이 길면 반복 질의가 줄어 안정적이지만 변경 반영이 느리고, TTL이 짧으면 전환은 빠르지만 리졸버와 권한 서버 질의량이 늘어납니다.
import socket
def resolve_all(domain):
"""운영체제 리졸버를 통해 IPv4/IPv6 후보를 확인하는 간단한 예시"""
results = socket.getaddrinfo(domain, 80, type=socket.SOCK_STREAM)
seen = set()
for family, _, _, _, address in results:
ip = address[0]
if ip in seen:
continue
seen.add(ip)
version = "IPv6" if family == socket.AF_INET6 else "IPv4"
print(f"{domain:<24} {version:<4} {ip}")
resolve_all("example.com")캐시는 리졸버뿐 아니라 운영체제와 브라우저에도 존재합니다. DNS 변경 후 예상과 다른 응답을 보면 브라우저 캐시, OS 캐시, 재귀 리졸버 캐시, 권한 서버 원본 레코드를 분리해서 확인해야 합니다. 존재하지 않는 이름(NXDOMAIN)도 SOA 정보와 함께 negative caching 될 수 있습니다.
DNS 실습 체크리스트
| 상황 | 명령어 | 확인 사항 |
|---|---|---|
| 기본 IP 조회 | dig example.com A | ANSWER 섹션의 A 레코드와 TTL |
| IPv6 조회 | dig example.com AAAA | AAAA 응답 여부 |
| 메일 서버 확인 | dig example.com MX | 낮은 preference 우선, MX target |
| 네임서버 확인 | dig example.com NS | 위임된 권한 서버 |
| 이메일 인증 확인 | dig example.com TXT | SPF, DKIM, DMARC 위치별 TXT |
| 해석 경로 추적 | dig +trace example.com | 루트 → TLD → 권한 서버 |
| 특정 리졸버 비교 | dig @1.1.1.1 example.com A | 리졸버별 캐시/응답 차이 |
| 권한 서버 직접 확인 | dig @ns1.example.com name A | 원본 레코드와 재귀 응답 차이 |
| 로컬 캐시 초기화 | ipconfig /flushdns | Windows OS DNS 캐시 제거 |
다음 절에서는 DNS의 심화 활용과 실무에서 마주치는 보안 이슈를 살펴보겠습니다.