본문 바로가기
서버

https://google.com 통신 흐름 완전 분석

by 탁구치는 개발자 2024. 11. 19.

 

브라우저에서 https://google.com URL을 호출 했을 때 패킷이 어떻게 만들어지고 전송되는지를 알아보겠습니다.


1. 도메인 이름을 IP 주소로 변환 (DNS 조회)

브라우저는 google.com 도메인에 대한 IP 주소를 알아내기 위해 DNS 서버에 요청합니다.
UDP 패킷을 만들고, DNS에 질의하면 DNS 서버가 응답을 해줍니다.
DNS 서버가 응답해준 UDP 패킷에는 google.com 도메인에 대한 IP 정보가 담겨져 있습니다.
그리고 IP 정보를 로컬 PC의 DNS 캐시에 저장합니다.

테스트를 한번 해보겠습니다.
브라우저에서는 자체적으로 관리하는 DNS 캐시가 있기 때문에 윈도우에서 테스트 하는 방법으로 해보겠습니다.
윈도우 PowerShell 프로그램을 실행하고, ping google.com 명령어를 날려봅니다.
ipconfig /displaydns | findstr "google.com" 명령어를 실행합니다. (데이터가 너무 많아서 findstr 명령어를 이용하여 google.com 만 출력합니다.)

데이터 이름 . . . . . : google.com
데이터 유형 . . . . . : 1
TTL(Time To Live) . : 277
데이터 길이 . . . . . : 4
섹션 . . . . . . . : 응답
(호스트) 레코드 . . . : 172.217.175.78

위와 같이 데이터가 출력됩니다.
TTL 값은 277로 되어 있죠?
277초 뒤에 google.com DNS 캐시가 사라진다는 의미입니다.

그럼 권장되는 TTL 값은 어떻게 될까요?
웹사이트는 5분 ~ 1시간
자주 변경되지 않는 사이트는 24시간 (기업 홈페이지, 정적 콘텐츠 제공 사이트)
동적으로 IP가 변경되는 사이트는 1분 ~ 5분 (로드밸런싱, 클라우드)

 

2. 애플리케이션 계층 처리

7계층인 애플리케이션 계층에서 HTTP 패킷을 생성합니다.

애플리케이션 계층에서 생성되는 데이터는 다음과 같습니다.

GET / HTTP/1.1
Host: google.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Upgrade-Insecure-Requests: 1


브라우저에서 https 프로토콜을 사용하였기 때문에 위의 요청 데이터가 생성되면 TLS 프로토콜이 사용됩니다.

TLS(Transport Layer Security) 프로토콜은 OSI 7계층에서 세션 계층(Layer 5)에 속합니다. 
그러나, TLS는 전송 계층 프로토콜인 TCP와 함께 작동합니다. 작동되는 원리는 TCP 전송계층을 다룰 때 함께 이야기 하겠습니다.


3. 전송 계층 처리

TCP 연결 설정은 OSI-7 레이어의 전송 계층(4계층)에서 이루어집니다.

전송 계층에 속하는 TCP는 데이터를 신뢰성 있게 전달하기 위해 3-Way Handshake라는 연결 과정을 수행합니다. 

SYN : 클라이언트가 서버에게 연결 요청을 보내기 위해 SYN 패킷을 전송합니다.
SYN-ACK : 서버는 클라이언트의 요청을 받고 연결을 승인하며, 동시에 SYN-ACK 패킷을 전송합니다.
ACK : 클라이언트는 서버의 응답을 확인하고 ACK 패킷을 보내 연결이 확립됩니다.

