CS/Network

네트워크 계층: IP

olsohee 2024. 3. 28. 13:07

네트워크 계층, IP 프로토콜

네트워크 계층의 대표적인 프로토콜은 IP(Internet Protocol)이고, 전송 단위는 패킷이다.

 

패킷의 데이터 부분에 전송 계층의 세그먼트가 담기게 된다. 즉 패킷의 구성은 "IP 헤더(20바이트) + TCP 헤더(20바이트) + 애플리케이션 메시지"라고 할 수 있다. 즉, IP 패킷의 최소 크기는 애플리케이션 메시지를 제외한 40바이트이다. 실제로 네트워크 상에 돌아다니는 IP 패킷을 보면 40바이트 크기의 패킷을 발견할 수 있는데, 그 예로 데이터를 잘 받았다는 피드백의 ACK 용도인 패킷이 있다.

 

IP 프로토콜의 특징은 다음과 같다.

  • 상위 계층에서 전송받은 데이터에 헤더를 붙여 패킷을 만든다.
  • 비연결형 프로토콜로 패킷을 수신지까지 전송하지만 전송 완료를 보장하지는 않는다. 
  • 각각의 패킷은 독립적으로 처리된다. 따라서 도착 순서가 보장되지 않으며, 목적지가 같더라도 항상 같은 경로를 따라가지 않는다.
  • 패킷의 경로는 사전에 설정되는 것이 아니라, 각 노드에서 라우팅 과정을 통해서 경로가 설정된다.

IP 주소

IP 주소는 무엇일까? IP 주소는 정확히는 특정 호스트(디바이스)를 지칭하는 것이 아니라, 네트워크와의 연결을 위한 인터페이스를 지칭한다고 할 수 있다. 대부분의 디바이스는 1개의 인터페이스를 갖지만 라우터의 경우 여러 개의 인터페이스를 갖는다. 따라서 라우터는 여러 개의 IP 주소를 갖는다.

IP 주소의 계층화 (네트워크 주소 + 호스트 주소)

그러면 IP 주소를 어떻게 배정할까? 만약 IP 주소를 임의로 막 배정하면, 라우터의 포워딩 테이블에 각 IP 주소를 하나씩 적어주어야 할 것이다. IP 주소를 임의로 배정했기 때문에 네트워크 위치에 따라 IP 주소를 범위로 묶을 수 없기 때문이다. 따라서 IP 주소가 많아질수록 포워딩 테이블의 크기가 비대해지고, 매칭하는 시간도 매우 오래 걸릴 것이다.

따라서 IP 주소는 계층화되어 있다. 32비트의 IP 주소를 2개로 나눠, 네트워크 주소와 호스트 주소로 나눈다. 

  • ex, 00001100 00100010 10011110 00000101 (12 34 158 5)
  • 앞에 24비트를 네트워크 주소, 뒤의 8비트를 호스트 주소라고 정의

따라서 같은 네트워크를 쓰는 IP 주소들은 모두 같은 네트워크 주소를 갖는다. 또한 IP 주소의 계층화를 통해 포워딩 테이블이 단순해지고 관리가 쉬워지며, 매칭도 빨라진다.

IP 주소의 계층화를 통해 어디까지가 네트워크 주소이고, 어디까지가 호스트 주소인지 구분할 필요가 생겼다. 따라서 이를 구분하기 위한 것이 서브넷 마스크이다.

 

각 기관마다 필요한 네트워크 사이즈가 다르다. 예를 들어 회사에 IP 주소가 10,000개가 필요한데 네트워크 주소가 24비트인 IP 주소를 사용하면, 2^8개의 IP 주소로는 부족하다. 

따라서 어디까지를 네트워크 주소로 하고 어디까지를 호스트 주소로 할지를 고정해서 정의해 둘 수는 없다. (예전에는 클래스로 나누어 A 클래스는 8비트까지 네트워크 주소, B 클래스는 16비트까지 네트워크 주소로 나눴다. 그러나 특정 클래스로 고정하면, 그 이상의 IP 주소가 필요한 경우가 생길 수도 있고, 그만큼의 IP 주소가 필요없는 경우가 생길 수도 있다.)

 

