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

Packet Handling in the Kernel - Conntrack

by yeongki0944 2025. 2. 26.

iptables의 상태추적(Connection tracking 또는 Stateful Inspection)

https://arthurchiao.art/blog/conntrack-design-and-implementation/

 

Conntrack

Conntrack is a component of Netfilter used to track the state of connections to (and from) the machine. Conntrack은 기기로의(그리고 기기로부터의) 연결 상태를 추적하는 데 사용되는 Netfilter의 구성 요소입니다.

Connection tracking directly associates packets with a particular connection.
연결 추적은 패킷을 특정 연결에 직접 연관시킵니다.

Without connection tracking, the flow of packets is much more opaque.
연결 추적이 없으면 패킷의 흐름이 훨씬 더 불투명해집니다.

Conntrack can be a liability or a valuable tool, or both, depending on how it is used.
Conntrack은 사용 방법에 따라 부담이 될 수도, 가치 있는 도구가 될 수도 있으며, 또는 둘 다일 수도 있습니다.

In general, Conntrack is important on systems that handle firewalling or NAT.
일반적으로 Conntrack은 방화벽이나 NAT를 처리하는 시스템에서 중요합니다.

Connection tracking allows firewalls to distinguish between responses and arbitrary packets.
연결 추적은 방화벽이 응답 패킷과 임의의 패킷을 구분할 수 있게 해줍니다.

A firewall can be configured to allow inbound packets that are part of an existing connection but disallow inbound packets that are not part of a connection.
방화벽은 기존 연결의 일부인 인바운드 패킷은 허용하고 연결의 일부가 아닌 인바운드 패킷은 허용하지 않도록 구성될 수 있습니다.

To give an example, a program could be allowed to make an outbound connection and perform an HTTP request, without the remote server being otherwise able to send data or initiate connections inbound.
예를 들어, 프로그램은 아웃바운드 연결을 만들고 HTTP 요청을 수행할 수 있지만, 원격 서버는 그 외에는 데이터를 보내거나 인바운드 연결을 시작할 수 없도록 허용될 수 있습니다.

NAT relies on Conntrack to function.
NAT는 기능하기 위해 Conntrack에 의존합니다.

iptables exposes NAT as two types: SNAT (source NAT, where iptables rewrites the source address) and DNAT (destination NAT, where iptables rewrites the destination address).
iptables는 NAT를 두 가지 유형으로 노출합니다: SNAT(소스 NAT, iptables가 소스 주소를 다시 작성하는 곳)와 DNAT(목적지 NAT, iptables가 목적지 주소를 다시 작성하는 곳)입니다.

NAT is extremely common; the odds are overwhelming that your home router uses SNAT and DNAT to fan traffic between your public IPv4 address and the local address of each device on the network.
NAT는 매우 흔합니다; 가정용 라우터가 공용 IPv4 주소와 네트워크의 각 장치의 로컬 주소 간에 트래픽을 분산시키기 위해 SNAT와 DNAT를 사용할 가능성이 압도적으로 높습니다.

With connection tracking, packets are automatically associated with their connection and easily modified with the same SNAT/DNAT change.
연결 추적을 통해 패킷은 자동으로 해당 연결과 연관되고 동일한 SNAT/DNAT 변경으로 쉽게 수정됩니다.

This enables consistent routing decisions, such as "pinning" a connection in a load balancer to a specific backend or machine.
이것은 로드 밸런서에서 연결을 특정 백엔드나 머신에 "고정"하는 것과 같은 일관된 라우팅 결정을 가능하게 합니다.

The latter example is highly relevant in Kubernetes, due to kube-proxy's implementation of service load balancing via iptables.
후자의 예는 kube-proxy가 iptables를 통해 서비스 로드 밸런싱을 구현하기 때문에 Kubernetes에서 매우 관련이 있습니다.