TCP 연결이 수립되면 TLS Handshake가 시작되어 클라이언트와 서버 간에 암호화된 통신이 설정됩니다. (https://google.com와 같이 https를 사용했기 때문)
ClientHello : 클라이언트가 지원하는 암호화 방식과 TLS 버전을 서버에 전송합니다.
ServerHello : 서버가 선택한 암호화 방식과 인증서를 클라이언트에 보냅니다.
Certificate : 서버가 클라이언트에 인증서를 전달하여 서버의 신뢰성을 보장합니다.
ClientKeyExchange : 클라이언트는 서버의 공개 키를 사용하여 세션 키를 암호화하여 전송합니다.
Finished : 클라이언트와 서버는 서로의 Finished 메시지를 확인하여 암호화된 세션을 수립 합니다.

TLS Handshake가 완료된 후에는 애플리케이션 계층 데이터는 세션키(대칭키 알고리즘 : AES, DES)를 사용해 암호화 처리가 됩니다.

연결이 성공하면 아래와 같이 애플리케이션 계층의 패킷 앞에 전송 계층 헤더가 추가됩니다.
+-------------------------------------------------------------------+
| 전송 계층 헤더
| 출발지 Port(1000), 목적지 Port(80), 시퀀스 번호
+-------------------------------------------------------------------+
| 애플리케이션 계층 데이터
+-------------------------------------------------------------------+


4. 네트워크 계층 처리

전송 계층에서 보낸 패킷이 네트워크 계층에 도달하면 아래와 같이 전송 계층 패킷 앞에 IP 헤더를 추가합니다.
+-------------------------------------------------------------------+
| IP 헤더
| 출발지 IP(172.18.97.x), 목적지 IP(172.217.175.78)
+-------------------------------------------------------------------+
| 전송 계층 헤더
| 출발지 Port(1000), 목적지 Port(80), 시퀀스 번호
+-------------------------------------------------------------------+
| 애플리케이션 계층 데이터
+-------------------------------------------------------------------+

이때 출발지 IP는 NAT의 공인아이피가 아닌 로컬 머신의 아이피가 됩니다.
사설 네트워크 망에서 동작하는 PC라면 172.18.97.x 와 같은 사설 아이피가 출발지 IP가 됩니다.
이 패킷이 그대로 목적지 IP에 도달했다고 가정해 보겠습니다. 요청자의 패킷은 목적지에 잘 도착하지만 목적지에서 요청자에게 응답을 보내고 싶어도 보낼 수 없게 됩니다. 공인 네트워크(인터넷)에서는 사설 IP 대역이 라우팅되지 않기 때문입니다.
이런 문제를 해결해 주는 것이 NAT 입니다. NAT에 대해서는 아래에서 추가 설명하겠습니다.


5. 데이터 링크 계층 처리

네트워크 계층에서 보낸 패킷이 데이터 링크 계층에 도달하면 아래와 같이 네트워크 계층 패킷 앞에 데이터링크 헤더를 추가합니다.
+-------------------------------------------------------------------+
| 데이터링크 헤더
| 출발지 MAC, 목적지 MAC
+-------------------------------------------------------------------+
| IP 헤더
| 출발지 IP(172.18.97.x), 목적지 IP(172.217.175.78)
+-------------------------------------------------------------------+
| 전송 계층 헤더
| 출발지 Port(1000), 목적지 Port(80), 시퀀스 번호
+-------------------------------------------------------------------+
| 애플리케이션 계층 데이터
+-------------------------------------------------------------------+

출발지 MAC은 로컬 PC의 MAC 주소이고, 목적지 MAC은 기본 게이트웨이 또는 라우터의 MAC 주소가 됩니다.
왜 MAC 주소가 필요할까요?
로컬 PC에서 생성한 IP 패킷이 외부 네트워크로 전달되기 위해서는 먼저 로컬 네트워크 내의 라우터(기본 게이트웨이)로 전달되어야 합니다. 이 과정에서 로컬 네트워크는 MAC 주소를 기반으로 장치 간에 데이터를 전달합니다.
로컬 PC에서 ipconfig /all 명령어를 실행해 보면 네트워크 카드에 등록되어 있는 기본 게이트웨이 아이피가 보입니다.
여기서 또 궁금증이 일어납니다.
게이트웨이 아이피는 알고 있지만 게이트웨이 MAC 주소는 로컬 PC가 모릅니다.
어떻게 기본 게이트웨이의 MAC 주소를 알아낼 수 있을까요?
ARP(Address Resolution Protocol) 프로토콜을 사용해서 IP 주소에 대응하는 MAC 주소를 확인합니다.
로컬 PC는 네트워크에 "이 IP 주소(192.168.1.10)를 가진 장치가 누구야?" 를 묻는 ARP 요청을 브로드캐스트로 전송합니다.
게이트웨이는 자신의 MAC 주소를 포함한 ARP 응답 메시지를 로컬 PC에게 전송합니다. 이 응답은 유니캐스트 방식으로 로컬 PC에게만 전달됩니다.

자~ 이제 출발지 MAC 주소와 목적지 MAC 주소가 패킷에 추가되었습니다.
이제 해당 패킷은 NAT로 이동하게 됩니다.


6. NAT에서 패킷 처리

NAT 라우터는 사설 IP 주소와 포트를 공인 IP 주소와 새 포트로 매핑하고, 내부 네트워크에서 나온 TCP 패킷을 외부 네트워크에서 처리될 수 있도록 합니다.

아래와 같은 정보가 포함되어 있는 패킷이 NAT로 전달되면 어떻게 변경될까요?
출발지 IP : 172.18.97.x -> 203.0.113.x (NAT 공인 아이피)
출발지 포트 : 1000 -> 50000 (NAT가 지정한 새로운 포트 번호)

이처럼 NAT는 공인 아이피와 포트로 패킷을 조작합니다.
이제 패킷은 다음과 같이 구성되었습니다.
+-------------------------------------------------------------------+
| 데이터링크 헤더
| 출발지 MAC, 목적지 MAC
+-------------------------------------------------------------------+
| IP 헤더
| 출발지 IP(203.0.113.x), 목적지 IP(172.217.175.78)
+-------------------------------------------------------------------+
| 전송 계층 헤더
| 출발지 Port(50000), 목적지 Port(80), 시퀀스 번호
+-------------------------------------------------------------------+
| 애플리케이션 계층 데이터
+-------------------------------------------------------------------+

7. 이후 처리

요청 패킷은 여러 라우터를 경유하여 최종 목적지에 도달하고, 마지막으로 대상 서버에 전달됩니다. 이 과정은 네트워크 계층에서 라우팅이라는 방식으로 이루어지며, 각 라우터는 패킷의 목적지 IP 주소를 보고 최적의 경로로 다음 라우터(또는 서버)로 전달합니다.

마지막으로 대상 서버는 요청 패킷의 아래 애플리케이션 데이터를 확인하여 응답 패킷을 생성하여 요청지로 전송합니다.

GET / HTTP/1.1
Host: google.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Upgrade-Insecure-Requests: 1



응답 패킷이 생성되고 전달되는 과정은 요청 패킷이 만들어지는 과정과 동일하기 때문에 생략하겠습니다.