← 모든 글
Computer Science
시리즈 · 한 요청의 여정 · 2/2

Step0 : DNS Resolution

`google.com` 은 어떻게 `142.251.118.102` 로 변경될까?

by rati·

들어가기 앞서 - 계층 구조.

OSI 7계층과 TCP/IP 4계층의 대응. L5부터 L7은 실제로 Chrome과 OS 서비스 안에서 한데 섞여 있고 TCP/IP는 이를 응용 계층 하나로 본다. PDU를 누르면 구조를 볼 수 있어요.TCP/IPOSI MODEL이 PC에서 일어나는 일PDU?PDU는 눌러서 설명, 아래 칸은 구조Application5~7계층을 하나로TransportInternetLink7Application응용6Presentation표현5Session세션4Transport전송Segment / DatagramUDP 헤더 붙이기포트 53012 to 533Network네트워크PacketIP 헤더 붙이기서브넷 판단, 다음 홉 결정2Data Link데이터 링크FrameARP로 MAC 확인Ethernet 프레임으로 감싸기1Physical물리BitNIC가 프레임을전기, 광, 전파 신호로 변환DataChrome과 OS 서비스 안에서 한데 섞여 동작응용URL 판단, DNS 질의 만들기, 캐시 확인표현평문 DNS는 할 일이 거의 없음 (HTTPS면 TLS)세션재시도 타이머 같은 대화 상태 관리위에서 아래로 내려갈수록 계층마다 헤더가 붙고(캡슐화), 이름도 Data, Segment, Packet, Frame, Bit로 바뀌어요.
  • 그림의 PDU를 누르면 PDU가 무엇인지 설명이 열리고, 각 PDU 이름(Segment, Packet 등)을 누르면 그 구조를 볼 수 있어요.
  • PDU 구조의 각 칸에 마우스를 올리면 그 항목의 설명이 보여요.

Chrome 주소창에 google.com을 치고 엔터를 누르면 요청이 서버까지 가요. 그런데 서버에 연결하려면 그 전에 이름을 IP로 바꿔야 해요. 이 글은 그 과정을 PC 안에서 시작해 google.com의 IP를 얻어 돌아오기까지 따라가요.

응용 계층: 먼저 IP를 알아내야 해요

URL인지 검색어인지 판단해요

주소창(omnibox)은 입력이 검색어인지 URL인지 먼저 판단해요. google.com은 도메인 형태라서 URL로 보고, 스킴이 없으면 기본으로 https://를 붙여 시도해요.

왜 바로 연결하지 못할까요

네트워크 계층은 이름을 모르고 IP 주소만 알아요. 패킷 헤더에는 google.com이 아니라 142.250.x.x 같은 숫자가 들어가요. 그래서 이름을 숫자로 바꾸는 단계가 반드시 앞에 필요해요. 이 일을 하는 것이 DNS(Domain Name System)예요.

밖에 묻기 전에 PC 안부터 확인해요

DNS 질의는 네트워크 왕복 한 번이라 비싸요. 같은 사이트에 계속 접속하는데 매번 물으면 느리기 때문에, 먼저 PC 안에서 답을 찾아요.

  1. Chrome 자체 DNS 캐시 (브라우저 프로세스 안)
  2. OS의 DNS 캐시 (Windows에서는 DNS Client 서비스)
  3. hosts 파일 (사람이 직접 적어 둔 이름과 IP 대응표)

여기서 NIC는 등장하지 않아요. NIC는 자기 MAC 주소를 알고 프레임을 신호로 바꿔 내보내고 받을 뿐이고, 이름과 IP의 대응표는 갖고 있지 않아요.

캐시는 영원히 믿을 수 없어요: TTL

캐시된 IP가 영원히 맞을 수는 없어요. 구글이 서버 IP를 바꾸면 옛 값이 문제를 일으켜요. 그래서 캐시에는 보존 기간이 함께 저장돼요. 이것이 **TTL(Time To Live)**이에요.

  • 도메인 소유자의 Authoritative Name Server가 레코드마다 “이 답은 N초 동안만 믿어라”라고 정해 응답에 실어 보내요.
  • 캐시는 시간이 지날수록 이 값을 줄이고, 0이 되면 버리고 다시 물어봐요.
  • TTL이 짧으면 IP 변경이 빨리 반영되지만 질의가 늘고, 길면 반대예요.
  • Chrome은 TTL과 별개로 자체 상한도 둬요. 그래서 브라우저와 OS의 캐시 상태가 다를 수 있어요.