Without connection tracking, every packet would need to be deterministically remapped to the same destination, which isn't doable (suppose the list of possible destinations could change...).
연결 추적 없이는 모든 패킷이 결정론적으로 동일한 목적지에 재매핑되어야 하는데, 이는 실행 불가능합니다(가능한 목적지 목록이 변경될 수 있다고 가정해보세요...).

Conntrack identifies connections by a tuple, composed of source address, source port, destination address, destination port, and L4 protocol.
Conntrack은 소스 주소, 소스 포트, 목적지 주소, 목적지 포트 및 L4 프로토콜로 구성된 튜플로 연결을 식별합니다.

These five pieces of information are the minimal identifiers needed to identify any given L4 connection.
이 다섯 가지 정보는 주어진 L4 연결을 식별하는 데 필요한 최소한의 식별자입니다.

All L4 connections have an address and port on each side of the connection; after all, the internet uses addresses for routing, and computers use port numbers for application mapping.
모든 L4 연결은 연결의 각 측면에 주소와 포트를 가지고 있습니다; 결국, 인터넷은 라우팅에 주소를 사용하고, 컴퓨터는 응용 프로그램 매핑에 포트 번호를 사용합니다.

The final piece, the L4 protocol, is present because a program will bind to a port in TCP or UDP mode (and binding to one does not preclude binding to the other).
마지막 부분인 L4 프로토콜은 프로그램이 TCP 또는 UDP 모드로 포트에 바인딩하기 때문에 존재합니다(하나에 바인딩해도 다른 것에 바인딩하는 것을 배제하지 않습니다).

Conntrack refers to these connections as flows.
Conntrack은 이러한 연결을 플로우라고 부릅니다.

A flow contains metadata about the connection and its state.
플로우는 연결과 그 상태에 대한 메타데이터를 포함합니다.

Conntrack stores flows in a hash table, shown in Figure 2-3, using the connection tuple as a key.
Conntrack은 연결 튜플을 키로 사용하여 플로우를 그림 2-3에 표시된 해시 테이블에 저장합니다.

The size of the keyspace is configurable.
키스페이스의 크기는 구성 가능합니다.

A larger keyspace requires more memory to hold the underlying array but will result in fewer flows hashing to the same key and being chained in a linked list, leading to faster flow lookup times.
더 큰 키스페이스는 기본 배열을 유지하기 위해 더 많은 메모리를 필요로 하지만, 동일한 키로 해싱되는 플로우가 더 적고 연결 리스트에 체인되어 더 빠른 플로우 조회 시간을 가져옵니다.

The maximum number of flows is also configurable.
최대 플로우 수도 구성 가능합니다.

A severe issue that can happen is when Conntrack runs out of space for connection tracking, and new connections cannot be made.
발생할 수 있는 심각한 문제는 Conntrack이 연결 추적을 위한 공간이 부족해지고 새로운 연결을 만들 수 없게 될 때입니다.

There are other configuration options too, such as the timeout for a connection.
연결 시간 초과와 같은 다른 구성 옵션도 있습니다.

On a typical system, default settings will suffice.
일반적인 시스템에서는 기본 설정으로 충분할 것입니다.

However, a system that experiences a huge number of connections will run out of space.
그러나 대량의 연결을 경험하는 시스템은 공간이 부족해질 것입니다.

If your host runs directly exposed to the internet, overwhelming Conntrack with short-lived or incomplete connections is an easy way to cause a denial of service (DOS).
호스트가 인터넷에 직접 노출되어 실행되는 경우, 짧은 수명이나 불완전한 연결로 Conntrack을 압도하는 것은 서비스 거부(DOS)를 일으키는 쉬운 방법입니다.

 

 

Conntrack's max size is normally set in /proc/sys/net/nf_conntrack_max, and the hash table size is normally set in /sys/module/nf_conntrack/parameters/hashsize.
Conntrack의 최대 크기는 일반적으로 /proc/sys/net/nf_conntrack_max에 설정되며,
해시 테이블 크기는 일반적으로 /sys/module/nf_conntrack/parameters/hashsize에 설정됩니다.

