DNS 동작 원리: 리졸버, 권한 서버, 레코드, TTL
들어가며
서버를 새 IP로 옮기고 레코드도 바꿨는데, 일부 사용자만 계속 옛 서버로 접속하는 일이 있습니다. 내 PC에서는 새 서버가 뜨는데 동료 PC에서는 옛 서버가 뜨기도 합니다. 설정이 틀린 것이 아니라 DNS가 원래 그렇게 동작하기 때문입니다.
이번 글에서는 이름이 IP로 바뀌는 과정, 재귀 리졸버와 권한 네임서버의 역할, 자주 쓰는 레코드, TTL을 다루는 방법을 정리합니다.
1. 이름 공간은 나무 모양입니다
DNS는 도메인 이름을 IP 주소로 바꾸는 분산 시스템입니다. 모든 이름을 한 서버가 갖고 있지 않고, 오른쪽 끝부터 단계별로 관리를 위임합니다.
www.example.com 이라면 루트가 .com 을 맡은 서버를 알고, .com 서버가 example.com 을 맡은 서버를 압니다. 실제 레코드는 맨 아래 example.com 의 서버에만 있습니다.
DNS 계층은 본사 → 지역 지사 → 담당 부서로 내려가는 회사 조직도예요.
2. 조회 과정: 리졸버가 대신 묻습니다
조회에는 역할이 다른 두 종류의 서버가 등장합니다. 재귀 리졸버(recursive resolver)는 클라이언트 대신 여기저기 물어 최종 답을 가져오는 서버이고, 8.8.8.8이나 1.1.1.1, 통신사 DNS가 여기에 해당합니다. 권한 네임서버(authoritative name server)는 그 도메인 레코드의 원본을 갖고 답하는 서버입니다.
리졸버는 루트부터 차례로 묻고, 위쪽 서버들은 답 대신 다음에 물을 곳을 알려 줍니다. 클라이언트가 리졸버에 "최종 답을 달라"고 하는 것이 재귀 질의, 리졸버가 위쪽 서버에 한 단계씩 묻는 것이 반복 질의입니다.
재귀 리졸버는 큰 빌딩의 안내원이에요. 본부와 층 안내에 대신 물어 담당자를 찾아 줘요.
dig 로 두 역할을 나눠 물어 볼 수 있습니다. 응답 flags에 ra 가 있으면 재귀가 가능한 서버이고, aa 가 있으면 권한 있는 답입니다.
dig @8.8.8.8 www.example.com A # 리졸버에게 묻기 (flags 에 ra)
dig example.com NS +short # 이 도메인의 권한 서버 찾기
dig @ns1.example.com www.example.com A # 권한 서버에 직접 묻기 (flags 에 aa)
dig www.example.com +trace # 루트부터 차례로 따라가기3. 자주 쓰는 레코드
레코드는 이름에 붙는 정보 한 줄입니다. 서비스를 운영하면서 자주 만나는 것은 다음 정도입니다.
- A · AAAA: 이름을 IP로 바로 잇습니다. A는 IPv4, AAAA는 IPv6입니다.
- CNAME: 이름을 다른 이름으로 잇습니다. 리졸버는 그 이름을 다시 조회합니다.
- MX · TXT: MX는 메일을 받을 서버, TXT는 자유 문자열입니다. TXT는 도메인 소유 인증과 SPF에 씁니다.
- NS · SOA: NS는 이 영역의 권한 서버, SOA는 영역의 기본 정보입니다.
CNAME의 장점은 상대방 IP가 바뀌어도 내 설정을 고치지 않아도 된다는 점입니다. 호스팅 업체 도메인에 CNAME을 걸어 두면 IP 관리는 업체 몫이 됩니다. 대신 조회가 한 번 더 듭니다.
$ dig www.example.com +noall +answer
www.example.com. 300 IN CNAME app.host.net.
app.host.net. 60 IN A 203.0.113.7루트 도메인(example.com, apex라고도 합니다)에는 CNAME을 걸 수 없습니다. CNAME은 같은 이름에 다른 레코드와 함께 둘 수 없는데, 루트 도메인에는 NS와 SOA가 반드시 있기 때문입니다. 그래서 DNS 업체들은 ALIAS나 CNAME flattening이라는 기능으로, 서버 쪽에서 이름을 미리 풀어 A 레코드처럼 답합니다.
4. TTL: 변경이 바로 반영되지 않는 이유
DNS 응답에는 TTL(캐시 유효 시간, 초 단위)이 붙습니다. 리졸버, OS, 브라우저는 TTL이 끝날 때까지 받아 둔 답을 다시 묻지 않고 씁니다. 덕분에 조회가 빠르고 네임서버 부하도 줄지만, 레코드를 바꿔도 이미 캐시한 쪽은 옛 IP로 갑니다.
그래서 서버를 옮길 때는 순서가 있습니다. TTL이 하루(86400초)인 레코드라면, IP를 바꾸기 최소 하루 전에 TTL부터 300으로 낮춥니다. 옛 TTL을 들고 있는 캐시가 모두 사라진 뒤에 IP를 바꾸면 변경이 5분 안에 퍼집니다.
TTL 낮추기는 이사 전에 수첩 유효기간을 미리 줄여 달라고 알려 두는 일이에요.
# D-1: TTL 만 낮춘다 (IP 는 그대로)
api 300 IN A 203.0.113.10
# D-day: 옛 TTL(하루)이 지난 뒤 IP 변경
api 300 IN A 198.51.100.20
# 확인: 남은 TTL 이 줄어드는지 본다
dig api.example.com +noall +answerTTL을 지키지 않는 리졸버나 앱도 있습니다. 옛 서버는 IP를 바꾼 뒤에도 며칠 더 켜 두고, 접속이 사라지는지 확인한 다음 내립니다.
TTL을 계속 짧게 두면 조회가 잦아져 지연이 조금 늘고 네임서버 부하가 커집니다. 네임서버 장애 때 캐시가 버텨 주는 시간도 짧아집니다. 평소에는 길게, 이전 전에만 짧게 두는 경우가 많은 이유입니다.
헷갈리기 쉬운 점
- 공용 DNS가 모든 도메인의 정답을 갖고 있지는 않습니다. 8.8.8.8은 권한 서버에 물어 받아 온 답을 TTL 동안 캐시할 뿐입니다. 원본은 권한 네임서버에 있습니다.
- CNAME은 리다이렉트가 아닙니다. DNS 안에서 이름을 따라갈 뿐, 브라우저 주소창의 URL과 HTTP의 Host 헤더는 그대로입니다.
- 네임서버를 옮기는 일과 레코드를 고치는 일은 다릅니다. DNS를 다른 업체로 옮길 때는 등록기관에서 NS를 바꿔야 합니다. 그 전까지는 새 업체 대시보드에 적은 레코드를 아무도 묻지 않습니다.
면접에서 자주 받는 질문
DNS는 TCP인가요, UDP인가요?
기본은 UDP 53번입니다. 응답이 UDP에 담기지 않을 만큼 크거나 존 전송을 할 때는 TCP를 씁니다. 최근에는 조회 내용을 암호화하는 DoH(HTTPS 위의 DNS)와 DoT(TLS 위의 DNS)도 널리 쓰입니다.
한 이름에 A 레코드가 여러 개면 어떻게 되나요?
리졸버가 여러 IP를 함께 돌려주고, 순서를 돌려 가며 주기도 합니다(라운드 로빈 DNS). 어느 IP를 쓸지는 클라이언트가 고르므로 정교한 부하 분산은 아닙니다. 죽은 서버의 IP도 TTL 동안 계속 나갈 수 있습니다.
DNS 리바인딩은 무엇인가요?
아주 짧은 TTL을 걸어, 검사할 때는 외부 IP를, 실제 접속할 때는 내부 IP를 답하게 만드는 공격입니다. 서버가 사용자 대신 URL을 가져오는 기능이라면 이름이 아니라 풀린 IP 전부를 검사하고, 검사한 IP로 그대로 접속하도록 고정하면 막을 수 있습니다.
정리
- 재귀 리졸버는 대신 물어 답을 캐시하고, 권한 네임서버는 레코드의 원본을 갖습니다.
- A는 이름을 IP로, CNAME은 이름을 다른 이름으로 잇습니다. 루트 도메인에는 CNAME을 둘 수 없습니다.
- TTL은 IP를 바꾸기 전에, 옛 TTL만큼 먼저 낮춥니다.
리졸버는 대신 묻고 메모하는 안내원이고, TTL은 그 메모의 유효기간입니다. 이 두 가지만 기억해도 "왜 나만 옛 서버로 가지?"라는 상황을 대부분 설명할 수 있습니다.