따라서 네트워크 크기를 고정하지 않고 네트워크를 각 기관에 배정할 때, 기관 사이즈에 맞게 네트워크 주소의 크기를 설정한다. (ex, 해당 기관의 네트워크 주소는 17비트)

 

따라서 라우터 내의 포워딩 테이블은 prefix(= 네트워크 아이디, 서브넷) 단위로 엔트리가 형성된다.

예를 들어 도착지 IP 주소가 201.10.6.17일 때 다음 포워딩 테이블에서는 201.10.0.0/21에도 해당되고 201.10.6.0/23에도 해당된다. 여러 개가 해당되는 경우에는 더 많은 비트 수가 일치하는 것을 채택한다. 즉, 23개의 비트가 일치하는 201.10.6.0/23에 맞춰서 아웃풋된다.

다음 사진에서 파란색으로 칠해진 각 구역의 IP 주소는 모두 같은 서브넷을 갖는다. 즉, 모두 같은 네트워크 주소, prefix를 갖는다. 따라서 이들 간에는 서로 라우터를 거치지 않고 접근 가능하다.

그리고 위 사진을 보면 알 수 있겠지만, 하나의 라우터는 여러 개의 인터페이스를 가지며 여러 개의 IP 주소를 갖는다. 그리고 이때 여러 개의 IP 주소는 모두 다른 prefix를 갖는다. 즉, 보통의 디바이스는 하나의 서브넷에 속하지만, 라우터는 특별하게 여러 개의 서브넷에 속할 수 있다.

 

그러면 다음 사진에서는 서브넷이 몇 개일까?

파란색으로 칠해진 구역의 수로 총 6개이다.

IP 프로토콜 버전

IPv4

네트워크 계층에서 서로 다른 네트워크 간 통신을 위해서는 패킷의 헤더에 송신지의 IP 주소와 수신지의 IP 주소를 추가해야 한다. 이때 IP 주소는 각 네트워크의 고유 주소인데, IP 주소 체계로 IPv4와 IPv6가 있다. 현재 주로 사용하는 IP 주소 체계는 IPv4이다.

 

IPv4의 IP 주소는 2진수의 32비트(4바이트) 숫자이다. 그리고 사람이 읽기 쉽게 32비트를 4개의 바이트로 나누어서 각 바이트를 10진수로 표현한 것이 IPv4이다. 따라서 IP 주소의 값은 0.0.0.0부터 255.255.255.255 사이의 값이 된다. 

 

IPv4는 다음과 같은 헤더를 갖는다.

  • Version
    • IP 프로토콜의 버전을 나타낸다. (IPv4, IPv6)
  • Identification, Flags, Fragment Offset
    • 단편화시 필요한 필드이다. 
  • Time To Live(TTL)
    • 패킷이 네트워크에서 생존할 수 있는 시간을 의미한다.
    • 패킷이 라우터를 통과할 때마다 라이프 타임 필드 값이 1씩 감소하며, 값이 0이 되면 라우터는 해당 패킷을 폐기한다.
    • 따라서 수신지를 찾지 못한 패킷이 계속 라우터에 존재하여 네트워크 트래픽을 증가시키는 것을 막을 수 있다.
  • Protocol
    • IP 계층의 서비스를 사용하는 상위 계층의 프로토콜이 무엇인지를 의미한다. 
    • 예를 들어 프로토콜 필드 값이 4이면 패킷의 데이터 영역에는 UDP 세그먼트가 들어 있다.

IPv6

IPv4는 32비트의 주소이므로, 2^32개의 호스트만 가질 수 있다. 따라서 IPv4의 주소 고갈이 우려되었으며, 이로 인해 등장한 것이 IPv6이다. IPv6의 IP 주소는 128비트로 구성되며, 16비트씩 콜론(:)으로 나누어 총 8개의 영역으로, 각 영역을 16진수로 표현한다.

NAT(Network Address Translation)

IPv4의 주소 고갈 문제에도 여전히 IPv4가 사용되고 있다. 그 이유는 무엇일까?

 