캐시에 없으면 누구에게 물을까요

세 곳 모두 없으면 PC는 자기에게 설정된 DNS 서버에 질의를 보내요.

  • 이 주소는 네트워크에 연결할 때 DHCP가 IP, 서브넷 마스크, 기본 게이트웨이와 한 묶음으로 알려줘요. 직접 입력해 고정하는 경우도 있어요.
  • 가정에서는 DNS 서버 설정값이 공유기 IP(예: 192.168.0.1)인 경우가 많아요. 공유기는 직접 답하거나, 캐시가 없으면 ISP나 8.8.8.8 같은 상위 DNS 서버로 전달하는 중계자예요.
  • DNS 서버 주소는 이름이 아니라 IP로 적혀 있어야 해요. DNS를 알려고 DNS를 쓸 수는 없기 때문이에요.
  • Chrome의 보안 DNS(DoH)가 켜져 있으면 OS와 공유기를 건너뛰고 Chrome이 HTTPS로 DNS 서버에 직접 물어요.

이 글은 평문 DNS를 기준으로 해요.

전송 계층: DNS는 왜 UDP를 쓸까요

DNS 질의 메시지(google.com의 A 레코드?)가 완성되어 전송 계층으로 내려와요. 전송 계층에는 TCP와 UDP가 있고, DNS는 기본으로 UDP 53번을 써요.

비교 TCP UDP
지연 (왕복 횟수) 2번: handshake 1번, 질문과 답 1번 1번: 질문과 답
패킷 수 (대략) 약 10개: SYN, SYN+ACK, ACK, 질문, 답, ACK들, FIN 4개 2개: 질문, 답
서버 부담 클라이언트마다 연결 상태를 유지 상태 없이 받고 답만 함

질문이 수십 바이트이고 한 번에 끝나는데 연결을 만들고 닫는 비용이 더 커요. 체감 지연은 절반, 패킷 수는 약 1/5이에요. 웹페이지 하나를 열 때 DNS 질의는 수십 번 나가기도 해서 이 차이가 쌓여요.

패킷이 사라지면 누가 다시 보낼까요

UDP는 재전송을 해 주지 않아요. 대신 UDP 위의 응용 계층이 해요. 질의를 보낸 쪽(Windows의 DNS Client 서비스나 Chrome)이 타이머를 걸어 두고, 시간 안에 답이 없으면 다시 보내요. 계속 실패하면 설정된 다른 DNS 서버로 바꿔 물어봐요.

TCP는 재전송을 전송 계층이 대신하고, UDP는 응용 계층이 자기 상황에 맞게 직접 해요. 질문이 작고 재시도가 싸면 후자가 이득이에요.

TCP도 쓰이는 경우

  • 응답이 UDP 메시지에 담기에 너무 커서 잘렸다는 표시(TC 플래그)가 오면, 같은 질의를 TCP로 다시 보내요.
  • 존 전송(zone transfer)처럼 데이터가 큰 경우에도 써요.
  • DNS over TLS(DoT)는 TCP 853번을 써요.

UDP 헤더

UDP 헤더는 8바이트이고 출발지 포트, 목적지 포트, 길이, 체크섬으로 이루어져요.

  • 목적지 포트: DNS 서버의 53
  • 출발지 포트: OS가 고르는 임시(ephemeral) 번호예요. 예를 들어 53012

출발지 포트는 왜 필요할까요. 지금 PC에서 Chrome과 PowerShell이 동시에 DNS 질의를 보냈다고 해 볼게요. 두 질의 모두 목적지는 192.168.0.1:53이고, 답이 돌아올 때 목적지 IP는 둘 다 내 PC예요.

  • IP는 PC까지 데려다줘요. 아파트 단지 주소 같은 거예요.
  • 포트는 PC 안의 어느 프로그램에게 줄지 정해요. 동과 호수 중 호수 같은 거예요.

