본문 바로가기

nftables

룰셋 Ruleset debug/tracing

source: https://wiki.nftables.org/wiki-nftables/index.php/Ruleset_debug/tracing

 

이전 글: Scripting

다음 글: Output text modifier

 

debug/tracing은 nftabels 0.6, linux kernel 4.6 부터 지원합니다. 최근에 설치한 Ubuntu 18.04에 설치한 nftables과 kernel version은 아래와 같습니다. 

- nftables: 0.8.2-1

- Linux: 5.4.0-80

iptables에서 -j TRACE와 같은 것이며, 더 향상된 기능이 있습니다. 

 

패켓에 대한 tracing을 하려면, 절차는 trace 목적의 chain을 만들어 hook 에 base chain으로 등록한 후, 해당 chain에서 nftrace를 활성화하는 룰을 설정하고, 마지막으로 tracing event를 지켜보면 됩니다. 

- add chain to a hook

- enable nftrace

- monitor trace

nftrace 활성화 방법

아래와 같이 rule을 추가하면 됩니다. 이렇게 하면 해당 chain을 지나는 모든 패켓에 대해 tracing을 하는 것입니다. 

meta nftrace set 1

만약 IP/TCP 패켓만 tracing 하려면 활성화 rule을 ip protocol tcp에 대해서만 적용합니다. 

ip protocol tcp meta nftrace set 1

실제 서비스에 적용된 상태에서는 범위를 좁혀 tracing하는 것을 추천합니다. 

Hook에 chain 추가

chain을 추가하기 위해서는 table을 먼저 생성해야 합니다. 그리고 나서 hook을 정하여 chain을 생성합니다. 그리고 나서 nftrace를 활성화하는 rule을 선언합니다. 

# nftrace table ip filter 생성
salsal@r3:~$ sudo nft add table ip filter

# chain trace_chain을 type filter로 설정하고 hook prerouting에 추가
salsal@r3:~$ sudo nft add chain filter trace_chain '{ type filter hook prerouting priority -301; }'

chain에 룰 추가

# trace_chain을 지나는 전체 패켓에 대해 nftrace 활성화
salsal@r3:~$ sudo nft add rule filter trace_chain meta nftrace set 1

salsal@r3:~$ sudo nft list ruleset
table ip filter {
	chain trace_chain {
		type filter hook prerouting priority -301; policy accept;
		nftrace set 1
	}
}
salsal@r3:~$

trace 지켜보기

salsal@r3:~$ sudo nft monitor trace
trace id 4704db2b ip filter trace_chain packet: iif "enp0s3" ether saddr 52:54:00:12:35:02 ether daddr 08:00:27:57:d9:98 ip saddr 35.224.170.84 ip daddr 10.0.2.15 ip dscp cs0 ip ecn not-ect ip ttl 64 ip id 13397 ip length 44 tcp sport http tcp dport 36446 tcp flags == 0x12 tcp window 65535
trace id 4704db2b ip filter trace_chain rule nftrace set 1 (verdict continue)
trace id 4704db2b ip filter trace_chain verdict continue

예제

다음과 같은 ruleset을 ruleset.nft 에 저장합니다. 

flush ruleset

table ip filter {
	chain input {
		type filter hook input priority 0; policy drop;
		ct state established,related counter packets 153677 bytes 6163412 accept
		ct state new tcp dport ssh counter packets 0 bytes 0 accept
	}
}

ruleset을 로드합니다. 

salsal@r3:~$ sudo nft -f nftables.nft

salsal@r3:~$ sudo nft list ruleset
flush ruleset

table ip filter {
	chain input {
		type filter hook input priority 0; policy drop;
		ct state established,related counter packets 153677 bytes 6163412 accept
		ct state new tcp dport ssh counter packets 0 bytes 0 accept
	}
}

hook prerouting에 priority가 더 높은 (숫자는 작은) trace_chain을 추가합니다. 

