DNS · TCP · 네트워크
URL을 입력하면 일어나는 일: DNS와 TCP
브라우저가 주소를 IP로 바꾸는 DNS 조회부터 3-way 핸드셰이크와 TLS를 거쳐 HTTP 요청이 도달하는 과정을 짚어 봅니다.
무료 공개 · 최근 수정
curl -w로 쪼개어 보는 웹 요청의 4단계 지연
웹 브라우저의 주소창에 https://vivolabs.org를 입력하고 엔터를 누르면, 눈 깜짝할 사이에 첫 페이지 화면이 눈앞에 나타납니다. 대부분의 사용자는 이 찰나의 순간을 하나의 단일한 동작으로 인식하지만, 운영체제의 네트워크 스택 내부에서는 최소 네 개의 서로 다른 프로토콜 계층이 맞물려 돌아가며 시간을 나누어 쓰고 있습니다.
터미널에서 curl 도구의 포맷 출력(-w) 옵션을 사용하면, 단 한 번의 웹 페이지 요청이 어떤 단계별 지연을 거쳐 완성되는지 밀리초 단위로 낱낱이 해부해 볼 수 있습니다.
curl -w "DNS 해석 시간: %{time_namelookup}초\nTCP 연결 수립: %{time_connect}초\nTLS 협상 완료: %{time_appconnect}초\n첫 바이트 도달(TTFB): %{time_starttransfer}초\n전체 전송 완료: %{time_total}초\n" -o /dev/null -s https://vivolabs.org위 명령을 실행하면 터미널 콘솔에 다음과 같은 형태의 단계별 누적 소요 시간이 기록됩니다.
예시 출력:
DNS 해석 시간: 0.024110초
TCP 연결 수립: 0.058320초
TLS 협상 완료: 0.122450초
첫 바이트 도달(TTFB): 0.185200초
전체 전송 완료: 0.186540초출력 수치를 단계별로 분해해 보면 웹 통신의 숨은 여정이 선명하게 드러납니다. 처음 0.024초는 영문 도메인을 컴퓨터가 이해할 수 있는 IP 주소로 바꾸는 DNS 조회에 쓰였습니다. 그 뒤 0.034초 동안 서버와 TCP 3-way 핸드셰이크를 주고받아 양방향 회선을 열었으며, 이어서 0.064초 동안 암호화 통신을 위한 TLS 키 교환이 이루어졌습니다.
클라이언트가 비로소 첫 HTTP GET 요청 헤더를 서버로 보낸 시점은 연결 시작 후 무려 0.122초가 지난 뒤였습니다. 우리가 주고받는 실제 웹 콘텐츠는 이 정교한 하위 계층 통로가 완벽하게 닦인 뒤에야 단 1밀리초 만에 통로를 타고 쏟아져 들어온 셈입니다.
문자열 도메인을 IP로 변환하는 분산 DNS 계층
인터넷에 연결된 모든 라우터와 스위치는 영문 알파벳으로 된 도메인 이름을 전혀 이해하지 못합니다. 네트워크 장비들은 패킷 헤더에 적힌 32비트 IPv4 주소나 128비트 IPv6 주소만을 이정표 삼아 패킷을 목적지로 중계합니다. 하지만 사람이 매번 76.76.21.21 같은 난해한 숫자를 외워 사이트에 접속할 수는 없으므로, 사람이 읽는 도메인과 숫자로 된 기계 주소를 상호 매핑해 주는 전 세계 규모의 분산 데이터베이스가 필수적입니다. 이 분산 계층 시스템을 도메인 네임 시스템(DNS; Domain Name System)이라고 부릅니다.
브라우저는 IP를 알아내기 위해 가장 먼저 가장 비용이 적게 드는 로컬 캐시를 차례대로 뒤집니다. 브라우저 내부 캐시 메모리를 살피고, 운영체제의 DNS 캐시와 로컬 파일 시스템의 hosts 파일을 확인합니다. 이전에 방문한 적이 있어 캐시에 레코드가 남아 있다면 네트워크 통신 없이 0밀리초 만에 IP를 즉시 얻습니다.
캐시에 주소가 없다면 비로소 공유기나 통신사(ISP)가 제공하는 로컬 DNS 리졸버(Resolver)로 재귀 질의(Recursive Query)를 보냅니다. 리졸버는 전 세계 13개 루트 네임서버(.)에 물어 .org 최상위 도메인(TLD) 관리 서버 주소를 알아내고, TLD 서버를 찾아가 vivolabs.org의 공식 존(Zone) 파일을 보관하는 권한 있는(Authoritative) 네임서버 주소를 확인합니다. 마지막으로 권한 네임서버에 도달해 최종 목적지 IP(A 레코드)를 얻어내어 클라이언트에 회신합니다.
신뢰성을 확립하는 TCP 3-way 핸드셰이크
목적지 IP 주소를 손에 넣었다 하더라도 곧바로 웹 페이지 요청 문장을 보낼 수는 없습니다. 인터넷의 기본 프로토콜인 IP는 패킷의 순서 뒤바뀜, 유실, 중복 수신을 책임지지 않는 비신뢰성 비연결형 프로토콜이기 때문입니다. 자바스크립트 코드의 단 몇 바이트만 유실되어도 프로그램 전체가 깨지는 웹 환경에서는 전송 계층의 신뢰성 보장 프로토콜이 반드시 개입해야 합니다.
전송 제어 프로토콜(TCP)은 본격적인 데이터 전송에 앞서 통신 양단 사이에 가상의 전용 파이프를 수립하는 3방향 핸드셰이크(3-way Handshake)를 진행합니다(RFC 9293). 패킷이 물리적으로 세 번 오가며 양측의 수신 준비 상태와 패킷 순서를 추적할 초기 시퀀스 번호(ISN)를 서로 맞춥니다.
- SYN (Synchronize): 클라이언트가 임의로 생성한 초기 시퀀스 번호(예:
seq=1000)를 담아 서버에 연결 요청 패킷을 전송합니다. - SYN-ACK: 서버는 요청을 수락한다는 의미로 클라이언트 번호에 1을 더한
ack=1001을 설정하고, 서버 자신의 초기 시퀀스 번호(예:seq=5000)를 실어 클라이언트에 화답합니다. - ACK (Acknowledge): 클라이언트가 서버의 번호에 1을 더한
ack=5001을 담아 마지막 확인 패킷을 전달합니다.
이 세 번의 교환이 완료되는 순간 양측 운영체제 커널에는 소켓 버퍼가 정식 할당되며, 데이터 유실 시 자동 재전송과 흐름 제어를 보장하는 가상 회선이 완성됩니다.
도청을 차단하는 TLS 1.3 암호화 터널
TCP 연결만으로는 평문 데이터가 공용 네트워크 라우터를 거치는 동안 제3자에게 도청되거나 변조되는 위험을 막을 수 없습니다. 현대의 안전한 웹 통신(https://)에서는 TCP 연결 직후 상위 계층에서 전송 계층 보안(TLS; Transport Layer Security) 핸드셰이크를 추가로 실행합니다(RFC 8446).
과거 TLS 1.2 버전은 키 교환과 인증서 검증을 위해 2회의 패킷 왕복(2 RTT)이 필요했으나, 최신 표준인 TLS 1.3은 이를 단 1 RTT로 압축했습니다. 클라이언트는 첫 ClientHello 패킷에 자신이 지원하는 암호화 알고리즘 목록뿐만 아니라 디피-헬만(Diffie-Hellman) 키 교환을 위한 공개키 파라미터를 미리 묶어서 보냅니다.
서버는 ServerHello로 화답하며 자신의 공개키 파라미터와 서버 인증서를 전달합니다. 클라이언트는 공인 인증기관(CA)의 서명을 통해 서버의 진위 여부를 검증하고, 양측은 네트워크상에 단 한 번도 노출되지 않는 대칭 암호화 세션 키를 각자 독립적으로 계산해 냅니다. 이 1 RTT의 협상이 끝나면 앞으로 오갈 모든 HTTP 트래픽은 강력한 AES-GCM 등의 알고리즘으로 암호화되어 안전한 터널을 통과합니다.
[참고] HTTP/3와 QUIC의 등장
TCP의 3방향 핸드셰이크와 TLS의 1 RTT가 누적되면 연결 수립에만 최소 2~3회의 왕복 지연이 발생합니다. 최신 표준인 HTTP/3는 TCP 대신 UDP 기반의 QUIC 프로토콜을 도입하여, 연결 수립과 TLS 암호화 키 교환을 단 한 번의 핸드셰이크(1 RTT, 재접속 시 0 RTT)로 통합해 지연 시간을 비약적으로 단축했습니다.
주소 확인부터 데이터 전송까지의 전체 시퀀스
URL을 입력한 순간부터 최종 웹 문서가 도착하기까지 참여하는 네 개의 독립된 시스템(클라이언트, 로컬 DNS 리졸버, 권한 네임서버, 목적지 웹 서버) 사이의 상호작용을 시간 순서에 따른 시퀀스로 정리합니다.
그림: DNS 조회부터 TCP 수립, TLS 협상, HTTP 요청까지의 통신 시퀀스
수직으로 뻗은 네 개의 라이프라인 사이를 가로지르는 메시지들을 살펴보면, 통신이 네 개의 뚜렷한 페이즈로 나뉘어 순차적으로 전개됨을 알 수 있습니다.
- 페이즈 1 (DNS 해석): 클라이언트가 리졸버에 질의를 던지고, 리졸버가 권한 네임서버와 통신하여 목적지 IP를 찾아내어 클라이언트에 전달합니다.
- 페이즈 2 (TCP 3방향 핸드셰이크): 확보한 IP를 향해 클라이언트와 웹 서버가 SYN, SYN-ACK, ACK 패킷을 교환하여 물리적 통로를 개방합니다.
- 페이즈 3 (TLS 1.3 보안 협상): 암호화 스위트 선정과 세션 키 교환을 단 1회 왕복으로 끝마쳐 도청이 불가능한 보안 세션을 확립합니다.
- 페이즈 4 (HTTP 데이터 교환): 마침내 암호화 터널 안에서
GET / HTTP/1.1요청이 전송되고, 서버가 비즈니스 로직을 처리한 뒤200 OK와 함께 HTML 본문을 반환합니다.
터미널 진단 도구로 네트워크 단계 추적하기
네트워크 통신의 각 단계가 실제로 정상 작동하는지 확인하려면 터미널 진단 명령어를 활용할 수 있습니다.
DNS 계층의 질의 경로를 단계별로 추적할 때는 dig 명령에 +trace 옵션을 부여합니다. 로컬 캐시를 우회하고 전 세계 루트 네임서버부터 권한 네임서버까지 단계별로 찾아 들어가는 과정을 확인할 수 있습니다.
dig +trace vivolabs.org위 명령은 루트 네임서버(.), .org TLD 네임서버, 그리고 최종 도메인 네임서버가 응답한 IP 위임 기록을 터미널에 순차적으로 보여 줍니다.
이어지는 TCP 연결과 TLS 핸드셰이크 과정을 상세히 들여다볼 때는 curl 명령에 상세 모드(-v)를 적용합니다.
curl -v -o /dev/null https://vivolabs.org이 명령을 실행하면 다음과 같은 커널 연결 및 SSL 협상 로그가 차례로 출력됩니다.
예시 출력:
* Trying 76.76.21.21:443...
* Connected to vivolabs.org (76.76.21.21) port 443
* ALPN: curl offers h2,http/1.1
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* SSL connection using TLSv1.3 / AEAD-CHACHA20-POLY1305-SHA256
* Server certificate: vivolabs.org
> GET / HTTP/2
> Host: vivolabs.org
> User-Agent: curl/8.5.0
> Accept: */*
>
< HTTP/2 200 Connected to ... port 443 행은 TCP 핸드셰이크의 완성을 가리키며, TLS handshake와 암호화 스위트 협상 기록은 안전한 대칭 키가 공유되었음을 보증합니다.
분산 도구 호출의 지연 시간과 소켓 풀링 전략
네트워크 연결 수립에 따르는 지연 시간은 외부 API 및 도구 호출이 잦은 현대 AI 에이전트 시스템에서 성능의 병목을 가르는 가장 큰 요인입니다.
최근의 지능형 에이전트는 Model Context Protocol을 통해 원격 서버에 배포된 도구를 실행하거나, 대규모 언어 모델 공급자의 추론 엔드포인트를 수시로 호출합니다. 사용자의 질문 하나를 해결하기 위해 에이전트가 내부적으로 5번의 외부 도구를 호출한다고 가정해 봅니다.
만약 에이전트 런타임이 도구를 호출할 때마다 매번 DNS를 조회하고, 새 TCP 소켓을 생성하며, 매번 TLS 핸드셰이크를 거친다면 어떤 일이 일어날까요? 해외 데이터센터와의 왕복 시간(RTT)이 80ms라면, 단 한 번의 연결 수립에만 80ms × 3 = 240ms가 소모됩니다. 도구를 5번 호출하면 순수하게 연결을 맺고 끊는 데만 1.2초의 불필요한 시간이 공중으로 날아갑니다.
이 오버헤드를 제거하기 위해 프로덕션 에이전트 아키텍처에서는 연결 풀링(Connection Pooling)과 HTTP 지속 연결(Keep-Alive)을 강제합니다. 이미 DNS 해석과 TLS 협상을 마친 TCP 소켓을 닫지 않고 메모리 풀에 상시 유지해 두었다가, 이어지는 도구 호출과 LLM 질의에 즉시 재활용합니다. 소켓 풀링을 적용하면 핸드셰이크 비용이 완전히 제거되어 단 1 RTT 만에 도구 실행 결과를 받아올 수 있으며, 시스템 전반의 응답성을 획기적으로 개선할 수 있습니다.
참고 문서
설명이 어렵거나 잘못된 부분을 발견하셨나요?
문서 수정 의견 보내기