Chrome이 53012로, PowerShell이 53099로 보냈다면 답의 목적지 포트로 OS가 소켓을 구분해요. 포트가 없으면 두 답이 섞여요.

네트워크 계층: 같은 동네일까요, 게이트웨이에 맡길까요

IP 헤더에는 이런 값이 들어가요.

  • 출발지 IP: 내 PC 192.168.0.10
  • 목적지 IP: DNS 서버 192.168.0.1
  • 프로토콜: UDP (17)
  • TTL: 보통 64부터 시작해 라우터를 지날 때마다 1씩 줄어들어요

패킷을 내보내기 전에 OS는 하나를 판단해요. 목적지가 나와 같은 동네(같은 로컬 네트워크)에 있을까? 이 판단에 필요한 것이 서브넷 마스크예요. DHCP가 IP와 함께 줘요.

내 IP         192.168.0.10
서브넷 마스크   255.255.255.0   (= /24)

/24는 “IP 32비트 중 앞 24비트가 동네 번호, 뒤 8비트가 그 동네 안의 호수”라는 뜻이에요. 목적지의 동네 번호가 내 동네 번호와 같은지 비교해요.

목적지 동네 번호 비교 결정
192.168.0.1 (DNS, 공유기) 192.168.0으로 같음 같은 링크에 있는 그 장치에게 직접 보내요
142.250.206.78 (구글 서버) 142.250.206으로 다름 기본 게이트웨이(공유기)에게 맡겨요

게이트웨이에 맡겨도 바뀌지 않는 것

가장 흔한 오해예요. 게이트웨이에 맡길 때도 IP 헤더의 목적지는 계속 구글 IP(142.250.206.78)예요. 바뀌는 것은 한 계층 아래인 데이터 링크 계층에서 “이 프레임을 다음에 받을 장치”예요. 이어서 데이터 링크 계층을 볼게요.

이번 DNS 질의는 공유기가 DNS 서버이므로 직접 보내는 경우예요.

데이터 링크 계층: ARP로 다음 장치의 MAC을 알아내요

Ethernet 프레임에는 목적지 MAC 주소가 필요해요. PC는 192.168.0.1의 IP는 알지만 MAC은 몰라요. 이때 **ARP(Address Resolution Protocol)**를 써요. DNS가 “이름 to IP”의 번역이라면 ARP는 “IP to MAC”의 번역이에요.

먼저 ARP 캐시를 봐요

DNS와 같은 패턴이에요. 이미 아는 매핑이면 여기서 끝나요.

캐시에 없으면 동네 전체에 외쳐요

그런데 질문도 프레임에 담아야 하고, 프레임에는 목적지 MAC이 필요해요. 그 MAC을 모르는 것이 지금 문제이므로, 특별한 목적지 MAC인 브로드캐스트를 써요.

ARP Request (Ethernet 프레임)
  목적지 MAC : ff:ff:ff:ff:ff:ff       동네 모두에게
  출발지 MAC : 내 PC MAC
  내용(ARP)  : 192.168.0.1 가진 사람, MAC 알려줘.
               내 IP는 192.168.0.10, MAC은 (내 MAC)
  • 같은 로컬 네트워크의 모든 장치가 이 프레임을 받아요.
  • 대부분은 “내 IP가 아니네” 하고 무시해요.
  • 192.168.0.1의 주인(공유기)만 나에게만 직접(유니캐스트) 답해요. 질문 안에 내 MAC이 들어 있기 때문에 가능해요.
  • PC는 답을 ARP 캐시에 저장하고, 보류해 둔 DNS 패킷을 이제 내보내요.

완성된 프레임

Ethernet 프레임
  목적지 MAC : 공유기 MAC
  출발지 MAC : 내 PC MAC
  타입       : 0x0800 (IPv4)
  내용       : IP 패킷 안에 UDP 데이터그램(DNS 질의)
  FCS        : 오류 검출용 CRC

물리 계층: NIC가 신호로 내보내요

  1. 커널이 메모리에 만든 프레임을 NIC가 DMA로 가져가요. CPU가 한 바이트씩 옮기지 않아요.
  2. 프레임 끝에 오류 검출용 FCS(CRC)를 붙여요. 이 계산은 보통 NIC 하드웨어가 해요.
  3. 비트를 전기 신호(구리선), 광 신호(광케이블), 전파(Wi-Fi)로 바꿔 내보내요.