우선 IPv4를 IPv6로 바꾸는 건 현실적인 어려움이 있다. 현재의 라우터는 IPv4 형태의 포맷만 인식 가능하므로, IPv6를 위한 라우터로 변경해야 한다. 그런데 수많은 라우터들이 존재하고 이들의 소유자가 모두 다르기 때문에 이는 현실적으로 불가하다.

 

그렇다면 주소 고갈 문제에도 여전히 IPv4를 문제없이 사용할 수 있는 이유는 무엇일까? 바로 NAT(Network Address Translation) 덕분이다. NAT은 네트워크 주소 변환 기술로, IP 주소 고갈 문제를 해결한다.

  • NAT에서는 같은 네트워크 내에서만 유니크한 IP 주소를 갖는다. 즉, 내가 속한 네트워크에서 나의 IP 주소는 유일하지만, 외부로 나가면 나와 동일한 IP 주소가 있을 수 있다.
  • 따라서 나의 IP 주소가 source IP 주소로 적혀서 외부 네트워크로 나가면, 중복된 IP 주소로 응답이 제대로 돌아오지 않는다.
  • 따라서 내부망에서 외부망으로 통신할 때, 출발지의 private IP 주소를 public IP 주소로 변환하여 외부로 나간다.
  • 마찬가지로 외부망에서 내부망으로 돌아올 때는, 도착지의 public IP 주소를 private IP 주소로 변환한다.
  • 예를 들어 대학 캠퍼스 내의 학생들이 와이파이를 통해 구글 서버에 접속하면? 모두 같은 네트워크에 존재하므로 이들의 IP 주소는 서버 입장에서 동일하다. 반면 SK LTE를 통해 구글 서버에 접속하면? 서버 입장에서 모두 같은 SK IP 주소로 동일하다. 

NAT의 동작 방식을 알아보자.

  1. 10.0.0.1이 외부로 패킷을 보내려 한다.
  2. NAT 라우터는 source IP 주소와 포트 번호를 변환하고 테이블에 기록한다. (10.0.0.1, 3345 ➡️ 138.76.29.7, 5001)
  3. 응답이 돌아올 때 dest IP 주소가 138.76.29.7이므로 NAT 라우터까지 패킷이 돌아온다.
  4. NAT 라우터는 테이블을 참고하여 IP 주소가 138.76.29.7이고 포트 번호가 5001인 정보를 찾아 변환시켜 포워딩한다. (138.76.29.7, 5001 ➡️ 10.0.0.1, 3345)

NAT을 사용하는 이유는 다음과 같다.

  • 사설 네트워크에 속한 여러 호스트가 하나의 public IP 주소를 사용하기 때문에 public IP 주소를 절약하여 주소 고갈 문제를 해결할 수 있다.
  • private IP 주소를 외부로 노출시키지 않음으로써 보안을 강화할 수 있다.

그러나 주소 고갈 문제를 IPv6로 바꾸어 근본적으로 해결하지 않았기 때문에, NAT에도 문제가 있다.

  • 외부에서 찾아 들어갈 수 없다. 
    • 예를 들어 외부에서 10.0.0.1, 3345로 패킷을 보내더라도, 이는 전세계적으로 유니크한 IP 주소가 아니기 때문에 도착하지 못한다.
    • 그러면 public IP 주소인 138.76.29.7, 3345로 패킷을 보낸다면? 이 경우 public IP 주소가 올바르기 때문에 해당 NAT 라우터까지는 패킷이 도착할 것이다. 그러나 NAT 라우터의 테이블에 매칭되는 정보가 기록되어 있지 않기 때문에 도착하지 못한다.
    • 즉, 테이블에 변환 정보가 기록되어 있어야 한다. 그런데 이 기록은 내부에서 외부로 패킷을 보낼 때 기록되기 때문에 외부에서 먼저 찾아 들어올 수는 없다.
  • 네트워크 계층화를 깨뜨린다.
    • NAT을 사용하면 NAT 라우터에서 패킷의 IP 주소와 포트 번호를 바꾼다.
    • 이때 IP 주소는 패킷의 헤더에 담기고 포트 번호는 TCP 세그먼트의 헤더에 담긴다.
    • 즉, NAT 라우터가 패킷의 데이터 부분을 열어서, 세그먼트의 헤더를 열어 포트 번호를 바꾼다. 
    • 즉, 전송 계층에서 담은 정보를 네트워크 계층에서 수정하는 문제가 발생한다.
  • 포트 번호로 호스트를 구분하는 문제가 발생한다.
    • 기존에 호스트 간의 구분은 IP 주소로 했다.
    • 그러나 NAT을 사용하면 하나의 네트워크 내의 호스트들은 모두 같은 public IP를 사용하고, 이들을 포트 번호로 구분한다.
    • 즉, IP 주소가 아닌 포트 번호로 호스트를 구분하는 이상한 기준이 생긴다.