salsal@r3:~$ sudo nft add chain ip filter trace_chain '{ type filter hook prerouting priority -1; }'

salsal@r3:~$ sudo nft add rule ip filter trace_chain icmp type {echo-request, echo-reply} nftrace set 1

salsal@r3:~$ sudo nft list ruleset
table ip filter {
	chain input {
		type filter hook input priority 0; policy drop;
		ct state established,related counter packets 237 bytes 13760 accept
		ct state new tcp dport ssh counter packets 0 bytes 0 accept
	}

	chain trace_chain {
		type filter hook prerouting priority -1; policy accept;
		icmp type {echo-request, echo-reply} nftrace set 1
	}
}

시스템 r3에서 nftrace를 활성화합니다. 

salsal@r3:~$ sudo nft monitor trace

 

시스템 r3와 연결되어 있는 시스템 r2에서 r3로 향하는 icmp packet을 발송합니다. 

salsal@r2:~$ ping -c 2 -W 1 192.168.23.3
PING 192.168.23.3 (192.168.23.3) 56(84) bytes of data.

--- 192.168.23.3 ping statistics ---
2 packets transmitted, 0 received, 100% packet loss, time 1004ms

그 때 시스템 r3의 nftrace 결과를 살펴봅니다. 

salsal@r3:~$ sudo nft monitor trace
trace id e10637fc ip filter trace_chain packet: iif "enp0s10" ether saddr 08:00:27:6a:e2:a9 ether daddr 08:00:27:f2:19:0d ip saddr 192.168.23.2 ip daddr 192.168.23.3 ip dscp cs0 ip ecn not-ect ip ttl 64 ip id 12173 ip length 84 icmp type echo-request icmp code 0 icmp id 3703 icmp sequence 1
trace id e10637fc ip filter trace_chain rule icmp type {  } nftrace set 1 (verdict continue)
trace id e10637fc ip filter trace_chain verdict continue
trace id e10637fc ip filter trace_chain
trace id e10637fc ip filter input verdict continue
trace id e10637fc ip filter input
trace id d864f713 ip filter trace_chain packet: iif "enp0s10" ether saddr 08:00:27:6a:e2:a9 ether daddr 08:00:27:f2:19:0d ip saddr 192.168.23.2 ip daddr 192.168.23.3 ip dscp cs0 ip ecn not-ect ip ttl 64 ip id 12216 ip length 84 icmp type echo-request icmp code 0 icmp id 3703 icmp sequence 2
trace id d864f713 ip filter trace_chain rule icmp type {  } nftrace set 1 (verdict continue)
trace id d864f713 ip filter trace_chain verdict continue
trace id d864f713 ip filter trace_chain
trace id d864f713 ip filter input verdict continue
trace id d864f713 ip filter input

위 내용을 살펴보면 

trace id e10637fc ip filter trace_chain packet: iif "enp0s10" ....

  • r3의 adapter enp0s10 로 들어온 시스템은 trace_chain을 통과합니다. 

trace id e10637fc ip filter trace_chain rule icmp type {  } nftrace set 1 (verdict continue)

  • 처음 만난 rule icmp type을 통과하며 default policy가 accpet 이므로 통과합니다. (ip filter trace_chain verdict continue)

trace id e10637fc ip filter input verdict continue

  • chain trace_chain을 통과하여 chain input을 지납니다.

chain input에서는 nftrace가 활성화되어 있지 않아 상세 내역을 출력하지 않는 듯 합니다. 

 

 

이전 글: Scripting

다음 글: Output text modifier

'nftables' 카테고리의 다른 글

nftables examples  (0) 2021.08.06
Output text modifier  (0) 2021.08.06
Scripting  (0) 2021.08.06
룰셋 갱신 지켜보기 / Monitoring ruleset updates  (0) 2021.08.06
룰셋 레벨 명령 / Operations at ruleset level  (0) 2021.08.06