여기까지가 “내 PC에서 NIC까지”예요. 지금부터는 이 프레임이 공유기에 도착한 뒤, 이름이 IP가 되어 돌아오기까지를 따라가요.

공유기: 질의를 받은 뒤

공유기가 DNS 질의를 받으면 먼저 자기 캐시를 봐요.

  • 직접 답하는 경우: 이전에 같은 이름을 물어 캐시에 남아 있고 TTL이 아직 지나지 않았을 때예요. 공유기가 스스로 아는 이름(자기 호스트명 등)도 직접 답해요.
  • 직접 답할 수 없는 경우: 질의를 상위 DNS 서버로 전달해요.

상위 DNS 서버의 주소는 어디서 올까요

PC가 DHCP로 DNS 서버 주소를 받았듯이, 공유기의 WAN 쪽도 ISP에서 IP를 받을 때(DHCP나 PPPoE) 기본 게이트웨이와 DNS 서버 주소를 함께 받아요. 같은 방식이 한 단계 위에서 반복돼요. 사용자가 8.8.8.8 같은 공용 DNS로 직접 바꿔 두기도 해요.

질의를 받는 대상은 ISP의 라우터가 아니라 **ISP가 운영하는 DNS 서버(재귀 리졸버)**예요.

전달은 NAT 변환과 달라요

공유기 안의 DNS 포워더(dnsmasq 같은 프로그램이에요. 구현은 제품마다 달라요)가 자기 이름으로 새 질의를 만들어 보내요. 새 질의 ID를 쓰고, 출발지 IP는 공유기의 공인 IP이고, 출발지 포트도 새로 골라요. 답을 받으면 PC가 보냈던 질의에 맞춰 다시 응답해요.

NAT는 같은 패킷의 출발지 주소와 포트만 바꿔 전달하는 것이라 이것과 달라요. 일부 공유기는 PC에게 DHCP로 ISP의 DNS 주소를 바로 알려줘서, PC가 공유기를 거치지 않고 ISP 리졸버에 직접 묻게 하기도 해요.

재귀 리졸버: 루트부터 시작해요

ISP의 리졸버도 캐시를 먼저 봐요. 비어 있으면 리졸버가 PC를 대신해 이름을 끝까지 풀어내요. 이것이 재귀 조회예요. PC와 공유기가 보낸 질의에는 “끝까지 알아봐 달라”는 RD(Recursion Desired) 비트가 켜져 있어요.

리졸버는 처음에 .com 서버가 어디 있는지도 몰라요. 더 위로 물어볼 곳이 없으니 가장 위인 루트 서버부터 시작해요.

  • 루트 서버 주소는 리졸버 소프트웨어 안에 미리 박혀 있어요(root hints). a.root-servers.net부터 m.root-servers.net까지 13개 이름이에요.
  • 이름은 13개지만 anycast로 같은 IP를 전 세계 수백 곳 이상에서 서비스해요.
  • DNS를 알려고 DNS를 쓸 수 없으니, 이름으로 찾는 길의 맨 처음만큼은 IP를 직접 적어 둔 거예요.

위임: 루트, TLD, Authoritative Name Server

각 단계는 자기가 아는 범위까지만 알려주고 다음 담당을 가리켜요. 이 응답을 위임(referral)이라고 해요.

단계 리졸버의 질문 응답
루트 서버 google.com의 A 레코드? 몰라요. com은 a.gtld-servers.net 등이 담당해요
.com TLD 서버 google.com의 A 레코드? 몰라요. google.com은 ns1.google.com 등이 담당해요
구글 Authoritative Name Server google.com의 A 레코드? 142.250.x.x, TTL 300

위임 응답의 모양: NS와 glue

루트에게 물으면 실제로 이런 응답이 와요.

com                 NS   172800  Authority   a.gtld-servers.net  (같은 형태로 13개)
a.gtld-servers.net  A    172800  Additional  192.5.6.30
  • NS 레코드: “이 영역을 맡은 서버의 이름”이에요.
  • glue 레코드: 이름만 오면 그 이름의 IP를 또 DNS로 찾아야 해서 순환이 생겨요. 그래서 응답의 Additional 영역에 그 서버들의 IP를 함께 실어 줘요.
  • 이 응답은 정답이 아니라 “다음에 물어볼 곳”이에요. 그래서 TTL이 172800초(2일)로 길어요. 담당자가 잘 안 바뀌기 때문이에요.