DHCP(Dynamic Host Configuration Protocol)

NAT에 대해 알아봤으니, 이런 궁금증이 들 수 있다. "그러면 내가 속한 네트워크에서 나의 사설 IP 주소는 언제 할당받는가?" 즉, 만약 스타벅스에서 노트북을 열면, NAT을 통해 나는 스타벅스 네트워크 내에서 고유한 IP 주소를 사용할 것이다. 그러면 이 IP 주소는 어떻게 언제 받게 되는 걸까? 이때 사용되는 것이 DHCP이다. DHCP는 호스트가 네트워크에 접속할 수 있도록 IP 주소와 각종 기본 설정을 제공해준다.

  1. discover
    • 클라이언트가 DHCP 서버에게 요청한다. 이때 브로드캐스트로 요청한다.
      • source IP 주소: 0.0.0.0 (아직 정해지지 않았으므로)
      • dest IP 주소: 255.255.255.255 (브로드캐스트)
      • source MAC 주소: 자신의 MAC 주소
      • dest MAC 주소: FF-FF-FF-FF-FF (브로드캐스트)
    • 브로드캐스트로 인해 네트워크 내의 모든 호스트가 해당 요청을 받게 된다. 그러나 해당 포트번호(67)가 열려 있지 않은 호스트들은 해당 소켓이 없으므로 요청을 드롭한다. 따라서 포트가 열려 있는 DHCP 서버만 해당 요청을 받게 된다.
  2. offer
    • 요청을 받은 DHCP 서버는 클라이언트에게 IP 주소를 제공한다.
      • source IP 주소: DHCP 서버의 IP 주소
      • dest IP 주소: 255.255.255.255 (브로드캐스트)
      • source MAC 주소: DHCP 서버의 MAC 주소
      • dest MAC 주소: FF-FF-FF-FF-FF (브로드캐스트)
    • 만약 여러 클라이언트가 DHCP 서버에게 discover 요청을 했다면, 여러 호스트에서 68번 포트가 열려 있을 것이다. 그러면 해당 offer 응답은 IP 주소가 브로드캐스트 주소에 포트번호 68인데, 어떻게 여러 호스트 중 딱 하나의 호스트에만 도착할 수 있는 것일까? 이때 사용되는 것이 transaction ID이다. 이를 통해 transaction ID가 654에 대한 응답이라는 것을 알 수 있다. 
  3. request
    • 클라이언트는 offer에 대한 요청을 한다.
      • source IP 주소: 0.0.0.0 (아직 정해지지 않았으므로)
      • dest IP 주소: 255.255.255.255 (브로드캐스트)
      • source MAC 주소: 자신의 MAC 주소
      • dest MAC 주소: FF-FF-FF-FF-FF (브로드캐스트)
    • discover - offer에서 끝나지 않고 request 작업이 필요한 이유는 무엇일까?
      • 예를 들어 스타벅스에서 DHCP 서버와 통신 과정이 일어날 때, discover할 때 옆에 있는 이디야의 DHCP 서버에도 브로트캐스트되어 요청이 갔을 수도 있다. 
      • 따라서 클라이언트는 여러 DHCP 서버로부터 여러 개의 offer를 받을 수 있기 때문에 그 중 하나를 선택하여 요청하는 request 과정이 필요하다.
  4. ACK
    • DHCP 서버는 ACK을 전송한다.
      • source IP 주소: DHCP 서버의 IP 주소
      • dest IP 주소: 255.255.255.255 (브로드캐스트)
      • source MAC 주소: DHCP 서버의 MAC 주소
      • dest MAC 주소: FF-FF-FF-FF-FF (브로드캐스트)
    •  ACK을 수신한 클라이언트는 자신의 IP 주소 뿐만 아니라 게이트웨이 라우터의 IP 주소, DNS 서버의 IP 주소를 획득하게 되고, 인터넷 사용이 가능하게 된다.

