본문 바로가기
Networking&K8S: A Layered Approach/2. Linux Networking

Packet Handling in the Kernel - Netfilter

by yeongki0944 2025. 2. 26.

Netfilter

  • Netfilter, included in Linux since 2.3, is a critical component of packet handling.
  • Netfilter is a framework of kernel hooks, which allow userspace programs to handle packets on behalf of the kernel.
    Netfilter는 사용자 공간(userspace) 프로그램이 커널을 대신하여 패킷을 처리할 수 있게 해주는 커널 훅(hook)의 프레임워크입니다.
  • In short, a program registers to a specific Netfilter hook, and the kernel calls that program on applicable packets. 
    간단히 말해, 프로그램이 특정 Netfilter 훅에 등록하면 커널은 해당되는 패킷에 대해 그 프로그램을 호출합니다.
    Netfilter hook에 등록??

  • Netfilter was created jointly with iptables, to separate kernel and userspace code.
    Netfilter는 커널 코드와 사용자 공간 코드를 분리하기 위해 iptables와 함께 공동으로 만들어졌습니다.

 

Triggers for packets where neither source nor destination matches the machine’s IP addresses
소스(출발지)도 목적지도 기기의 IP 주소와 일치하지 않는 패킷들에 대한 트리거

Triggers when a packet, originating from the machine, is leaving the machine.
기기에서 발생하여 기기를 떠나는 패킷이 있을 때 트리거됨

Triggers when any packet (regardless of origin) is leaving the machine.
출처에 상관없이 기기를 떠나는 어떤 패킷이 있을 때 트리거됨


Netfilter triggers each hook during a specific phase of packet handling, and under specific conditions, we can visualize Netfilter hooks with a flow diagram, as shown in Figure 2-2.
Netfilter는 패킷 처리의 특정 단계 동안 그리고 특정 조건에서 각 훅을 트리거합니다. Figure 2-2와 같이 흐름도를 통해 Netfilter 훅을 시각화할 수 있습니다.

We can infer from our flow diagram that only certain permutations of Netfilter hook calls are possible for any given packet.
우리는 흐름도로부터 어떤 주어진 패킷에 대해 Netfilter 훅 호출의 특정 조합들만 가능하다는 것을 추론할 수 있습니다



Note that if a process sends a packet destined for the same host, it triggers the NF_IP_LOCAL_OUT and then the NF_IP_POST_ROUTING hooks before “reentering” the system and triggering the NF_IP_PRE_ROUTING and NF_IP_LOCAL_IN hooks.

주의할 점은, 만약 프로세스가 같은 호스트를 목적지로 하는 패킷을 보내는 경우, 시스템에 '재진입(reentering)'하기 전에 NF_IP_LOCAL_OUT과 NF_IP_POST_ROUTING 훅을 트리거하고, 그 후에 NF_IP_PRE_ROUTING과 NF_IP_LOCAL_IN 훅을 트리거한다는 것입니다.


In some systems, it is possible to spoof such a packet by writing a fake source address (i.e., spoofing that a packet has a source and destination address of 127.0.0.1).
일부 시스템에서는 가짜 출발지 주소를 작성하여 이러한 패킷을 스푸핑하는 것이 가능합니다(즉, 패킷의 출발지와 목적지 주소가 127.0.0.1인 것처럼 속이는 것).

Linux will normally filter such a packet when it arrives at an external interface.
리눅스는 일반적으로 외부 인터페이스에 도착했을 때 이러한 패킷을 필터링합니다



More broadly, Linux filters packets when a packet arrives at an interface and the packet’s source address does not exist on that network.

더 넓게 말하자면, 리눅스는 패킷이 인터페이스에 도착했을 때 해당 패킷의 출발지 주소가 그 네트워크에 존재하지 않는 경우 패킷을 필터링합니다.

A packet with an “impossible” source IP address is called a Martian packet.
불가능한' 출발지 IP 주소를 가진 패킷은 '화성인 패킷(Martian packet)'이라고 불립니다

It is possible to disable filtering of Martian packets in Linux. However, doing so poses substantial risk if any services on the host assume that traffic from localhost is “more trustworthy” than external traffic.
리눅스에서 화성인 패킷(Martian packets)의 필터링을 비활성화하는 것이 가능합니다. 그러나, 호스트의 어떤 서비스가 로컬호스트에서 오는 트래픽이 외부 트래픽보다 '더 신뢰할 수 있다'고 가정하는 경우, 이렇게 하는 것은 상당한 위험을 초래합니다.

This can be a common assumption, such as when exposing an API or database to the host without strong authentication.
이것은 강력한 인증 없이 API나 데이터베이스를 호스트에 노출시킬 때와 같이 흔한 가정일 수 있습니다.



Note that packets from the machine to itself will trigger NF_IP_LOCAL_OUT and NF_IP_POST_ROUTING and then “leave” the network interface. They will “reenter” and be treated like packets from any other source.

Network address translation (NAT) only impacts local routing decisions in the NF_IP_PRE_ROUTING and NF_IP_LOCAL_OUT hooks (e.g., the kernel makes no routing decisions after a packet reaches the NF_IP_LOCAL_IN hook). We see this reflected in the design of iptables, where source and destination NAT can be performed only in specific hooks/chains.

주의할 점은 기기 자신에서 자신으로 가는 패킷은 NF_IP_LOCAL_OUT과 NF_IP_POST_ROUTING을 트리거한 다음 네트워크 인터페이스를 '떠나게' 됩니다. 그런 다음 '재진입'하여 다른 출처의 패킷처럼 처리됩니다.

