이번시간에는 브라우저 주소창에 google.com을 입력하면 눈으로 보이지 않는 🪄마법 같은 일들에 대해 자세히 알아보겠습니다!!
🛫 떠나기 전 큰 틀 부터 잡고 가보자!!
HTTP의 마법에 대해 알아보기 위해 전체적인 흐름을 이해하고 있어야 마법도 이해를 할 수 있답니다.🎩
따라서 아래 좋은 예시의 그림으로 저와 함께 큰 분류를 먼저 나눠보겠습니다!🍳
우선 그림의 번호에 따라 한번 살펴 보겠습니다!
여기에선 특징과 함께 간략한 설명을 적어놓았으니 우선은 이해를 못하셔도 좋습니다.😉 이따가 아래에서 단계별로 깊이 들어갈 때 이해할 수 있도록 설명을 드릴 거니까 큰틀만 먼저 이해를 해주세요!
1. DNS서버 (①, ②, ③, ④)
- DNS 서버는 도메인( "google.com" )을 해당 웹 서버의 IP 주소로 해석하고 반환합니다.
2. HTTP 메시지 작성 (⑤, ⑨)
- DNS 서버에서 변환받은 IP주소와 함께 HTTP 메시지를 작성합니다. (클라이언트 측에서만)
3. TCP를 통한 인터넷 연결 (⑤ ~ ⑥ 사이)
- 작성된 HTTP 메시지의 IP를 통해 TCP의 3-way-handshake를 이용한 서버 연결을 합니다.
4. OS 네트워크 스택 (⑥, ⑩)
- 서버 측 OS에서는 HTTP 메시지를 쪼개서 세그먼트, 패킷으로 캡슐화합니다.
5. 웹서버(구글)에 접속하여 웹페이지 데이터 받음 (⑦, ⑧)
- 프레임화 되어 라우터 등을 통하여 전달된 HTTP 요청을 웹서버에서 전달받고 요청에 따른 HTTP 응답을 만들어 다시 전송합니다.
6. 크롬에서 응답 메시지를 통해 해석하여 브라우저 출력 (⑪, ⑫)
- OS는 구글 웹서버와 동일한 방식으로 패킷을 받아 HTTP 응답 메시지를 조립하여 포트번호를 통해 브라우저에게 전달하게 되고 브라우저는 HTTP 응답 메시지를 해석하여 HTML, CSS, JavaScript 등의 웹 페이지 요소를 추출받아 렌더링합니다.
7. 연결 종료(⑫)
- 이후 사용자에게 보여주게 되어 모든 요청이 완료되면 TCP의 4-way-handshake를 통해 연결을 종료합니다.
자 이러한 대략적인 큰틀에 대해서 어느정도 감은 잡히셨나요? 그렇다면 이제부터 하나하나 자세히 알아봅시다!!
📫1. DNS 서버
DNS(Domain Name Server)란?
- google.com 와 같은 도메인 주소를142.250.76.142 와 같은 IP주소로 변환하여 줍니다.
사실 이 글에선 DNS서버에 대해서 자세히 설명하지 않고 동작과정에 대해서만 다루도록 하겠습니다.
(DNS에 대해선 이미 더 좋은 글들이 많거든요.👍)
다만 도메인 네임 서버의 구조는 눈에 익혀두면 이해가 더 쉽기 때문에 간단하게 설명을 드려보자면!
- 1단계인 최상위 도메인은 일명 TLD(Top-Level Domain) 라고 불립니다.
- TLD는 국가코드 최상위 도메인과 일반 최상위 도메인으로 나뉩니다.
- 여기서 재미있는 건 같은 구글 페이지에 접속하는 것이더라도
- google.com 으로 검색하면 루트 도메인 서버에서 일반 최상위 도메인으로,
- google.co.kr로 검색하면 루트 도메인 서버에서 국가코드 최상위 도메인으로
- 각각 다른 TLD 서버에 접근하고 그로인해 실제 응답도 다르게 받는다는 사실도 알고 계시면 좋을 것 같아요!😄 (
재밌지 않나요?)
- 여기서 재미있는 건 같은 구글 페이지에 접속하는 것이더라도
🎢 자! 이제 google.com이 DNS서버를 통해 실제로 어떻게 IP주소로 변환이 되는지 같이 살펴 볼까요?
0️⃣ 브라우저는 검색창에 google.com이 입력된 순간 위 사진에는 없지만 DNS Server에 쿼리 하기 전에 먼저 사용자 컴퓨터 내부에서부터 찾아보게 됩니다.
- hosts.txt 파일 검색 (위치: C:\Windows\System32\drivers\etc\host)
- DNS 캐시 테이블 조회 (조회 명령어: ipconfig /displaydns))
1️⃣ 내부적으로 찾아보았지만 존재 하지 않을 경우 DNS Resolver가 Local DNS Server(ISP)에 쿼리하게 됩니다.
- Local DNS Server는 보통 ISP(인터넷 제공 업체)자체 네트워크 인프라에서 보유하고 있는 DNS Server이므로 이제 DNS Server라고 지칭하도록 하겠습니다.
- DNS Resolver(주로 OS나 공유기에 내장)는 해당 DNS Server에 google.com의 IP 정보가 있는지 확인을 요청합니다.
- Local DNS Server 에도 존재하지 않는다면 다음 2️⃣부터의 절차를 수행하게 됩니다.
- 추가적으로 ipconfig /all 또는 nslookup 명령어를 사용하면 DNS Server의 IP를 알아낼수도 있습니다.
- 추가적으로 ipconfig /all 또는 nslookup 명령어를 사용하면 DNS Server의 IP를 알아낼수도 있습니다.
2️⃣3️⃣ DNS Server를 통해 Root Name Server에 접근하고, .com을 처리하는 TLD 서버의 IP주소를 반환 받습니다.
- 루트 DNS Server는 전 세계적으로 분산된 서버 중 하나로 전세계에 13대 밖에 존재하지 않습니다.
4️⃣5️⃣ DNS Server는 다시 해당 주소로 TLD Server에 접근하고, google.com의 도메인 처리하는 하위 Domain Name Server의 IP주소를 반환 받습니다.
6️⃣7️⃣ DNS Server는 Domain Name Server에 접근하고, 실제 google.com의 IP주소를 반환 받습니다.
- 최종적으로 google.com의 IP주소를 가지고 있는 마지막 Domain Name Server는 일반적으로 신뢰할 수 있는 DNS Server라고 불립니다.
8️⃣ DNS Server는 google.com의 실제 IP주소를 반환 받아 DNS Server에 저장하고 DNS Resolver에게 전달하여 브라우저에게 IP주소를 전달합니다.
9️⃣🔟브라우저는 받은 IP주소를 포함하여 추후 설명드릴 HTTP 메시지를 생성하는 등의 일련의 과정을 통해 google 웹서버에게 데이터를 받아 화면에 렌더링 해줍니다.
🌟 참고로 nslookup 명령어로 google.com의 IP주소를 얻어 낼 수도 있습니다.
✉️ 2. HTTP 메시지
HTTP 통신을 하기 위해 이번단계에서는 구글 웹서버에 요청하기 위한 HTTP 메시지를 웹 브라우저 생성하게 됩니다.
🥝 HTTP 요청 메시지의 형식
🚝Header
- 첫 번째 줄 (start-line)
- 요청 메서드 + 요청 URI + HTTP 프로토콜 버전
- 두 번째 줄부터 (http headers)
- Header 정보들을 포함합니다.
- 'Header Name': 'Header Value' 형태
- 빈 줄(empty-line)
- 요청에 대한 모든 헤더 메타 정보가 전송되었음을 나타냅니다.
🚃 Body
- 원칙적으론 POST, PUT의 경우에만 존재합니다.
이번 주제에선 GET 방식을 사용 하기때문에 아래의 HTTP의 Header의 정보를 보면 됩니다.
(만약 Body 데이터도 있다면 거기엔 중요한 정보를 담고 있지만 서버별로 천차만별이라서 그때그때 이해하여 사용하면 됩니다.)
구글에서 개발자 도구의 Network를 살펴보면 이런식으로 HTTP 메시지를 생성한 것을 확인 할 수 있습니다.
이를 토대로 만들어보면 아래와 같이 만들어 졌을 거라고 추측해 볼 수 있습니다.👀
(참고로 제가 이해하기 쉽도록 임의로 만들어본 예시라 정확하지는 않을 수도 있습니다.!!)
GET / h3
Host: www.google.com
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate, br
Cache-Control : max-age=0
...
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36
- GET / h3
- 여기서 GET 방식으로 조회를 하였고 HTTP/3 프로토콜을 사용하였습니다.
- 물론 제 PC 환경에선 HTTP/3를 사용했고, HTTP/3는 TCP가 아닌 UDP(QUIC)를 사용하지만,
- 아직까지 많이 사용되는건 HTTP/1.1, HTTP/2 이므로 이글에선 TCP로 설명을 드리겠습니다.
- 여기서 GET 방식으로 조회를 하였고 HTTP/3 프로토콜을 사용하였습니다.
- Host: www.google.com
- 요청이 전송되는 호스트를 ww.google.com로 지정하였습니다.
- Accept: ...
- 클라이언트가 서버로 부터 받을 수 있는 콘텐츠 유형을 지정하였습니다.
- 각 유형들의 우선순위로 순차적으로 지정되어있고 q의 값이 높을 수록 우선순위가 높습니다.
- Accept-Encoding : gzip, deflate, br
- 서버가 응답을 압축해서 보낼 수 있도록 클라이언트가 지원하는 인코딩 형식을 알려주었습니다.
- Cache-Control : max-age=0
- 캐시의 유효시간을 0으로 설정하여 캐시된 리소스를 사용하지 않는다는 것을 의미합니다.
- 이는 서버에게 항상 새로운 데이터를 반환하고 클라이언트는 로컬 캐시에 저장하지 않겠다는 의미입니다.
- User-Agent: ...
- 클라이언트의 소프트웨어 및 운영체제 정보를 제공합니다.
- 윈도우10, Chrome 브라우저의 정보 등이 포함되어 있습니다.
📡 3. TCP 연결
TCP의 3-way-handshake로 구글 웹서버와 전송계층(TCP)을 통해 연결을 수립합니다.
(이글에선 3-way-handshake도 더 자세히 다루진 않으므로 궁금하신 분들은 해당 키워드로 추가 학습하시는걸 추천드립니다.)
TCP 3-way-handshake는 주로 전송계층의 역할이지만 실제로 연결 시에는 어쨋거나 ACK와 FIN 등의 메시지를 주고 받기 위해선 네트워크 계층의 IP주소를 기반으로 목적지까지 라우팅 되고, IP패킷은 다른 네트워크까지 연결이 되어야 하므로 데이터링크 계층의 스위치를 통해 이더넷도 사용되며 물리 계층의 모뎀 등을 사용해 아날로그 신호로 전송하게 됩니다.
4. OS 네트워크 스택
이제 TCP로 웹서버와 연결도 되어있고! HTTP 요청 메시지도 준비됐겠다! TCP/IP를 타고 구글 웹서버에 접근을 해볼시간인데요!
과거에는 OSI 7계층으로 많이쓰였지만 최근에는 TCP/IP 모델을 주로 사용하므로 TCP/IP 모델로 설명을 드리겠습니다.
위 그림을 설명드리기에 앞서 앞에서 애써 만든 HTTP 데이터가 어떻게 손실이 이루어지지 않고 웹서버에 잘 전달이 될지 살펴봐야 합니다!
먼저 위의 그림과 같이 각 전송 계층을 지나며 데이터에 헤더를 만들어 붙여주게 됩니다.
1. 응용 계층에서는 HTTP 헤더를 붙이고 캡슐화
2. 전송 계층에서는 TCP 헤더를 붙이고 캡슐화
3. 인터넷 계층에서는 IP 헤더를 붙이고 캡슐화
4. 네트워크 계층에서는 이더넷 헤더를 붙이고 캡슐화 하여 최종적으로 네트워크 전송 단위인 프레임이 완성이 되죠!
이제 그림으로 실제 전송이 어떻게 되는지 이해해 볼까요?
1️⃣ 응용계층, 즉 사용자의 브라우저(크롬)에서는 구글 웹 페이지를 요청하기 위한 HTTP 메시지를 작성하게 됩니다.
- 데이터(HTTP Body)에 헤더(HTTP Header(요청 메서드, 요청 URI, HTTP 프로토콜 버전 등)) 를 붙입니다.
- 아까 위의 대분류 중 2단계 HTTP 메시지에서 자세히 다뤘으므로 여기선 넘어가겠습니다.
2️⃣ 전송계층에서는 OS가 HTTP 메시지를 작은 패킷단위로 나누고 TCP 헤더를 붙여 세그먼트로 캡슐화를 합니다.
- 송신지와 수신지의 각 Port 번호
- 순서 번호 및 확인 응답 번호
- 플래그 비트 들
- SYN (연결 요청)
- ACK (연결 응답)
- FIN (연결 종료) 등
- 윈도우 크기
- 수신 측의 서버에서 수신 받을 수 있는 maximum 데이터 크기를 정합니다.
- Checksum
- 모든 값을 16비트로 변환하여 더한 뒤 1의 보수를 취합니다. 수신 측도 동일하게 모든 값을 16비트로 변환하여 더한 뒤 Checksum 값을 더하여 값이 유효한지 검사합니다.
- 💡왜 보수를 취할까요?
-
더보기예를 들어 모든 값을 변환하여 더한값이 1011이라면 Checksum은 그의 1의 보수인 0100입니다.
따라서 Checksum을 더하게 되면 1111로 모든 자리가 1로 되어 값이 유효하게 잘 전달 받았는지 쉽게 확인 할 수 있습니다.
-
- 💡왜 보수를 취할까요?
- 모든 값을 16비트로 변환하여 더한 뒤 1의 보수를 취합니다. 수신 측도 동일하게 모든 값을 16비트로 변환하여 더한 뒤 Checksum 값을 더하여 값이 유효한지 검사합니다.
3️⃣ 인터넷 계층에서는 OS가 나뉘어진 세그먼트에 IP 헤더를 붙이고 데이터그램으로 한번 더 캡슐화 합니다.
- 출발지와 목적지의 IP 주소
- IP 길이
- TTL (Time To Live)
- 패킷이 네트워크 전달 과정 동안 계속 감소되며, 0이 되면 폐기하여 무한정 횡단하지 않도록 합니다.
- 프로토콜
- TCP(6)
- UDP(17) 등
4️⃣ 네트워크 계층에서 이더넷 헤더를 추가하고 작은 전송 단위인 프레임으로 캡슐화합니다.
- 출발지와 목적지의 MAC 주소
- 상위 계층 프로토콜 종류
- 0x0800 (IPv4) / 0x86DD (IPv6)
5️⃣ 네트워크 장치들을 통한 데이터 전송이 이루어 집니다.
- 먼저 컴퓨터의 OS에서 HTTP 메시지를 세그먼트(TCP패킷)화 한 이후 데이터그램(IP 패킷)으로 캡슐화 합니다.
- NIC 장치를 통해 데이터그램을 프레임화(이더넷 패킷)하여 Swtich에 전달합니다.
- Switch에서는 프레임화 된 패킷들을 외부 네트워크에 전송하기 위해 Router로 전송합니다. (일부는 통합되어 사용)
- Router는 외부 네트워크에 전송하기 위해 Modem에 접근합니다.
- Modem은 ISP에 연결하여 데이터를 인터넷을 통해 전송하기 위해 디지털 신호를 아날로그 신호로 변환하여 전달합니다.
- ISP의 BGP(Border Gateway Protocol)을 통해 인터넷을 제공 받아 구글 웹 서버까지 인터넷이 연결됩니다.
- 구글 웹서버는 네트워크 스택에 따라 해당 역순대로 진행되며 역캡슐화를 통해 웹서버까지 전달됩니다. (물론 위의 그림은 가정용 네트워크를 가정하였으므로 실제 기업용 인프라는 더욱 방대합니다.)
🏢 5. 웹서버 응답
구글의 웹서버 사이트에서도 요청 메시지를 읽고 해당 요청에 맞추어 HTTP 응답 메시지를 만들어 이전 우리가 전송한 방식과 동일한 방식을 통해 인터넷 통신을 하여 저희 ISP에 다시 응답하여 줍니다.
추후 구글 웹서버가 자바 스프링이라 가정하고 스프링이 HTTP를 처리하는 방법에 대해 자세히 포스팅을 작성하여 연결해 두겠습니다.!🫡
🎥 6. 브라우저 렌더링 (HTTP 응답 메시지 해석)
- ISP에 도착한 HTTP 응답 메시지는 모뎀을 통해 아날로그 신호를 디지털 신호로 다시 변환하며 라우터로 전송하여 줍니다.
- 라우터(스위치)는 받은 프레임들을 데이터그램으로 역캡슐화하여 얻어낸 IP주소에 전달합니다.
- IP주소에 해당하는 컴퓨터의 NIC가 데이터그램을 받습니다.
- OS는 해당 데이터그램을 네트워크 스택에 따라 역캡슐화 하며 얻어낸 포트번호를 통해 어느 어플리케이션으로 전달해야할지 결정합니다.
- 마지막으로 크롬 웹 브라우저가 OS에게 HTTP 응답 메시지를 전달 받습니다.
이렇게 전달 받은 브라우저는 해당 HTTP 응답 메시지를 분석하여 HTML과 CSS 등을 분석해 브라우저에 랜더링 하여 사용자에게 보여주게 됩니다.
🎥 7. TCP 연결 종료
모든 데이터의 전송을 주고 받으면 TCP 연결을 종료하기 위해 4-way-handshake를 통하여 연결을 종료하게 됩니다.
📚 참조자료