[network] Packet flow in netfilter ( iptables)

김지환·2023년 8월 22일
0
post-thumbnail

TL;DR

linux 기반 OS에서 Firewall설정을 이야기하면 iptables에 대한 이야기를 많이 한다. iptables는 packet filtering에 대한 network rule을 만드는 userspace영역의 command line program이다. iptables가 rule을 만들면 그 rule은 어디에 적용이 되는걸까?

그 것이 바로 netfilter이다.

( 최근 대규모 Container 환경에서의 성능 문제로 인해서 eBPF를 network stack으로 사용하는 추세가 가속화 되고 있긴하다... )

Netfilter

Trulli Fig.1 - Wikipedia Netfilter.

netfilter는 kernel 영역에서 동작하는 framework로 packet filtering, mangling 등에 기능을 수행한다.

netfilter hooks는 다른 위치의 linux kernal에 callback function을 등록하고, 등록된 callback function들은 각각의 packet들에 대해서 callback이 이루어지게 된다.

최신 linux버전에서는 iptables 의 다음 버전인 nftables를 이용해서 각각의 hook에 filtering을 등록할 수 있게 된다.

netfilter 를 거쳐 들어오는 packet은 5개의 훅 영역을 거칠 수 있고, 이를 통해서 filtering, mangling, forwarding 작업들이 수행된다!

Tables & Chains

netfilter는 Tables, Chains라는 개념이 있는데 Tables는 Raw, Mangle, Nat(DNAT, SNAT), Filter, Security(nftables) 가 존재하며 각각에 Filtering Rule을 적용할 수 있게 되고, 이를 각 Chain 단계에서 적용하게 되는 것이다.

Chains는 PREROUTING -> INPUT -> FORWARD -> OUTPUT -> POSTROUTING 5개의 단계가 존재한다. ( linux kernel 4.2 이후 부터 INGRESS, EGRASS가 도입됨. PREROUTING 이전에 Filtering을 적용할 수 있음. in nftables )

아래 표를 보면 각 Chain별 적용이 되는 Table들을 확인할 수가 있다.

그럼 각각의 Tables, Chains 에 대해서 알아보자

Tables

1. Filter Table

default table로 기본적인 filtering작업을 주로 진행한다.

  • INPUT chain: Packet 이 userspace 영역으로 올라갈 때 적용이 된다.
  • OUTPUT chain: userspace에서 만들어진 packet이 kernel영역으로 나갈 때 적용이 된다.
  • FORWARD chain: Packet 이 다른 NIC(local server)으로 갈 때 적용이 된다.

2. NAT Table

  • PREROUTING chain: routing 되기 전에 packet을 변경할 때 사용하는데 PREROUTING의 경우에는 Destination ip address를 변경하여 local server 목적지에 잘 도착할 수 있도록 변경하는 작업을 한다. 이를 Destination NAT (DNAT)라고 한다.
  • POSTROUTING chain: routing 되기 전에 packet을 변경하는데 이 때는 PREROUTING과 다르게 주로 Source ip address를 변경하는데 사용이 되며 이를 Source NAT (SNAT)라고 한다.
  • OUTPUT chain: userspace 에서 kernel로 내려온 packet에 대한 작업.

3. Mangle Table

모든 chain에 적용이 되며 특정 packet을 변경하는데 사용이 된다. TCP header의 QOS bit를 변경하는데 사용이 된다.

4. Raw Table

netfilter의 conntrack과 독립적인 작업을 해야하는 규칙을 적용할 때 사용한다.

Chains

chain 은 직접 새로 만들 수도 있지만 기본적으로 Pre defined 돼있는 chain이 존재한다. 아마 istio, calico, cilium 같은 추가적인 network 기능을 쓴다면 더 많은 chain들이 추가 돼 있을 것이다. 각각의 Network stack에 따라서 그 흐름을 이해하면 운영에 훨씬 도움이 될 것 이다.

아래는 가장 기본적인 Pre-defined chain이다.
1. PREROUTING
패킷이 네트워크 인터페이스에 도착하게 되면 routing, nat rule을 적용하기 전에 prerouting chain을 거치게 된다. prerouting단계에서는 packet 의 header 를 변경하거나, drop할 수 있다. linux kernel에서는 이렇게 변경된 packet에 대해서 routing을 하게 되고 그 목적지에 따라서 INPUT chain을 거치거나 FORWARD chain을 거치게 된다.

2. INPUT
local application으로 향하는 packet이 거치게 되며 이곳에서도 마찬가지로 packet 수정이 가능하고 accept, reject 그리고 drop이 가능하다. 그리고 ip, port, protocol등의 정보를 기반으로 filtering 또한 가능하다.

connection tracking도 가능한데 이를 통해 linux kernel은 connection에 대한 정보를 수집할 수 있다.

3. FORWARD