Conntrack entries contain a connection state, which is one of four states.
Conntrack 항목은 네 가지 상태 중 하나인 연결 상태를 포함합니다.

It is important to note that, as a layer 3 (Network layer) tool, Conntrack states are distinct from layer 4 (Protocol layer) states.
레이어 3(네트워크 레이어) 도구로서, Conntrack 상태는 레이어 4(프로토콜 레이어) 상태와 구별된다는 점을 유의하는 것이 중요합니다.

Table 2-3 details the four states.
표 2-3은 네 가지 상태를 자세히 설명합니다.



Although Conntrack is built into the kernel, it may not be active on your system.

Conntrack이 커널에 내장되어 있지만, 시스템에서 활성화되어 있지 않을 수 있습니다.

Certain kernel modules must be loaded, and you must have relevant iptables rules (essentially, Conntrack is normally not active if nothing needs it to be).
특정 커널 모듈이 로드되어야 하며, 관련 iptables 규칙이 있어야 합니다(본질적으로, Conntrack은 필요로 하는 것이 없으면 일반적으로 활성화되지 않습니다).

Conntrack requires the kernel module nf_conntrack_ipv4 to be active.
Conntrack은 kernel 모듈 nf_conntrack_ipv4가 활성화되어 있어야 합니다.

lsmod | grep nf_conntrack will show if the module is loaded, and sudo modprobe nf_conntrack will load it.
lsmod | grep nf_conntrack은 모듈이 로드되었는지 보여주고, sudo modprobe nf_conntrack은 그것을 로드할 것입니다.

You may also need to install the conntrack command-line interface (CLI) in order to view Conntrack's state.
Conntrack의 상태를 보기 위해 conntrack 명령줄 인터페이스(CLI)를 설치해야 할 수도 있습니다.

When Conntrack is active, conntrack -L shows all current flows.
Conntrack이 활성화되면, conntrack -L은 모든 현재 플로우를 보여줍니다.

Additional Conntrack flags will filter which flows are shown.
추가적인 Conntrack 플래그는 어떤 플로우가 표시되는지 필터링합니다.

Let's look at the anatomy of a Conntrack flow, as displayed here:
여기에 표시된 대로 Conntrack 플로우의 구조를 살펴봅시다:

tcp      6 431999 ESTABLISHED src=10.0.0.2 dst=10.0.0.1
    sport=22 dport=49431 src=10.0.0.1 dst=10.0.0.2 sport=49431 dport=22 [ASSURED]
    mark=0 use=1
<protocol> <protocol number> <flow TTL> [flow state>]
    <source ip> <dest ip> <source port> <dest port> [] <expected return packet>

 

The expected return packet is of the form <source ip> <dest ip> <source port> <dest port>.
예상되는 반환 패킷은 <source ip> <dest ip> <source port> <dest port> 형식입니다.

This is the identifier that we expect to see when the remote system sends a packet.
이것은 원격 시스템이 패킷을 보낼 때 볼 것으로 예상되는 식별자입니다.

Note that in our example, the source and destination values are in reverse for address and ports.
우리 예제에서 주소와 포트에 대한 소스 및 대상 값이 역순이라는 점을 유의하세요.

This is often, but not always, the case.
이것은 종종 그렇지만, 항상 그런 것은 아닙니다.

For example, if a machine is behind a router, packets destined to that machine will be addressed to the router, whereas packets from the machine will have the machine address, not the router address, as the source.
예를 들어, 기계가 라우터 뒤에 있는 경우, 그 기계로 가는 패킷은 라우터로 주소가 지정되는 반면, 기계에서 온 패킷은 라우터 주소가 아닌 기계 주소를 소스로 가지게 됩니다.

