앞으로 네 번에 걸쳐서 IP 패킷과 IP 패킷 헤더(header) 정보를 중점적으로 다룰 것이다. 이번 글에서는 계층-3(layer-3)과 계층-4(layer-4) 헤더의 다양한 필드를 소개하며, 다음 기사에서는 “tcpdump" 유틸리티를 사용하여 오늘 다룬 정보를 확인할 것이다. 그러면 오늘의 기사가 패킷 필터 규칙 및 방화벽과 어떻게 관련되는지 더 잘 알 수 있으리라 생각한다.
FreeBSD 시스템은 네트워킹 프로토콜로 TCP/IP를 사용한다. 프로토콜의 정의에 대해 가장 잘 나와 있는 곳은
www.whatis.com이며, 여기에 일부를 인용했다.
“정보 기술에서 프로토콜(protocol, 필사본에 붙어서 책의 내용을 알려 주는 페이지를 나타내는 그리스어의 protocollon에서 비롯되었음)은 원격 통신 연결의 종점(end point) 간에 통신할 때 사용하는 일련의 특별 규칙이다. 통신시 프로토콜은 여러 계층에 있으며, 각각의 기능 계층과 통신 중인 다른 계층 사이에는 같은 프로토콜이 있어야 한다. 프로토콜은 산업 및 국제 표준으로 묘사되기도 한다.”
FreeBSD 시스템에서 네트워크 연결로 데이터를 전송하기 전에, TCP/IP 프로토콜이 먼저 이 데이터를 IP 패킷으로 묶어야 한다. IP 패킷은 데이터 앞부분에 추가한, 라벨 정보가 있는 데이터의 덩어리일 뿐이다. 그리스어 protocollon처럼 헤더(header)라고 하는 이 라벨이 붙은 정보는, 헤더 뒤에 나오는 데이터를 나타낸다.
IP 패킷에는 하나 이상의 헤더가 있다. 이 헤더는 IP 헤더라고 부르는데, 때로는 Layer 3이나 네트워크 헤더로 부르기도 한다. IP 헤더는 집합 크기에 따른 필드로 그룹화된 일련의 비트(bit)이다. 모든 IP 헤더는 같은 구조를 띄며, 필드값을 결정하거나, 필드 내 이진수를 나타내기 위해 어떤 집합을 “1”로 정하느냐에 따라 차이가 나타난다. IP 헤더의 필드를 좀더 자세히 살펴보자.
IP 패킷에는 14개의 필드가 있다. 각 필드는 다음과 같다.
버전(Version)
4 비트 필드로, 바이너리 IP 버전을 의미한다. IPv4를 사용하고 있다면 비트는 0100으로 설정되며, IPv6을 사용하고 있다면 비트는 0110으로 설정된다.
IHL(헤더 길이)
이 4비트 필드는 IP 패킷 헤더의 길이를 나타내는데, IP 패킷의 어떤 부분이 헤더이며, 어떤 부분이 실제 데이터인지 구분하는 데 사용한다. IP 패킷 그림을 보면 IP 패킷의 넓이가 32비트라는 것을 알 수 있다. 이제 패킷의 길이를 살펴보자. 데이터는 헤더의 일부가 아니며 옵션은 선택적이지만, 다른 필드는 필수적이다. 그래서 헤더는 최소한 5개의 32비트 워드(word)이거나, 이진 0101이 되어야 한다. 단어는 바이트(byte)로 나타낼 수도 있다. 이때 1워드는 4바이트에 해당하므로(1바이트는 8비트임), 5워드는 20바이트의 헤더 길이가 된다. 옵션을 사용하면, 헤더 길이는 최소한 6개 32비트 워드가 된다. 이 필드는 4비트이기 때문에, 최소한의 길이는 2^4-1, 즉 15가 된다. 이로써 IP 패킷의 길이는 60바이트로 제한된다(4바이트가 1워드임).
서비스 유형(TOS) 플래그
필드 길이는 8비트이다. 앞의 3비트는 우선순위 비트이고, 뒤의 5비트는 서비스 유형 플래그를 나타낸다. 이 플래그는 원래 라우터가 바쁠 때, 전달할 패킷과 그대로 둘 패킷을 결정하기 위해 만들었다. 그 이후로 다른 프로토콜은 트래픽에 우선순위를 정하는 기능을 갖게 되었고, 라우터는 대부분 플래그가 설정되어 있어도 이를 무시해 버린다.
전체 길이(패킷 길이, 혹은 데이터그램 길이)
이 16비트 필드는 IP 패킷의 전체 길이로, 데이터와 헤더 둘 다 나타낸다. 최소한의 길이는 21바이트(디폴트 헤더 길이와 데이터의 1바이트의 합)이다. 필드 길이가 16비트이므로, 최대한의 패킷 크기는 2^16-1, 즉 65,535바이트이다. (0에 대한 길이 값은 나타날 수 없으므로, 1을 빼 준다.)
식별(identification)
모든 IP 패킷은 생성될 당시, 식별 번호(identification number)를 부여받는다. 번호는 16 비트 필드 안에 있다. IP 패킷은 더 작은 “프래그먼트(fragment)"로 분리되어 목적지에 전송된다. 각각의 프래그먼트는 원래의 IP 패킷에 속해서 고유 번호가 같기 때문이다.
플래그
필드에는 다음과 같은 플래그 3개가 포함되어 있다.
- reserved flag: 항상 0으로 설정
- don"t fragment flag: 0으로 설정하면, IP 패킷을 분할한다. 1로 설정하면, IP 패킷을 분할하지 않는다.
- more fragments flag: 0으로 설정되면, 더 이상의 프래그먼트는 없다는 뜻이며, 1로 설정되면 아직 수신되지 않는 IP 패킷이 있다는 뜻이다.
프래그먼트 오프셋(Fragment offset)
IP 패킷이 프래그먼트로 되면, 각각의 단락은 원래의 IP 패킷의 정보를 나타내는 13비트 필드 내에서 값을 갖게 된다. 예를 들어, 128바이트의 데이터를 포함하는 IP 패킷이 두 개의 프래그먼트로 되었고, 각각 64바이트의 데이터를 포함한다고 가정해 보자. 앞의 64데이터를 포함하는 프래그먼트는 데이터가 원래의 IP 패킷에 속하는 것이므로, 오프셋이 0이 될 것이다. 뒤의 64바이트 데이터를 포함하는 프래그먼트는 앞의 64바이트 다음에 시작하는 것임을 나타내 주어야 한다. 이 필드의 넘버가 8바이트를 곱해준 수를 나타내므로, 프래그먼트 오프셋은 8이 된다(8*8=64).
생존기간(TTL)
IP 패킷이 라우터를 지나칠 때마다, 라우터는 TTL값을 1씩 감소시킨다. 그래서 TTL이 0이 되면, 패킷은 더 이상 전송하지 않는다. 지금까지 전송되지 않는 것은 전송할 수 없다고 생각하는 것이다. 원래의 TTL값은 운영체제에 따라 다르다. FreeBSD의 경우 디폴트 TTL은 64이다. 이는 8 비트 필드라서 TTL은 최대 255까지 될 수 있다(2^18-1, 0에 대한 TTL은 있을 수 없으므로, 1을 빼 준다).
프로토콜
이 8 비트 값은 어떤 IP 패킷에 프로토콜의 데이터가 들어 있는지, 패킷의 데이터 영역에 어떤 정보 유형이 들어 있는지를 알려 준다. 필드에 나타나는 프로토콜 넘버는 FreeBSD의 "/etc/protocols" 파일에 있다.
프로토콜 넘버 1은 ICMP(인터넷 제어 메시지 프로토콜)임을 나타낸다. 이는 IP 패킷에 애플리케이션으로부터 온 데이터가 하나도 없다는 뜻이다. 그 대신 약간의 ICMP 정보가 들어 있다. 앞으로의 기사에서 ICMP에 대해서, 그리고 ICMP가 방화벽에 어떤 영향을 미치는지 자세히 살펴 볼 것이다.
프로토콜 넘버 6은 TCP 프로토콜을 나타낸다. 이미 알겠지만, TCP는 전송 제어 규약(Transport Contrl Protocol)이다. 이 IP 패킷은 TCP 헤더라는 또 다른 헤더가 있는데, IP 헤더 바로 뒤, 전송되는 실제 데이터 초반부 앞에 위치한다.
프로토콜 넘버 17은 UDP 프로토콜을 나타내는데, UDP는 비연결 전송(connectionless transport)이다. 이 IP 패킷에는 UDP 헤더가 있는데, IP 헤더 바로 뒤, 전송되는 데이터 앞에 위치한다.
헤더 체크섬(Checksum)
IP 헤더가 생성되거나 수정될 때마다 CRC(주기적 덧붙임 검사)는 IP 헤더 내 비트를 검사한다. 기본적으로 체크섬이라는 결과로 나타나는 수학적 프로세스(CRC 알고리즘)가 일어난다. IP 패킷이 전송되면, 똑같은 CRC 과정이 헤더에서 반복된다. 만약 결과가 똑같이 나타난다면(체크섬), IP 헤더의 모든 비트는 정확하게 전송된 것이다. 결과가 다르게 나타나면, 헤더의 비트 일부가 전송되지 않은 것이며, 이는 전송 중에 IP 패킷이 일부 손상되었다는 뜻이다.
송신지 주소(Source Address)
IP 패킷을 전송하는 호스트의 IP 주소이다.
목적지 주소(Destination Address)
IP 패킷에 들어 있는 데이터를 수신하는 호스트의 IP 주소이다.
옵션(option)과 패딩(padding)
IP 패킷에서 유일한 선택 사항으로, IP 헤더의 다른 필드가 하지 못하는 특별한 전송 명령을 제공한다. 40바이트까지 부가적으로 명령할 수 있지만 32비트 워드 내여야 한다. 명령이 32비트 워드가 안되면, 나머지 비트는 “패딩” 비트로 채워진다.
데이터
IP 패킷의 마지막 필드는 데이터 필드이다. 이는 하나의 호스트에서 다른 호스트로 전송되는 실제 데이터이다. 데이터 필드는 Layer 4 헤더로 시작하는데, 데이터를 받게 되는 애플리케이션에 부가적인 명령을 내린다. 혹은 사용자 정보를 하나도 포함하지 않은 ICMP 헤더일 수도 있다.
지금까지 Layer 3(IP) 헤더에 관해 살펴보았으니, 이제부터는 Layer 4 헤더에 대해 알아보자. Layer 4 헤더는 IP 데이터 필드의 초반부에 있으며, TCP 헤더나 UDP 헤더가 될 수 있다. Layer 4 TCP 헤더에 있는 필드부터 시작하자.
TCP 헤더 역시 32비트 워드로 구성된다. 기본 크기는 옵션 필드를 사용하지 않았을 때, IP 헤더와 마찬가지로 20바이트이다. TCP 헤더에서 사용할 수 있는 필드를 간략히 살펴보자.
송신지 포트(Source Port)
이 16비트 숫자는 IP 패킷에서 데이터를 전송하는 애플리케이션의 이름을 나타낸다. FreeBSD 시스템의 /etc/services 파일은 애플리케이션이 어떤 포트 넘버를 사용하는지 보여 준다. 포트 넘버는 65,535개까지 사용할 수 있다(2^16 -1)
목적지 포트(Destination Port)
이 16비트 넘버는 IP 패킷에 포함되어 있는 데이터를 수신하는 애플리케이션명을 나타낸다. 이것이 Layer 3과 Layer 4 헤더의 주요 차이점이다. Layer 3 헤더는 IP 패킷을 수신하는 컴퓨터의 IP 주소를 포함하고 있다. 이에 반해 패킷을 전송받으면, Layer 4 헤더의 포트 주소는 IP 패킷에 포함되어 있는 데이터가 컴퓨터의 정해진 애플리케이션으로 전송되었는지 확인해 준다.
일련 번호(Sequence Number)
TCP는 전송한 모든 IP 패킷을 실제로 수신국에 전달한다. 애플리케이션의 데이터가 IP 패킷으로 분할되면, TCP는 분할된 IP 패킷에 일련 번호를 부여한다. 수신 컴퓨터가 모든 패킷을 전송받으면, TCP는 이 32비트 필드의 넘버로 모든 패킷이 실제로 전송되었고, 순서(sequence)도 올바르다는 사실을 확인해 준다.
확인 번호(Acknowledgement Number)
수신 컴퓨터가 어떤 패킷이 성공적으로 전송되었는지를 확인하는 번호이다. 이 번호는 수신되는 다음 패킷의 일련 번호이다.
헤더 길이, 혹은 오프셋
TCP헤더의 길이를 나타낸다는 것만 제외하면, IP 패킷의 헤더 길이와 개념이 같다.
예약(Reserved)
이 6 비트는 사용되지 않으며, 항상 0으로 설정되어 있다.
제어 플래그(Control Flags)
TCP는 6개의 제어 플래그를 사용하는데, 각각의 플래그는 고유한 비트이다. 비트가 1로 설정되어 있으면, 플래그는 켜져 있다. 비트가 0으로 설정되어 있으면, 플래그가 꺼져 있다는 뜻이다. 플래그 순서는 다음과 같다.
- URGent
- ACKnowledgement
- PuSH
- ReSeT
- SYNchronize
- FINish
"tcpdump"를 운용할 때나, 패킷 필터 규칙을 만들 때 이러한 플래그를 다시 보게 될 것이다.
윈도우 크기(Window Size)
모든 TCP 패킷에는 한번에 어느 정도의 옥텟(octet)을 받을 수 있는지를 나타내는 16 비트 값이 있다. IP 패킷이 전송되면, 옥텟은 수신 컴퓨터가 처리하기까지 버퍼로 알려진 RAM의 임시 구역에 있게 된다. 이 수치는 수신 호스트가 IP 패킷의 임시 저장할 수 있는 버퍼의 용량을 나타낸다.
체크섬(Checksum)
IP와 달리, TCP는 전체 IP 패킷을 수신했는지 확인해 준다. TCP는 (헤더 뿐 아니라) 전체 IP 패킷에서 CRC을 운영해서, 나타나는 체크섬을 이 필드에 보여 준다. IP 패킷이 전송되면, TCP는 전체 패킷에서 이러한 CRC를 다시 운영해서 체크섬이 같은지 확인한다.
긴급 포인터(Urgent Pointer)
만약 Urgent 플래그가 켜지도록 설정되어 있으면, 이 값은 urgent 데이터가 어디에 있는지를 나타낸다.
옵션(Option)과 패딩(Padding)
IP 옵션과 마찬가지로, 이 필드는 선택 사항이며, 다른 TCP 필드가 하지 못하는 부가적인 명령을 내린다. 여기에서도 옵션이 32비트 워드를 채우지 못하면, 패딩 비트로 채워진다.
데이터
실제로 전송되는 데이터로, 부가적인 헤더는 포함하지 않는다.
마지막으로 Layer 4 UDP 헤더를 살펴보자. TCP와 달리, UDP는 비접속 전송이며, 데이터가 전송되는지 확인하지도 않는다. 그래서 UDP 헤더에는 TCP 헤더에 비해 약간의 필드만 있다.
UDP 헤더에는 옵션이 없기 때문에 항상 8바이트이다. UDP 헤더 필드는 다음과 같다.
송신지 포트(Source Port)
TCP와 마찬가지로 이 필드는 어떤 애플리케이션이 IP 패킷에 포함된 데이터를 전송했는지를 나타낸다.
수신지 포트(Destination Port)
TCP와 마찬가지로 어떤 애플리케이션이 IP 패킷에 포함된 데이터를 수신할 것인지를 나타낸다.
길이
UDP 헤더와 데이터의 길이(바이트)를 나타낸다. 모든 UDP 헤더가 8바이트이기 때문에, 이 수치에서 8을 빼면 전송된 데이터의 길이를 알 수 있다.
체크섬(Checksum)
UDP는 데이터가 확실히 전송되었는지 확인하지 않으므로, 체크섬은 선택 사항이다. 사용하지 않으면, 이 필드는 0으로 설정된다.
데이터
여기에서도 전송되는 실제 데이터이며, 부가적인 헤더는 포함하지 않는다.
지금까지 IP 패킷의 Layer 3과 Layer 4에 있는 모든 필드를 살펴보았다. 다음주에 tcpdump 유틸리티로 생성한 덤프 파일(dump file)에 대해 알고 나면, 이러한 필드를 더 잘 이해하게 될 것이다.
드루 래빈(Dru Lavigne)은 온타리오주, 킹스톤(Kingston, ON)의 사설 기술 칼리지에서 네트워킹을 강의한다. 테스트 머신에서 한번에 몇 개의 운영 체제를 멀티부팅하는지 증명하는 것으로도 유명하다.