DNS는 domain name을 IP address로 바꿔주는 시스템입니다. 사용자가 example.com에 접속하면 browser는 먼저 cache를 확인하고, 없으면 OS나 configured DNS resolver에 질의합니다. resolver는 필요하면 root name server, TLD server, authoritative name server를 차례로 찾아가 해당 domain의 record를 얻습니다.
결과는 TTL 동안 cache될 수 있어 다음 요청은 더 빠르게 처리됩니다. 웹 요청은 보통 DNS lookup 이후 TCP/TLS 연결, HTTP 요청 순서로 이어집니다.
DNS가 계층 구조인 이유는 규모와 관리 위임 때문입니다. 전 세계 모든 domain을 한 서버가 관리하면 트래픽도 감당할 수 없고 단일 장애점이 됩니다. 그래서 root는 "com은 저쪽에 물어봐"만 알려주고, com TLD 서버는 "example.com은 저쪽"만 알려주는 식으로 각 계층이 바로 아래 단계의 위치만 위임(delegation)합니다. 각 조직은 자기 domain의 record를 자기 authoritative server에서 직접 관리합니다.
resolver라는 이름은 서로 다른 두 역할에 함께 쓰여 헷갈리기 쉽습니다. 사용자 쪽의 recursive resolver(보통 ISP나 8.8.8.8 같은 공개 resolver)는 root부터 authoritative까지 대신 순회하며 답을 완성해 주는 대리인이고, 각 name server는 자기가 아는 부분만 답하는 iterative 응답을 합니다. cache가 대부분 recursive resolver에 쌓이기 때문에, 같은 domain을 묻는 두 번째 사용자부터는 root까지 갈 일이 거의 없습니다.
꼬리질문
조금 더 깊게 물어본다면
답변 뒤에 이어질 수 있는 질문들을 하나씩 열어볼 수 있어요.
TTL은 무엇인가요?
DNS record를 cache해도 되는 시간을 의미합니다. TTL이 길면 lookup 비용은 줄지만 IP 변경이 반영되는 데 시간이 걸릴 수 있습니다.
서비스 이전이나 장애 대응에서는 TTL 설정이 중요해질 수 있습니다.
TTL의 트레이드오프가 실제로 드러나는 상황이 서버 이전입니다. TTL이 86400(24시간)인 상태에서 IP를 바꾸면, 이미 cache된 resolver들은 최대 하루 동안 옛 주소로 트래픽을 보냅니다. 그래서 이전 계획이 잡히면 미리 TTL을 60초 수준으로 낮춰 두고, 이전이 끝나 안정되면 다시 올리는 순서로 운영합니다. TTL을 낮추는 변경 자체도 기존 TTL이 만료되어야 퍼지므로, 최소 기존 TTL만큼 앞서 해야 합니다.
TTL을 계속 낮게 두지 않는 이유는 비용입니다. cache 적중률이 떨어져 authoritative server의 질의량이 늘고, 사용자 입장에서도 lookup이 자주 발생해 latency가 늘어납니다. 참고로 "그 domain은 없다"는 부정 응답도 cache되는데(negative caching), 이 때문에 record를 만들기 전에 질의해 본 domain은 생성 직후에도 한동안 없는 것으로 보일 수 있습니다.
CNAME은 무엇인가요?
한 domain name을 다른 domain name의 alias로 지정하는 record입니다. 최종적으로는 A나 AAAA record를 통해 IP로 해석됩니다.
CDN이나 외부 서비스 연결에서 자주 볼 수 있습니다.
CNAME이 유용한 이유는 IP를 직접 아는 책임을 상대에게 넘길 수 있기 때문입니다. www.example.com을 CDN의 xxxx.cdn-provider.net으로 CNAME 연결해 두면, CDN이 내부적으로 서버 IP를 바꾸거나 지역별로 다른 IP를 주더라도 내 zone은 손댈 필요가 없습니다. A record로 IP를 직접 적었다면 상대가 IP를 바꿀 때마다 따라 바꿔야 합니다.
제약도 있습니다. CNAME이 있는 이름에는 다른 record를 둘 수 없다는 규칙 때문에, SOA와 NS record가 반드시 있는 zone apex(example.com 자체)에는 CNAME을 걸 수 없습니다. 그래서 apex를 CDN에 연결하려는 수요를 위해 DNS 제공자들이 ALIAS, ANAME 같은 비표준 record를 만들었습니다. 조회 시점에 제공자가 대신 해석해 A record처럼 응답하는 방식입니다.
DNS lookup은 성능에 영향을 주나요?
영향을 줍니다. 새로운 domain에 접근할 때 DNS lookup 시간이 추가됩니다. 다만 cache, preconnect, dns-prefetch 같은 브라우저 최적화로 줄일 수 있습니다.
외부 resource domain이 많으면 초기 연결 비용이 늘 수 있습니다.
cache miss가 난 DNS lookup은 수십에서 수백 ms까지 걸릴 수 있고, 이 시간 동안 브라우저는 해당 domain의 리소스를 아무것도 받지 못합니다. 페이지가 폰트, 분석 스크립트, CDN 이미지 등 여러 외부 domain을 쓰면 domain마다 lookup과 연결 수립이 반복됩니다.
브라우저 힌트 두 가지는 미리 해 두는 범위가 다릅니다. dns-prefetch는 DNS 해석만 미리 해 두고, preconnect는 DNS에 더해 TCP handshake와 TLS handshake까지 미리 끝내 둡니다. preconnect가 더 많이 아끼지만 연결 유지 비용이 있으므로, 확실히 곧 쓸 소수의 domain에는 preconnect, 쓸 가능성만 있는 domain에는 dns-prefetch를 거는 식으로 나눠 씁니다.
DNS는 보안상 어떤 문제가 있나요?
DNS spoofing, cache poisoning 같은 공격이 가능합니다. DNSSEC은 record의 무결성을 검증하기 위한 확장입니다.
또 HTTPS 연결에서는 DNS 이후 인증서 검증과 TLS handshake도 중요합니다.
cache poisoning이 성립하는 이유는 전통적인 DNS가 UDP 기반이고 응답을 검증할 방법이 질의 ID 정도뿐이기 때문입니다. 공격자가 resolver의 질의에 대해 authoritative server보다 먼저 위조 응답을 보내는 데 성공하면, resolver는 가짜 IP를 TTL 동안 cache하고 그 기간의 모든 사용자를 공격자 서버로 보냅니다. 질의 ID와 source port를 무작위화해 위조 난이도를 높였지만 근본 해결은 아닙니다.
근본 대책이 record에 전자 서명을 붙여 위변조를 검증하는 DNSSEC입니다. 다만 DNSSEC은 무결성(내용이 바뀌지 않았는지)만 보장하고 질의 내용 자체는 평문으로 노출됩니다. 질의를 암호화해 도청과 중간 조작을 막는 것은 DoH(DNS over HTTPS)와 DoT(DNS over TLS)의 역할로, 해결하는 문제가 서로 다릅니다.
부가 설명
Browser cache-> OS cache-> Recursive resolver-> Root DNS-> TLD DNS-> Authoritative DNS-> IP address
실제로는 cache 때문에 매번 이 모든 과정을 거치지 않습니다.
DNS record에는 A, AAAA, CNAME, MX, TXT 등 여러 종류가 있습니다. 웹 접속에서는 IPv4 주소를 가리키는 A record, IPv6 주소를 가리키는 AAAA record, 다른 domain alias를 가리키는 CNAME record를 자주 봅니다.
DNS는 단순한 주소록이 아니라 cache와 resolver 흐름을 포함하는 분산 naming system입니다.
한 줄 정리
DNS는 domain을 IP로 바꾸는 계층적 이름 해석 시스템이고, cache와 TTL이 성능과 운영에 큰 영향을 줍니다.