위임은 누가 등록할까요

도메인을 사면 등록 업체(레지스트라)에서 “이 도메인의 네임서버는 이것이다”를 설정하고, 그것이 .com 레지스트리에 반영돼요. .com 서버는 mail.google.com 같은 하위 이름을 알지 못해요. 도메인 하나가 누구에게 위임됐는지만 알아요.

최종 답을 주는 Authoritative Name Server

google.com을 맡은 Authoritative Name Server가 진짜 레코드를 갖고 있어요. 이 서버는 구글처럼 직접 운영하기도 하고, 대부분의 도메인은 Cloudflare, AWS Route 53, 등록 업체의 DNS를 빌려 써요.

google.com   A   300   Answer   142.251.118.102   (같은 형태로 여러 개)
  • 응답에는 AA(Authoritative Answer) 표시가 켜져요. 캐시가 아니라 원본이 답했다는 뜻이에요.
  • 응답에 TTL(여기서는 300초)이 붙어요.
  • IP가 하나가 아니라 여러 개 올 수 있어요. 부하 분산과 가용성을 위해서예요.

계층과 캐시가 만드는 확장성

전 세계 모든 도메인의 대응표를 한 곳에 두지 않고 계층으로 나눈 이유가 여기서 드러나요.

  • 분산: 루트는 TLD 위임만, TLD는 도메인 위임만, Authoritative Name Server는 자기 도메인의 레코드만 관리해요. 한 곳에 부하와 데이터가 쏠리지 않아요.
  • 위임: 도메인 주인이 자기 레코드를 자기 Authoritative Name Server에서 직접 바꿔요.
  • 캐시: 위쪽 응답일수록 TTL이 길고 재사용이 잦아요.

리졸버가 방금 google.com을 푼 뒤 다른 사용자가 naver.com을 물어보면, 처음부터 다 거치지 않아요. 앞에서 저장한 .com 담당 서버의 NS(TTL 2일)가 있으니 .com 서버부터 시작해요. 그래서 루트 서버에는 질의가 비교적 적게 도달해요.

응답이 돌아오는 길

구글 Authoritative Name Server의 답은 거꾸로 돌아와요.

Authoritative Name Server, 리졸버, 공유기, PC의 OS 캐시, Chrome
  • 각 단계가 TTL 동안 저장해요. 같은 사이트에 두 번째 접속하면 대부분 PC 안의 캐시에서 끝나요.
  • PC에서는 응답 UDP 패킷의 목적지 포트(53012)와 질의 ID로 처음 질문을 보낸 프로그램을 찾아요.
  • Chrome이 IP를 받으면 이름 풀이는 끝나요. 이제 목적지 142.250.x.x로 가는 TCP 연결을 시작해요. 네트워크 계층에서 이 IP는 내 동네 밖이므로 이번에는 게이트웨이에 맡기는 쪽이에요.

직접 확인해 보기 (PowerShell)

# Chrome 밖, OS의 DNS 캐시
Get-DnsClientCache | Where-Object Entry -like "*google*"

# 내 PC에 설정된 DNS 서버 (DHCP가 알려준 값)
Get-DnsClientServerAddress -AddressFamily IPv4

# IP, 서브넷 마스크(프리픽스 길이), 기본 게이트웨이
Get-NetIPConfiguration

# ARP 캐시: IP와 MAC 대응표
arp -a

# DNS 질의를 직접 보내고 TTL 확인
Resolve-DnsName google.com -Type A

# OS 캐시를 비우고 다시 질의
Clear-DnsClientCache

# 루트 서버에 직접 묻기 (재귀 없이): 답 대신 com 담당 서버(NS)와 glue IP를 알려준다
Resolve-DnsName google.com -Type A -Server a.root-servers.net -NoRecursion -DnsOnly

# google.com을 맡은 Authoritative Name Server 목록
Resolve-DnsName google.com -Type NS -DnsOnly