In the previous example from machine 10.0.0.2, 10.0.0.1 has established a TCP connection from port 49431 to port 22 on 10.0.0.2.
기계 10.0.0.2의 이전 예에서, 10.0.0.1은 포트 49431에서 10.0.0.2의 포트 22로 TCP 연결을 설정했습니다.

You may recognize this as being an SSH connection, although Conntrack is unable to show application-level behavior.
Conntrack이 응용 프로그램 수준의 동작을 보여줄 수 없지만, 이것이 SSH 연결임을 알아볼 수 있을 것입니다.

Tools like grep can be useful for examining Conntrack state and ad hoc statistics: grep ESTABLISHED /proc/net/ip_conntrack | wc -l
grep과 같은 도구는 Conntrack 상태와 임시 통계를 검사하는 데 유용할 수 있습니다: grep ESTABLISHED /proc/net/ip_conntrack | wc -l

 


Conntrack 기초 가이드 (Linux 초급 엔지니어용)

Conntrack이란?

Conntrack(Connection Tracking)은 Linux 커널의 Netfilter 프레임워크에 포함된 기능으로, 간단히 말해 네트워크 연결의 상태를 추적하는 시스템입니다. 네트워크 패킷이 어떤 연결에 속하는지 기억하고 관리합니다.

왜 중요한가요?

  1. 방화벽(Firewall) 기능: 패킷이 기존 연결의 일부인지 아닌지 구분할 수 있어, 합법적인 응답만 허용 가능
  2. NAT(Network Address Translation): 내부 네트워크와 외부 인터넷 간 통신 가능하게 함
  3. 로드 밸런싱: 같은 연결의 패킷들이 같은 서버로 전달되도록 함

어떻게 작동하나요?

  1. 연결 식별: 모든 연결은 5가지 정보로 식별됩니다
    • 출발지 IP 주소
    • 출발지 포트
    • 목적지 IP 주소
    • 목적지 포트
    • 프로토콜(TCP/UDP)
  2. 상태 관리: 모든 연결은 다음 상태 중 하나를 가집니다
    • NEW: 새로 시작된 연결
    • ESTABLISHED: 양방향으로 패킷이 오간 연결
    • RELATED: 기존 연결과 관련된 새 연결
    • INVALID: 어떤 연결에도 속하지 않은 패킷
  3. 해시 테이블: 연결 정보는 메모리의 해시 테이블에 저장됩니다

실무에서 자주 마주치는 상황

  1. 방화벽 관리: iptables 규칙에서 -m state 옵션으로 Conntrack 상태 활용
    Copy
    iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
  2. 문제 해결: 시스템에 네트워크 연결 문제가 있을 때 확인 방법
    Copy
    # 현재 연결 상태 확인 conntrack -L # 연결 수 확인 cat /proc/sys/net/netfilter/nf_conntrack_count
  3. 성능 이슈: 대량의 연결을 처리하는 시스템에서 발생할 수 있는 문제
    • 최대 연결 수 확인: cat /proc/sys/net/nf_conntrack_max
    • 필요시 늘리기: sysctl -w net.nf_conntrack_max=131072

초보자가 주의할 점

  1. Conntrack 테이블이 가득 차면 새 연결이 만들어지지 않음
  2. 서버에 갑자기 네트워크 문제가 생기면 Conntrack 테이블 확인하기
  3. 고트래픽 환경에서는 Conntrack 설정 최적화가 필요함

리눅스 초급 엔지니어라면 우선 이 정도를 이해하고 있으면 많은 네트워크 문제 해결에 도움이 될 겁니다!

 


Conntrack의 탄생 배경 및 필요성

초기 리눅스 방화벽의 한계

1990년대 초기 리눅스 방화벽(ipchains, ipfwadm)은 스테이트리스(stateless) 방식이었습니다. 이는 각 패킷을 독립적으로 검사하고 규칙을 적용했다는 의미입니다. 즉:

  • 패킷 A가 들어오고
  • 나중에 패킷 B가 들어오면
  • 두 패킷이 실제로는 같은 연결의 일부라도 시스템은 이를 알지 못했습니다