단편화(Fragment)

단편화를 이해하기 위해서는 먼저 MTU를 알아야 한다. MTU(Maximum Transmission Unit)은 데이터 링크 계층에서의 데이터 단위인 프레임의 최대 크기이다. 따라서 패킷을 데이터 링크 계층으로 전송할 때는 MTU 크기에 맞춰 패킷을 쪼개서 전달해야 한다. 이를 단편화라고 한다. 쪼개진 각 패킷들은 독립적으로 수신지까지 전송된다. 그리고 수신지의 전송 계층에 도착하기 전에 재조립된다.

 

따라서 패킷이 MTU보다 큰 경우, 패킷이 쪼개지는데, 패킷 도착 후 쪼개진 패킷들을 재조립하기 위한 정보들이 패킷 헤더의 Identification, Flags, Offset 필드에 담긴다.

 

예를 들어 4000 바이트 크기의 패킷이 전송되는데, MTU가 1500 바이트라고 가정하자. 이때 4000 바이트의 패킷은 헤더 20 + 데이터 3980이다. 따라서 MTU 크기에 맞춰 쪼개지면 다음과 같다.

  • 헤더 20 + 데이터 1480
  • 헤더 20 + 데이터 1480
  • 헤더 20 + 데이터 1020

그리고 각 헤더에 패킷 재조립을 위한 정보를 담아준다. 

  • Identification: 3개의 패킷이 하나의 패킷이라는 것을 나타내기 위해 모두 같은 ID를 갖는다.
  • Flags: 1이면 뒤에 더 붙을 패킷이 있다는 의미이고, 0이면 없다는 의미이다.
  • Offset: 현재 패킷이 재조립될 때 어느 위치에 있어야 하는지를 나타낸다. 이때 헤더 데이터 크기를 줄이기 위해 8로 나눈 값을 해당 필드에 저장한다. 
    • 첫 번째 패킷: 0 ~ 1479 ➡️ 0
    • 두 번째 패킷: 1480 ~ 2959 ➡️1480 / 8 = 185
    • 세 번째 패킷: 2960 ~ 3980 ➡️ 2960 / 8 = 370

라우팅

네트워크 계층에서 데이터를 전송할 때 패킷이 거쳐가는 최적의 경로를 찾는 것을 라우팅이라 한다.

라우팅 테이블

라우팅 테이블은 목적지까지 가는 거리와 방법 등을 명시한 테이블이다. 라우터는 자신에게 온 패킷의 dest IP 주소와 라우팅 테이블을 참고하여, 적절한 곳으로 포워딩한다. 이때 포워딩이란, 라우터의 인풋 포트로 들어온 패킷을 적절한 아웃풋 포크로 내보내는 것을 말한다.

 

그리고 하나의 라우터에 여러 개의 인풋 포트가 있는데, 빠른 처리를 위해 인풋 포트마다 라우팅 테이블을 독립적으로 라우팅 테이블을 갖는다. 

 

하나의 라우터에는 여러 개의 인풋 포트가 있는데, 빠른 처리를 위해 각 인풋 포트마다 라우팅 테이블을 독립적으로 라우팅 테이블을 갖는다. 그리고 아무리 빠르게 처리한다고 하더라도 처리 속도보다 패킷이 들어오는 속도가 빠를 수 있기 때문에 각 인풋 포트마가 처리를 위한 큐를 갖는다.


Reference

'CS > Network' 카테고리의 다른 글

링크 계층  (0) 2024.03.30
전송 계층: UDP, TCP  (1) 2024.03.26
소켓(Socket)  (0) 2024.03.26
애플리케이션 계층: DNS  (1) 2024.03.26
애플리케이션 계층: HTTP  (0) 2024.03.26