# Authoritative Name Server에 직접 묻기: Answer 섹션에 A 레코드가 오고 TTL은 300
Resolve-DnsName google.com -Type A -Server ns1.google.com -NoRecursion -DnsOnly
  • Resolve-DnsName을 두 번 연속 실행해서 TTL이 줄어드는지 보면 캐시가 눈에 보여요.
  • 루트와 Authoritative Name Server에 직접 물은 결과를 비교하면 위임 응답(Authority, Additional)과 최종 응답(Answer)의 차이가 보여요.
  • 같은 방식으로 .com TLD 서버(a.gtld-servers.net)에 물으면 제 환경에서는 DNS server failure가 나왔어요. 환경에 따라 다를 수 있어서 위 세 명령만 적었어요.

정리

계층 하는 일 이 예에서 붙는 값
응용 계층 이름을 IP로 바꾸려 DNS 질의 메시지를 만들어요 google.com의 A 레코드?
전송 계층 UDP 헤더를 붙여요 출발지 53012, 목적지 53
네트워크 계층 IP 헤더를 붙이고 다음 홉을 정해요 192.168.0.10에서 192.168.0.1, 같은 서브넷이라 직접
데이터 링크 계층 ARP로 MAC을 알아내 프레임으로 감싸요 목적지 MAC은 공유기 MAC
물리 계층 프레임을 신호로 바꿔 내보내요 FCS를 붙이고 DMA로 가져가요

2부는 이렇게 정리돼요.

단계 하는 일 핵심
공유기 캐시를 보고, 없으면 상위 DNS에 새 질의를 만들어요 포워더가 새 질의를 만들어요 (NAT와 달라요)
재귀 리졸버 캐시가 없으면 PC 대신 끝까지 풀어요 루트 서버 주소는 미리 박혀 있어요
루트 서버 com 담당 서버를 알려줘요 NS와 glue, TTL 2일
.com TLD 서버 google.com 담당 서버를 알려줘요 도메인 위임만 알아요
Authoritative Name Server 진짜 A 레코드를 답해요 AA 표시와 TTL 300
돌아오는 길 각 단계가 TTL 동안 저장해요 두 번째 접속부터는 대부분 PC 안에서 끝나요

자주 하는 오해

  • IP나 이름을 NIC가 안다: NIC는 자기 MAC만 알아요. 이름과 IP의 대응표는 DNS와 OS 캐시에 있어요.
  • 게이트웨이에 맡기면 목적지 IP가 공유기 IP로 바뀐다: 바뀌지 않아요. 바뀌는 것은 데이터 링크 계층의 목적지 MAC이에요.
  • 포트는 서버만 쓴다: 클라이언트도 임시 포트를 쓰고, 그래서 답을 올바른 프로그램에 전달할 수 있어요.
  • UDP는 신뢰할 수 없어서 DNS에 부적합하다: 재전송을 UDP 위의 응용 계층이 직접 하므로 문제없어요. 오히려 작고 빠른 질의에 유리해요.
  • ISP에 물어보면 ISP 라우터가 답한다: 질의를 받는 것은 ISP가 운영하는 DNS 서버(재귀 리졸버)예요. 라우터는 패킷을 전달할 뿐 이름을 풀지 않아요.
  • 공유기가 DNS 질의를 전달하는 것은 NAT다: 포워더가 자기 이름으로 새 질의를 만들어요. NAT는 같은 패킷의 주소와 포트만 바꿔요.
  • 루트 서버가 google.com의 IP를 안다: 루트는 com을 맡은 서버만 알아요. IP는 맨 아래 Authoritative Name Server만 알아요.
  • .com 서버가 google.com의 IP를 안다: .com 서버는 google.com을 누구에게 위임했는지만 알아요.
  • 매번 루트부터 다 거친다: 위쪽 응답은 TTL이 길어 캐시돼요. 보통은 .com이나 Authoritative Name Server부터 시작해요.

다음에 다룰 내용

이제 Chrome은 google.com의 IP를 알아요. 다음은 이 IP로 향하는 TCP 연결, 즉 3-way handshake예요. 이 연결을 거친 뒤에야 TLS 핸드셰이크와 HTTP 요청이 시작돼요.

끝까지 읽어주셔서 감사합니다.