이러한 방식은 몇 가지 심각한 문제가 있었습니다:

  1. 복잡한 방화벽 규칙: 양방향 통신을 허용하려면 들어오는/나가는 패킷에 대해 별도의 규칙을 만들어야 했습니다
  2. 보안 취약점: 중간에 끼어드는 패킷(스푸핑)을 구분하기 어려웠습니다
  3. 고급 기능 부재: FTP와 같이 동적으로 포트를 사용하는 프로토콜 지원이 어려웠습니다

NAT의 필요성 증가

1990년대 후반, 인터넷이 급속도로 성장하면서 IPv4 주소 부족 문제가 심각해졌습니다. 이를 해결하기 위한 대책으로 NAT(Network Address Translation)이 필수적이 되었는데, NAT는 본질적으로 연결 상태를 추적해야 합니다.

왜냐하면:

  • 내부 네트워크의 여러 기기가 하나의 공용 IP를 공유할 때
  • 응답 패킷이 돌아오면 어떤 내부 기기로 보내야 할지 기억해야 함

커널 2.4와 Netfilter의 등장

2000년대 초반, 리눅스 커널 2.4에서는 이러한 문제들을 해결하기 위해 완전히 새로운 네트워크 필터링 프레임워크인 Netfilter가 도입되었습니다. 이때 Conntrack이 핵심 구성 요소로 개발되었습니다.

Conntrack은 다음과 같은 근본적인 필요성을 해결하기 위해 만들어졌습니다:

  1. 스테이트풀 방화벽(Stateful Firewall): 패킷의 맥락(어떤 연결에 속하는지)을 이해하는 방화벽
  2. 효율적인 NAT 지원: 대규모 네트워크에서 주소 변환 처리
  3. 현대적 네트워크 보안: 연결 상태를 기반으로 한 보안 정책 적용

현대적 중요성

클라우드 컴퓨팅과 컨테이너 기술의 발전으로 Conntrack의 중요성은 더욱 커졌습니다:

  • 쿠버네티스(Kubernetes): 서비스 로드 밸런싱에 iptables와 Conntrack 사용
  • 가상 네트워크: 클라우드 환경에서 가상 머신 간 통신 관리
  • 마이크로서비스: 수많은 서비스 간 네트워크 연결 관리

정리

Conntrack은 단순히 기술적 필요성이 아닌, 인터넷의 발전 방향과 IP 주소 체계의 한계, 그리고 현대적 네트워크 보안 요구사항이 맞물려 탄생했습니다. 단순한 패킷 필터링을 넘어, 연결 자체를 이해하고 관리할 수 있는 시스템이 필요했기 때문입니다.

오늘날 리눅스 기반 시스템의 네트워킹은 Conntrack 없이는 상상하기 어려울 정도로, 기본적인 인터넷 접속부터 복잡한 클라우드 인프라까지 모든 곳에서 중요한 역할을 하고 있습니다.

 

 


https://blog.naver.com/accdar/150166962169

※ 요즘 포스팅되고 있는 netfilter 와 iptables 관련 내용은 대부분 'Linux netfilter Hacking HOWTO' 문서에서 인용하고 있습니다. 더 깊은 내용을 원하시거나 제 포스팅 내용이 이상하다 생각하시면 google에 검색하셔서 보는 것이 좋으실 것입니다. 
 
본론으로 가서 오늘은 conntrack에 대해 알아보겠다. conntrack는 connection tracking의 줄임 말이다. Connection tracking은 말 그대로 연결을 추적하는 것이다. Conntrack은 현재의 시스템에서 기존의 모든 connection을 저장하고 있다.
 
이 state에서 새로운 packet이 들어오면 기존에 저장하고 있던 connection과 같은지 검사를 하게 된다. 만약 기존에 저장되어 있는 connection과 같다면 그 경로를 그대로 따라가게 되고, 그렇지 않으 면 새로운 connection을 맺어주고, 그 맺어준 connection을 다시 시스템에 저장하게 된다.
 

 
 
