nftables wiki page
:국내블로그나 사이트에는 자세한 자료는 좀 찾기 힘듬
nftables 를 이해하기 위해서는 기존 iptables 의 개념을 이해하고 있으면 도움이 된다.
iptables 튜토리얼을 참고하면 도움이 될거 같다
https://www.frozentux.net/iptables-tutorial/iptables-tutorial.html |
넷필터 훅 (netfilter hook)
:넷필터에서 패킷을 처리하는 프로세스를 나타내는듯 함
서버로 들어오는 연결 → PREROUTING → 라우팅 결정 → INPUT
서버에서 나가는 연결 → Output → 라우팅 결정 → Postrouting
목적지가 서버가 아닌 연결 → PREROUTING → FORWARD → Postrouting |
iptables 와 비슷하게 동작한다 (모듈적재)
modprobe nf_tables modprobe nf_tables_ipv4
[root@localhost ~]# lsmod | grep nf_tables nf_tables_ipv4 12916 1 nf_tables 49879 1 nf_tables_ipv4 nfnetlink 14606 1 nf_tables |
생성가능한 (미리정의된) 필터 혹은 체인들
filter : 패킷필터, arp,bridge, ip,ip6, inet tables 지원
route : iptables mangle 테이블과 유사한듯
nat :
prerouting
input
forward
output
postrouting |
테이블 추가 (table)
:filter, kek 이라는 테이블 생성
nft add table ip filter nft add table ip kek : kek 이라는 이름으로도 생성 가능하다 |
테이블 확인
:filter, raw, kek 이라는 3개의 테이블 존재
nft list tables table filter table raw table kek |
테이블 삭제
: 메뉴얼에는 삭제하고자 하는 테이블에 체인이 없을때 삭제가 된다? 라고 되어 있는듯 하다
nft delete table ip filter : filter 테이블을 삭제 |
테이블 flush
:flush는 초기화 한다라는 의미일듯 (== iptables -F)
nft flush table ip kek :kek 테이블 flush 한다? |
체인생성 (chain)
:priority 0 은 우선순위를 의미하는듯 함
:메뉴얼에는 아래의 문법대로 꼭 만들어줘야 한다는 의미가 강조되어 있음
INPUT 체인 생성
nft add chain ip filter input { type filter hook input priority 0 \; } : filter 테이블에 input 체인 생성한다는 의미인듯 |
OUTPUT 체인 생성
nft add chain ip filter output { type filter hook output priority 0 \; } :filter 테이블에 output 체인 생성 |
임의의 체인 생성
nft add chain ip filter test :filter 테이블에 test 라는 체인을 생성해보았다 |
체인삭제
nft delete chain ip filter input :filter 테이블에 input 체인 삭제 |
체인 flush
nft flush chain filter input |
테이블 구조 확인
[root@localhost ~]# nft list table filter table ip filter { chain input { type filter hook input priority 0; }
chain output { type filter hook output priority 0; } } |
원문 You can disable host name resolution via using the -n option You can also disable service name resolution via -nn
옵션 -a : 포지션 handle 이라는 개념으로 해서 구 iptables에 (–line-number) 개념, 라인순서 표시 -n : host ↔ IP 변환 하지 않음 -nn : service ↔ port 번호 |
단독서버의 경우 아래와 같이 생성하면 된다고 함 (테이블 먼저 생성 → 체인생성 순서로 만드는듯 함)
nft add table ip filter nft add chain ip filter input { type filter hook input priority 0 \; } nft add chain ip filter output { type filter hook output priority 0 \; } |
카운터 옵션
: 패킷과 바이트수를 출력 (10개 패킷과 840바이트가 현재 카운터 되었음)
nft add rule filter output ip daddr 8.8.8.8 counter nft add rule filter output tcp dport ssh counter
ip daddr 8.8.8.8 counter packets 10 bytes 840 # handle 4 |
정책 추가
insert
[root@localhost ~]# nft list table filter -n -a table ip filter { chain input { type filter hook input priority 0; }
chain output { type filter hook output priority 0; ip daddr 8.8.8.8 counter packets 10 bytes 840 # handle 4 tcp dport ssh counter packets 0 bytes 0 # handle 5 } } |
handle은 라인 순서대로 나오는것이 아니라 정책이 추가된 시점이거나 처리되는 순서인듯 함
정책추가
nft insert rule filter output position 5 ip daddr 127.0.0.8 drop : -a 옵션을 통해서 반드시 핸들러 숫자를 입력해야지만 추가됨 위 예제에서는 4 혹은 5 를 입력해야 한다 |
정책삭제
특정 정책만 삭제 nft delete rule filter output handle 30 nft delete rule filter output ip saddr 192.168.1.1 counter : handle 번호로도 삭제 가능하며 정책 그대로 입력해서 삭제 가능하다
테이블 안의 체인 전체 삭제 (아래 예제는 filter 테이블의 output 체인 삭제) nft delete rule filter output
테이블 전체 삭제 (filter 테이블 전체 삭제)
nft flush table filter |
ex) nftables ↔ iptables 룰 추가 예제
nft insert rule filter output ip daddr 192.168.10.1 counter == iptables -I OUTPUT -t filter -d 192.168.1.1 |
nftalbe 파일 입출력
정책 적용
nft -f [file명] : (== iptables-restore) 정책 적용 |
정책 저장
nft list table filter > [file명] == iptables-save |
정책 match
논리기호
ne which stands for non equal. Alternatively you can use !=. lt means less than. Alternatively you can use <. gt means less than. Alternatively you can use >. le means less than. Alternatively you can use <=. ge means less than. Alternatively you can use >=. |
논리기호 예제
같다 nft add rule filter output tcp dport 33
같지 않다 nft add rule filter output tcp dport != 33
크다 nft add rule filter output tcp dport <. 33
작다 nft add rule filter output tcp dport >. 44
크거나 같다 nft add rule filter output tcp dport .>= 44
작거나 같다 nft add rule filter output tcp dport .=> 44 |
패킷 매칭
tcp 프로토콜 전체 매칭 nft add rule filter output ip protocol tcp
mac-address 매칭 nft add rule filter input ether daddr ff:ff:ff:ff:ff:ff counter
ipv4 header filter nft add rule filter input ip saddr 192.168.1.100 ip daddr 192.168.1.1 counter
ipv6 header filter nft add rule filter output ip6 daddr abcd::100 counter
tcp/udp/udplite nft add rule filter input tcp dport 23-1024 counter drop nft add rule filter input tcp flags != syn counter
SYN 과 ACK 패킷을 로그를 남기고 카운터하기 [root@localhost ~]# nft -i nft> add rule filter output tcp flags & (syn | ack) == (syn | ack) counter log
※ 그냥 shell 에서 바로 명령어를 날리는 경우 구분에러 때문에 -i 옵션을 쓰고 넣는듯함 [root@localhost ~]# nft add rule filter output tcp flags & (syn | ack) == (syn | ack) counter log -bash: syntax error near unexpected token `==’
ICMP 패킷 매칭 (icmp 응답 요청 패킷은 카운터 하고 드롭) nft add rule filter input icmp type echo-request counter drop |
메타정보 매칭
인터페이스 장치 이름 : iifname, oifname, iif and oif 인터페이스 타입 : iiftyte and oiftype tc handle: priority socket user and group identifier: skuid and skgid packet length: length |
인터페이스 이름 매칭
iifname, to match the input network interface name (인터페이스로 들어오는) oifname, to match the output network interface name (인터페이스에서 나가는)
ex) nft add rule filter input meta oifname lo accept |
패킷 마크
nft add rule filter output meta mark 123 counter |
socket UID
: 구 iptables에서도 잘 안써봤지만 패킷을 발생시키는 소유자를 의미하는듯함
[root@localhost log]# nft add rule filter output meta skuid pablo counter <cmdline>:1:35-39: Error: User does not exist add rule filter output meta skuid pablo counter
pablo 라는 UID로 발생되는 패킷을 카운터하라는듯 한데 계정정보를 참조하는듯 하다 (/etc/passwd)
실제로 /etc/passwd 에서 존재하는 root 계정으로 해보니깐 되네 nft add rule filter output meta skuid root counter |
conntrack 매칭
상태정보 (iptables 와 동일한듯)
new established related invalid The conntrack mark |
ex) #1 , #2 는 아마 주석인듯… ct 는 conntrack 의 약자 같은데 ct mark 와 ct 없이 mark 도 먹긴 하는데 둘 차이는 모르겠네..
nft add rule filter input ct state established,related counter accept #1 nft add rule filter input counter drop #2
패킷 마크 nft add rule filter input ct mark 123 counter |
ratelimit 정책
a maximum of 10 ICMP echo-request packets per second (초당 10개의 ICMP 응답패킷을 받아들이고 나머지 패킷은 처분?) % nft add rule filter input icmp type echo-request limit rate 10/second accept |
DROP/ACCEPT 정책
drop 정책 nft add rule filter output drop :이거 넣으면 접속 끊어지네 ㅋ
accept 정책 nft add rule filter output counter accept |
jump to chain
nft add chain ip filter tcp-chain : tcp-chain 체인을 하나 생성
nft add rule ip filter input ip protocol tcp jump tcp-chain : tcp 는 tcp-chain 체인으로 점프하라?
nft add rule ip filter tcp-chain counter : tcp-chain 체인의 카운터를 체크하라? |
reject 정책
ex) nft add rule filter input reject :모든 input 체인 거부 (아마네트워크 끊어짐)
nft delete rule filter input : filter 체인 삭제
nft add rule filter input ct state new reject : 새로운 연결에 대해서만 거부 |
LOG 정책
nft add rule filter input tcp dport 22 ct state new log prefix \”SSH for ever: \” accept |
NAT 테이블
nft add table nat nft add chain nat postrouting { type nat hook postrouting priority 0 \; } nft add rule nat postrouting ip saddr 192.168.1.0/24 oif enp1s0f1 snat 1.2.3.4 : nat 테이블 생성후 192.168.1.0 에서 오는 트래픽을 인터페이스 enp1s0f1 를 통해서 1.2.3.4 공인 아이피를 가지고 나간다 (주소변환)
Note: There is no masquerading support yet. (아직 마스쿼레이드 기능은 지원하지 않는다는 의미) |
route 테이블
route 테이블 생성후 nft add table ip route nft add chain route output { type nat hook postrouting priority 0 \; } nft add rule route output mark set 123 |
queue
nft add filter input counter queue : 그냥 input 으로만 하면 네트워크 접속이 끊어져 버리네
nft add filter input tcp dport 80 counter queue : 세부 포트 옵션을 주면 네트워크는 끊어지지 않음
queue 65535가 가득차면 아래와 같이 숫자를 지정하여 큐를 지정하는듯 (num 이 생략되면 기본적으로 0 으로 생성됨) nft add filter input counter queue num 3
Important note: If there is no userspace application listening to that queue, then all packets will be dropped (queue가 가득차면 패킷이 드롭된다는것)
nft add filter input counter queue bypass : queue가 가득차더라도 DROP하지 않고 패킷을 ACCEPT 시키겠다는 의미
[root@localhost ~]# nft add filter input tcp dport 25 counter queue bypass <cmdline>:1:45-50: Error: syntax error, unexpected bypass, expecting end of file or newline or semicolon add filter input tcp dport 25 counter queue bypass
nft add filter input counter queue accept :bypass 는 안먹고 accept 명령어는 먹는듯…
queue 로드발랜싱 (아래 옵션은 안 먹는다) : 0,1,2,3 4개의 큐를 이용 nft add filter input counter queue num 0-3
When doing load balancing, you can use the fanout option to use the CPU ID as an index to map packets to the queues. The idea is that you can improve performance if there’s a queue/userspace application per CPU % nft add filter input counter queue num 0-3 fanout
nft add filter input counter queue num 0-3 fanout bypass |
counters
Counters are optional in nftables, thus, you need to explicitly specify them in the rule if you want them. The following example allows you to account all tcp traffic that you machine receives: % nft add rule filter input ip protocol tcp counter An interesting feature of the counter action is that its position in the rule syntax matters. This rule is not equivalent to the previous rule: % nft add rule filter input counter ip protocol tcp The rule is evaluated from the left to the right, so any kind of packet will update the counters, not only TCP packets. |
Anonymous sets
nft add rule filter output tcp dport { 22, 23 } counter |
Named sets
네임셋 생성
nft add set filter blackhole { type ipv4_addr\;} |
네임셋 추가
nft add element filter blackhole { 192.168.3.4 } nft add element filter blackhole { 192.168.1.4, 192.168.1.5 } |
네임셋 리스트 출력
nft list set filter black |
네임셋을 가지고 정책 추가
네임셋을 가지고 정책 적용 : 블랙홀이라는 네임셋의 아이피를 드롭 nft add rule filter input ip saddr @blackhole drop |
iptables → nftables (라인수를 줄일수 있다)
iptables 표현 ip6tables -A INPUT -p tcp -m multiport –dports 22,80,443 -j ACCEPT ip6tables -A INPUT -p icmpv6 –icmpv6-type neighbor-solicitation -j ACCEPT ip6tables -A INPUT -p icmpv6 –icmpv6-type echo-request -j ACCEPT ip6tables -A INPUT -p icmpv6 –icmpv6-type router-advertisement -j ACCEPT ip6tables -A INPUT -p icmpv6 –icmpv6-type neighbor-advertisement -j ACCEPT iptables -A FORWARD -p tcp –dport 22 -j LOG iptables -A FORWARD -p tcp –dport 22 -j DROP
nftables 표현 nft add rule ip6 filter input tcp dport {telnet, http, https} accept nft add rule ip6 filter input icmpv6 type { nd-neighbor-solicit, echo-request, nd-router-advert, nd-neighbor-advert } accept nft add rule filter forward tcp dport 22 log drop |
네임셋 생성가능 종류
The supported data types currently are: IPv4 address. IPv6 address. Ethernet address. Protocol type. Mark type. |
Dictionaries
:요것은 잘만 배치하면 퍼포먼스적으로 꽤 향상될듯 하다
테이블 생성
nft add chain ip filter tcp-chain { type filter hook input priority 0 \; } nft add chain ip filter udp-chain { type filter hook input priority 0 \; } nft add chain ip filter icmp-chain { type filter hook input priority 0 \; } |
프로토콜에 따라서 각각의 체인으로 점프 (iptables에서는 4라인이상 써야 하는데 1 라인으로 되네)
nft add rule ip filter input ip protocol vmap { tcp : jump tcp-chain, udp : jump udp-chain , icmp : jump icmp-chain } nft add rule ip filter input counter accept |
체인생성
nft add rule filter icmp-chain counter nft add rule filter tcp-chain counter nft add rule filter udp-chain counter |
intervals (==iptables 의 멀티 아이피 / 포트 의 개념인듯 하다)
nft add rule filter input ip daddr 192.168.0.1-192.168.0.250 drop nft add rule filter input tcp ports 1-1024 drop nft add rule ip filter input ip saddr { 192.168.1.1-192.168.1.200, 192.168.2.1-192.168.2.200 } drop ft add rule ip filter forward ip daddr { 192.168.1.1-192.168.1.200 : jump chain-dmz, 192.168.2.1-192.168.20.250 : jump chain-desktop } drop |
maps
nft add rule ip filter input dnat set tcp dport map { 80 : 192.168.1.100, 8888 : 192.168.1.101 }
If the destination port is 80, then the packet is dnat’ed to 192.168.1.100. If the destination port is 8888, the the packet is dnat’ed to 192.168.1.101.
80번 포트로 들어오면 192.168.1.100으로 패킷을 보내고 8888번 포트로 들어오면 192.168.1.101으로 패킷을 보내라? |
대략 아래 페이지에서 나온 듀토리얼들은 다 읽어 보았다 (약 일주일정도 소요된듯 하다)
기존의 iptables 정책을 가지고 nftables 문법으로 바꿔본다면 많은 실력 향상이 있을듯 하다.
읽어보시고 유용하였으면 1따봉 부탁드리겠습니다.
[polldaddy rating=”7739789″]