네트워크 주소 변환(NAT)은 NF_IP_PRE_ROUTING과 NF_IP_LOCAL_OUT 훅에서만 로컬 라우팅 결정에 영향을 미칩니다(예: 커널은 패킷이 NF_IP_LOCAL_IN 훅에 도달한 후에는 라우팅 결정을 하지 않습니다). 이것은 iptables의 설계에 반영되어 있으며, 여기서 소스 및 대상 NAT는 특정 훅/체인에서만 수행될 수 있습니다

Programs can register a hook by calling NF_REGISTER_NET_HOOK (NF_REGISTER_HOOK prior to Linux 4.13) with a handling function. The hook will be called every time a packet matches. This is how programs like iptables integrate with Netfilter, though you will likely never need to do this yourself.

프로그램은 처리 함수와 함께 NF_REGISTER_NET_HOOK(리눅스 4.13 이전에는 NF_REGISTER_HOOK)을 호출하여 훅을 등록할 수 있습니다. 패킷이 일치할 때마다 이 훅이 호출됩니다. 이것이 iptables와 같은 프로그램이 Netfilter와 통합되는 방식이지만, 사용자가 직접 이 작업을 수행할 필요는 거의 없을 것입니다.


There are several actions that a Netfilter hook can trigger, based on the return value:
Accept
Continue packet handling.
Drop
Drop the packet, without further processing.
Queue
Pass the packet to a userspace program.
Stolen
Doesn’t execute further hooks, and allows the userspace program to take owner‐ ship of the packet.
Repeat
Make the packet “reenter” the hook and be reprocessed.
Hooks can also return mutated packets. This allows programs to do things such as reroute or masquerade packets, adjust packet TTLs, etc.

Netfilter 훅이 반환값에 따라 트리거할 수 있는 여러 동작들이 있습니다:

Accept (수락) 패킷 처리를 계속합니다.

Drop (삭제) 추가 처리 없이 패킷을 삭제합니다.

Queue (큐) 패킷을 사용자 공간 프로그램으로 전달합니다.

Stolen (가로챔) 추가 훅을 실행하지 않고, 사용자 공간 프로그램이 패킷의 소유권을 가질 수 있게 합니다.

Repeat (반복) 패킷이 훅에 '재진입'하여 재처리되도록 합니다.

훅은 또한 변형된 패킷을 반환할 수 있습니다. 이를 통해 프로그램은 패킷을 재라우팅하거나 마스커레이드(위장)하고, 패킷 TTL을 조정하는 등의 작업을 수행할 수 있습니다.

 

 

CVE-2020-8558 취약점 간단 설명

기본 개념

  1. 로컬호스트(127.0.0.1): 컴퓨터가 자기 자신을 가리키는 특별한 IP 주소입니다. 보통 외부에서는 접근할 수 없고, 컴퓨터 내부에서만 사용됩니다.
  2. 신뢰 기반 인증: 많은 시스템이 "로컬호스트에서 오는 요청은 안전하다"고 가정합니다. 따라서 로컬호스트에서 오는 요청에는 추가 보안 검사를 하지 않는 경우가 많습니다.

쿠버네티스 취약점 내용

  • 쿠버네티스에서 발견된 이 취약점(CVE-2020-8558)은 외부 컴퓨터가 자신의 패킷을 "로컬호스트에서 왔어요"라고 속일 수 있게 하는 문제였습니다.
  • 일반적으로는 리눅스가 이런 "거짓말하는 패킷"을 차단하지만, 쿠버네티스의 특정 설정으로 인해 이 보호 기능이 우회될 수 있었습니다.

실제 위험성

  • 공격자는 이 취약점을 이용해 일반적으로는 접근할 수 없는 서비스(예: 내부 API나 데이터베이스)에 접근할 수 있었습니다.
  • 특히 쿠버네티스 환경에서 kube-proxy를 실행하는 노드가 있다면, 공격자는 마치 신뢰할 수 있는 내부 요청인 것처럼 위장하여 API 서버에 접근할 수 있었고, 이를 통해 전체 클러스터를 제어할 가능성이 있었습니다.
  • 쉽게 말해, "나는 너의 내부 시스템이야"라고 속이고 들어가서 관리자 권한을 얻을 수 있는 상황이었습니다.

이 취약점은 후에 패치되었지만, 이런 사례가 네트워크 보안, 특히 내부 요청에 대한 신뢰 모델의 위험성을 보여주는 중요한 예시입니다.

 


할루시네이션 있을 수 있음.

NAT(네트워크 주소 변환)가 적용되는 시점은 Netfilter 훅의 특정 지점에서 이루어집니다:

  1. 출발지 NAT (SNAT, Source NAT):
    • 주로 NF_IP_POST_ROUTING 훅에서 적용됩니다.
    • 패킷이 네트워크 인터페이스를 통해 나가기 직전에 적용됩니다.
    • 이는 iptables의 POSTROUTING 체인에 해당합니다.
  2. 목적지 NAT (DNAT, Destination NAT):
    • 주로 NF_IP_PRE_ROUTING 훅에서 적용됩니다.
    • 패킷이 네트워크 인터페이스로 들어온 직후, 라우팅 결정이 이루어지기 전에 적용됩니다.
    • 이는 iptables의 PREROUTING 체인에 해당합니다.
  3. 로컬 생성 패킷에 대한 DNAT:
    • NF_IP_LOCAL_OUT 훅에서도 목적지 NAT가 적용될 수 있습니다.
    • 로컬에서 생성된 패킷의 목적지 주소를 변경해야 할 때 사용됩니다.
    • 이는 iptables의 OUTPUT 체인에서 처리됩니다.

중요한 점은 NAT가 라우팅 결정 전에 적용되어야 한다는 것입니다. 특히, 패킷이 NF_IP_LOCAL_IN 훅에 도달한 후에는 라우팅 결정이 이미 완료되었기 때문에 NAT를 적용하는 것이 의미가 없습니다.