local application을 통하지 않고 다른 목적지로 가는 packet이 거치는 chain이다.
다른 chain과 마찬가지로 packet filtering, connection tracking, packet manipulation등이 가능하다.

이 FORWARD chain을 활용한 것이 router, brdige network이다. 우리가 이를 활성화 시키기 위해서는 ip_forward 기능을 켜줘야하는데 다음과 같이 기능을 킬 수 있다.

echo 1 > /proc/sys/net/ipv4/ip_forward

sysctl 명령어를 사용할 수도 있다.
sysctl -w net.ipv4.ip_forward=1

혹은 /etc/sysctl.conf에 적용해줄 수도 있다.

4. OUTPUT

local application에서 나오는 packet이 거치는 chain이다.
다른 chain과 마찬가지로 packet filtering, connection tracking, packet manipulation등이 가능하다.

5. POSTROUTING

local system을 나갈 때 거치는 chain으로 다른 chain과 마찬가지로 packet filtering, connection tracking, packet manipulation등이 가능하다.

이 chain을 활용한 것이 우리가 아는 NAT ( Network Address Translation )으로 packet 의 Source IP주소를 바꿔서 여러 기기가 하나의 network를 공유하면서 단일 Public ip를 사용할 수 있게 되는 것이다.

Rules

각 table 별로 rule을 지정해 줄 수가 있다.

룰은 기준과 타겟이 존재하는데 특정 기준을 충족하면 타겟에 룰을 적용하게 된다. 만약 기준을 충족하지 않는다면 다음 rule로 넘어가게 된다.

룰은 4가지가 존재하는데

  • ACCEPT – 패킷을 Accpet 한다.
  • DROP – 패킷을 Drop 시킨다.
  • QUEUE – Packet을 userspace로 보낸다.
  • RETURN – 다음 룰에 적용하지 않고 정지 시킨다.

iptables --list 명령어를 통해 적용할 수 있는 rule을 검색할 수 있다. 이렇게 하면 적용돼 있는 모든 rule을 볼 수가 있다.

-t 옵션을 주어서 각 table별 적용된 rule을 볼 수도 있다

iptables -t filter --list

target, prot, opt, source, destination field가 나타나 있는데 각각은

  • num – 특정 체인에 있는 룰의 번호
  • target – Special target variable that we discussed above
  • prot – 프로토콜 정보이다. e.g.) tcp, udp, icmp, etc.,
  • opt – 특정 룰에 대한 정보.
  • source – 패킷의 source ip address 정보
  • destination – 패킷의 destination ip address 정보

iptables command

iptables [테이블][액션] [체인][매치] [-j 타겟]

chat-gpt 를 통해 알아본 자주 사용되는 iptables 명령어

규칙 표시 (-L 또는 --list): 현재의 모든 방화벽 규칙을 표시합니다.

iptables -L

규칙 추가 (-A 또는 --append): 새로운 방화벽 규칙을 추가합니다.

iptables -A INPUT -p tcp --dport 80 -j ACCEPT

규칙 삭제 (-D 또는 --delete): 특정 방화벽 규칙을 삭제합니다.

iptables -D INPUT -p tcp --dport 80 -j ACCEPT

정적 NAT 포트 포워딩: 내부 IP 주소와 포트를 외부 IP 주소와 포트에 연결하여 포트 포워딩을 설정합니다.

iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 8080 -j DNAT --to-destination 내부IP:80
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

동적 NAT (SNAT): 소스 IP 주소를 변경하여 패킷을 라우팅하는 NAT 규칙을 설정합니다.

iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source 외부IP

특정 IP 차단 (-s 또는 --source): 특정 소스 IP 주소를 차단합니다.

iptables -A INPUT -s IP -j DROP

허용된 IP 제외 차단: 모든 소스 IP 주소를 차단하고, 특정 IP 주소를 허용합니다.

iptables -A INPUT -s IP -j ACCEPT
iptables -A INPUT -j DROP

포트 기반 차단: 특정 포트에 대한 트래픽을 차단합니다.

iptables -A INPUT -p tcp --dport 22 -j DROP

포트 포워딩: 외부 포트를 내부 포트로 포워딩하여 내부 서비스에 액세스합니다.

iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 8080 -j REDIRECT --to-port 80

특정 인터페이스에 대한 규칙 적용: 특정 네트워크 인터페이스에만 규칙을 적용합니다.

iptables -A INPUT -i eth0 -p tcp --dport 80 -j ACCEPT

기본적으로 많이 사용되는 Iptables 명령어 이외의 것들은 man page를 찾아보면 좋을 것 같다.

Reference

https://www.netfilter.org/
https://wiki.nftables.org/wiki-nftables/index.php/Netfilter_hooks#Ingress_hook
https://www.digitalocean.com/community/tutorials/a-deep-dive-into-iptables-and-netfilter-architecture

profile
Developer

0개의 댓글