connection tracking 하기 위해서는 protocol types, connection state, source ip address and destination ip address, port number 등과 같은 정보를 확인하고 이용해야 하는데
 
다음 포스팅에 이러한 자료를 저장하는 구조체를 알아보겠다.
[출처] connection tracking(conntrack)|작성자 accdar

위에 글에 대한 Claude3.7 검증

Conntrack 블로그 내용 검증

이 블로그 내용은 기본적으로 맞는 정보입니다만, 몇 가지 부분에서 좀 더 정확한 설명이 필요합니다.

정확한 정보

Conntrack은 connection tracking의 줄임말이 맞습니다.

연결 추적 기능이 맞으며, 시스템에서 네트워크 연결 상태를 저장하고 있습니다.

패킷 처리 방식에 대한 설명 - 새 패킷이 들어오면 기존 연결과 비교하는 과정은 기본적으로 맞습니다.

정보 확인 - 프로토콜 타입, 연결 상태, IP 주소, 포트 번호 등을 사용하는 것이 맞습니다.

보완이 필요한 부분

⚠️ **"기존의 모든 connection을 저장"**이라는 표현은 약간 제한적입니다. Conntrack은 설정된 최대 용량(nf_conntrack_max) 까지만 저장 가능하며, 용량 초과 시 새 연결이 불가능합니다.

⚠️ **"새로운 connection을 맺어준다"**는 표현은 약간 오해의 소지가 있습니다. Conntrack은 실제로 연결을 생성하지 않고, 단지 연결 상태를 추적하고 기록할 뿐입니다. 실제 연결은 애플리케이션이나 OS의 네트워크 스택에 의해 이루어집니다.

⚠️ 연결 상태에 대한 설명이 부족합니다. Conntrack은 NEW, ESTABLISHED, RELATED, INVALID와 같은 상태를 사용하여 연결을 추적합니다.

총평

이 블로그 내용은 Conntrack의 기본 개념을 이해하기에 충분한 정보를 제공하고 있습니다. 초보자가 처음 개념을 접하기에는 적절한 내용이지만, 실제 시스템 관리나 문제 해결을 위해서는 더 상세한 정보(상태 관리, 테이블 크기 설정, 성능 고려사항 등)가 필요합니다.

Conntrack에 대한 더 깊은 이해를 원한다면 공식 문서나 더 상세한 기술 자료를 참고하시는 것이 좋을 것입니다.



해당 표현 "만약 기존에 저장되어 있는 connection과 같다면 그 경로를 그대로 따라가게 되고"는 다소 부정확합니다.

정확한 설명:

Conntrack이 실제로 하는 일은:

  1. 패킷이 기존 연결에 속하는지 확인합니다 - 이 부분은 맞습니다.
  2. 그러나 "경로를 따라간다"는 것은 오해의 소지가 있습니다 - Conntrack 자체는 패킷의 물리적 경로나 라우팅을 결정하지 않습니다.

실제 동작:

패킷이 기존 연결에 속한다고 판단되면:

  • 해당 연결 상태가 업데이트됩니다 (예: 타임아웃 갱신)
  • 연결 상태에 따라 iptables 규칙이 적용됩니다
  • NAT가 설정된 경우 해당 주소/포트 변환이 일관되게 적용됩니다
  • 방화벽이 이 패킷을 기존 연결의 일부로 인식하고 그에 맞게 처리합니다

즉, Conntrack은 경로를 직접 결정하거나 패킷을 라우팅하지 않고, 단지 패킷의 연결 상태를 추적하여 다른 네트워크 구성요소가 올바른 결정을 내릴 수 있도록 정보를 제공합니다.

더 정확하게 표현하자면: "기존에 저장되어 있는 연결에 속한다고 판단되면, 해당 연결의 상태 정보에 따라 처리됩니다."