브라우저에서 서버로 요청을 보낼 때, 어떤 프로토콜들이 어떻게 사용되는지 각각의 역할에 대해서는 알고 있었다. 하지만 네트워크 통신이라는 하나의 기능 안에서 다양한 조력자들이 어떻게 협력하는지에 대해서는 명확하게 이해하지 못했다. 지금 가장 많이 사용되는 네트워크 아키텍처인 TCP/IP 통신으로 다양한 조력자들의 협력 관계를 명확하게 파악해 보자.
먼저 TCP/IP 통신에 사용되는 프로토콜들이 각각 어떤 계층에 속하는지 간단하게 알아보자.
이보다 더 많은 프로토콜들이 있지만 이번에 다룰 예정인 프로토콜만 나타냈다.
우리가 웹 서비스에 접속하기 위해 사용하는 도메인은 실제 주소가 아니다. 단지 주소를 편리하게 기억하고 사용할 수 있도록 인간친화적으로 표현한 것이다. 따라서 실제 주소 즉, 최종 목적지를 먼저 파악해야 한다.
도메인 이름에 대응하는 실제 IP 주소를 찾아주는 역할을 수행하며, IP 주소와 부가 데이터를 저장하고 있는 계층형 분산 DB 구조를 가진다. 브라우저에 도메인 이름을 지정하면, OS가 내부적으로 DNS 리졸버를 사용해 현재 사용자 PC와 가장 가까운 DNS 서버로 IP 주소를 질의한다.
DNS 서버는 루트를 정점으로 한 계층 구조로 되어 있기 때문에, 한 번에 호스트명을 찾지 못했다면 결과를 도출할 때까지 하위 계층으로 내려가며 질의를 반복한다.
실제 목적지의 IP 주소를 찾았다면, 목적지로 전송할 데이터를 준비해야 한다. 브라우저에서 서버 측의 웹 애플리케이션으로 요청을 보낸다고 가정해 보자.
브라우저와 서버 간 데이터 통신을 위한 프로토콜로, HTML이나 이미지 등을 주고받을 수 있다. 사용자가 서버로 전달할 데이터는 HTTP 바디에 저장되며, 요청 형식과 부가 정보들은 HTTP 헤더를 통해 전달된다.
이렇게 전송할 데이터에 해당 프로토콜이 헤더를 덧붙이는 작업을 캡슐화라고 하는데, 앞으로 다양한 프로토콜에 의해 캡슐화가 진행될 것이다. HTTP 헤더로 캡슐화된 현재 상태는 HTTP 메시지라고 표현한다.
통신 과정에 신뢰성을 부여하는 프로토콜로 실제 요청을 전송하기 전에 3-way handshake를 통해 서버와 커넥션을 생성한다.
3-way handshake는 DNS를 통해 IP 주소를 조회하고 나서, 그리고 HTTPS 통신을 위한 SSL(TLS) 커넥션 전에 수행된다. SSL 커넥션은 이곳에서 참고할 수 있다. TCP 커넥션 생성 후, 앞서 만들어둔 HTTP 메시지를 TCP 헤더로 캡슐화하는데 이를 TCP 세그먼트라고 한다.
TCP는 MSS를 넘는 크기의 데이터는 분할해서 전송하는데, 시퀀스 번호로 데이터가 어떻게 분할되었는지, ACK 번호로 데이터를 바르게 수신했음을 알 수 있다.
MSS(Maximum Segment Size)
TCP에서 애플리케이션의 데이터를 분할하는 단위로 표준 크기는 1460 바이트다.
인터넷상에서 데이터를 주고받을 수 있도록 출발지와 목적지 IP 주소를 포함시키는 프로토콜이다. IP 헤더를 캡슐화한 상태를 IP 패킷이라고 한다.
이렇게 목적지 IP 주소를 포함한 하나의 패킷을 준비했다.
지금까지 준비한 IP 패킷은 아직 네트워크 상으로 전송할 수 없다. "목적지를 알고 있는데 왜?"라고 생각할 수도 있다. 간단한 예를 들어보자. 친구의 생일날, 평소에 갖고 싶어 했던 선물을 준비했다. 친구의 집 주소도 알고 있기 때문에 택배로 보내기만 하면 된다. 마치 IP 패킷을 가지고 있는 지금 상황이랑 유사하다. 하지만 IP 패킷은 택배로 보낼 수 없다. 정확히 말하자면 친구 집까지 가는 길을 세부적으로 알지 못하면 선물을 전달할 수 없다.
최종 목적지를 아는 것과 최종 목적지까지 도달하는 것은 엄연히 다르다는 말이다. 그럼 네트워크 통신에서는 어떻게 길을 찾을 수 있을까?
데이터는 물리적인 신호로 변환되어 전송되기 때문에 출발지와 목적지가 물리적인 배선으로 연결되어 있어야 한다. 하지만 모든 장치들을 물리적으로 연결하는 것은 불가능하다. 앞서 든 예시에서, 택배 기사님도 이미 만들어진 길을 이용하지, 새로운 길을 만들어서 가지 않는다. 네트워크 통신도 마찬가지다. 우리가 준비한 IP 패킷은 이미 만들어진 길을 통해 목적지를 찾아간다. 이때 중요한 것은 "어디서부터 어디까지 이동할 것인가?" 이다.
네트워크 인터페이스 계층의 프로토콜로 캡슐화를 통해 물리적으로 이동할 수 있는 목적지를 포함시킨다. 이더넷 헤더에는 출발지와 도착지의 MAC 주소가 포함되는데, MAC 주소는 IP 주소와 다르게 실제 장치의 물리적인 주소다.
MAC
네트워크 인터페이스 카드(NIC)에 할당된 고유한 식별자로, 24비트의 제조업체 식별자와 24비트의 장치 식별자로 표현한다.
여기에 더해 FCS라는 것도 추가되는데, 여기에는 에러 체크를 위한 정보가 들어있다. 이더넷 프레임을 생성할 때 헤더와 페이로드 비트에 대해 수학적 계산을 진행하고, 계산 결과를 FCS 필드에 배치한다. 그런데 뜬금없이 MAC 주소가 나왔는데 MAC 주소는 어디서 나온 걸까?
하나의 네트워크 내에서 목적지 IP 주소에 대응하는 MAC 주소를 찾아준다. IP 주소와 MAC 주소를 대응시키는 것을 주소 해석이라고 하며, 다음과 같이 동작한다.
라우팅 테이블을 보고 같은 네트워크에 속하는 것을 확인한다.
같은 네트워크에 목적지가 있다면, ARP 요청으로 IP 주소에 대응하는 MAC 주소를 질의한다. ARP 요청은 브로드캐스트로 동일한 네트워크에 속한 모든 호스트에게 출발지 IP 주소, MAC 주소, 그리고 목적지의 IP 주소가 포함된 요청 패킷을 전송한다.
목적지 IP 주소에 해당하는 장비는 응답 패킷으로 MAC 주소를 전달하고, 나머지 호스트들은 요청을 폐기한다.
주소 해석한 IP 주소와 MAC 주소의 대응을 ARP 캐시에 보존하고, 이후 캐시를 참조해서 MAC 주소를 찾는다.
만약 목적지가 해당 네트워크에 존재하지 않는다면, 네트워크에 위치하는 라우터의 MAC 주소를 전달한다.
이렇게 이더넷 헤더와 FCS가 추가된 상태를 이더넷 프레임이라고 하며, 이제 이더넷 인터페이스를 통해 물리적인 신호로 전환되어 목적지까지 전송할 수 있게 되었다.
드디어 사용자 PC에서 준비한 데이터가 네트워크 세상으로 나왔다. 정성스레 준비한 이더넷 프레임이 어떤 과정으로 목적지까지 도달하는지 알아보자.
물리적인 신호로 전환된 이더넷 프레임은 이더넷 헤더에 있는 목적지 MAC 주소로 이동한다. 보통 여러 네트워크를 거쳐 목적지로 이동하기 때문에 현재 MAC 주소는 같은 네트워크에 속한 라우터의 주소가 된다. 이더넷 프레임은 먼저 사용자 PC와 연결된 레이어2 스위치로 이동한다.
레이어2 스위치는 자신의 MAC 주소 테이블에서 이더넷 프레임에 포함된 목적지 MAC 주소를 찾는다. 목적지 MAC 주소가 있다면 해당 주소로 이더넷 프레임을 전송하고, 없다면 Unknown 유니캐스트 프레임으로 간주하고 플러딩 즉, 수신한 포트를 제외한 모든 포트로 전송한다.
네트워크 내부 이동 과정을 거쳐 라우터까지 도달했다면, 라우터가 속한 네트워크에 목적지가 있는지 확인한다. 목적지가 해당 네트워크에 존재하지 않는다면, 다음으로 전송할 라우터를 판단한다.
이 과정에서 다른 네트워크로 이동하기 때문에 ARP가 수행되고, 기존의 이더넷 헤더와 FCS를 교체한다. 그리고 이전과 같은 방식으로 네트워크 내부에서 라우터를 향해 이동하고 목적지가 속한 네트워크에 도달할 때까지 라우팅 과정을 수행하게 된다.
라우팅 과정에서 목적지가 속한 네트워크에 도달하면 ARP가 주소 해석을 통해 목적지 호스트의 MAC 주소를 구한다. 이번에 교체되는 이더넷 헤더에는 최종 목적지의 MAC 주소가 포함되며, 레이어2 스위치를 거쳐 최종 목적지에 도달하게 된다.
드디어 친구 집으로 선물이 도착했다. 설레는 마음으로 포장을 풀어보자.
출발지에서 데이터를 캡슐화했던 프로토콜들이 목적지에서는 역캡슐화를 수행한다. 도착한 이더넷 프레임은 먼저 출발지와 동일한 계산을 수행하고 FCS와 비교해 데이터 손상 여부를 확인한다. 이상이 없다면 이더넷 헤더를 역캡슐화하고 IP에게 전달한다. IP 주소와 포트 번호를 확인하면서 캡슐화 진행 순서의 역순으로 헤더를 제거한다. 이 모든 과정을 거치고 나면, 서버에 배치된 웹 애플리케이션으로 HTTP 메시지가 도달하게 된다.
사용자 PC에서 서버까지 물리적으로 어떻게 이동하는지 알아보았다. 아래 그림과 함께 전체적인 흐름을 간단하게 정리해 보자.
준비과정
먼저 DNS를 통해 목적지 IP 주소를 전달받고, 목적지로 전송할 데이터를 IP 패킷으로 만든다. 이 과정에서 HTTP 메시지와 TCP 커넥션이 생성된다.
네트워크 내부 이동
목적지까지 도달하려면 실제 배선으로 이동해야 한다. ARP를 통해 목적지로 도달할 수 있는 경유지(라우터)의 MAC 주소를 전달받고 이더넷 프레임을 생성한다. 이더넷 프레임은 네트워크 인터페이스를 통해 물리적인 신호로 전환되고, 레이어2 스위치를 거쳐 라우터에 도달한다.
네트워크 외부 이동
라우터는 동일한 네트워크 내부에 목적지가 존재하는지 확인하고, 없다면 다음 이동할 라우터를 판단한다. 이때, 다른 네트워크로 이동하기 때문에 이더넷 헤더와 FCS는 새로 교체된다.
목적지 네트워크 도착
반복되는 라우팅 끝에 목적지가 속한 네트워크에 도달하면, ARP를 통해 목적지의 MAC 주소를 전달받는다. 그리고 레이어2 스위치를 거쳐 실제 목적지 장비에 도달하게 된다.
역캡슐화
준비과정에서 캡슐화했던 순서의 역순으로 역캡슐화를 진행한다. MAC 주소, IP 주소, 포트 번호를 확인한 후, 서버 측에 배치된 애플리케이션으로 HTTP 메시지가 전달된다.
https://www.geeksforgeeks.org/tcp-ip-model/?ref=lbp
https://developer.mozilla.org/en-US/docs/Glossary/TCP_handshake
https://egstory.net/edge-study/tech-lesson/aos-cx-switching/368/
그림으로 배우는 네트워크 Network 원리(Gene, 2020, Ch2-6)