- nftables のコンパイル
requirement)
yum install gmp gmp-devel
yum install readline
yum install docbook* (doc 作成)
yum install jansson jansson-devel ( >= 2.3)
tables の入出力(json)の為に使用する
A:libmnl
.configure
make; sudo make install
B:libnftnl
./configure --with-json-parsing (--with-xml-parsing )
make; make install
C:nftables
kernel 3.14.x が起動している環境でコンパイルする
./configure ( --prefix=/ )
make; sudo make install
- nftables の構造
Table Chain Hook 直下のsub-chain それ他のsub-chain
ip filter prerouting prerouting ==> sub-chains ==> sub-chains
ip6 route postrouting ==> sub-chains ==> sub-chains
inet nat input
arp output
bridge forward
直下のsub-chain は iptabelsのINPUT、OUTPUT等登録済みのchainと同じ機能
nftabelsは直下のsub-chain を定義する必要がある
直下のsub-chainの定義がない場合には何もしないので accept と同じになる
直下のsub-chainのtemplateが
/etc/nftables (/usr/local/etc/nftables) にある
ipv4-filter
ipv4-mangle ...
nft -f /etc/nftables/ipv4-filter 等で取り込む使用する事が出来る。
直下のsub-chain設定には Chain,Hookのtype を指定する
chain prerouting { type filter hook prerouting priority 0;}
それ他のchainにはChain,Hook等の指定はしない。
nft add chain ip filter incoming_tcp{}
- 使用方法
1)shell ファイルに記述、又はシェルからコマンドを使用する
nft add table ip filter
2)ファイル記述
ファイルにコードを記述し引数で指定する、又はファイルを直接起動する
sudo nft -f filename
sudo ./ipv4.nft
ファイルにルールを保存し、保存したファイルから設定する
nft list table filter > filter-table
nft -f filter-table
XML/JSON ruleset export
sudo nft export json > rules.json
json,XML 形式での保存、(将来は読み込みも可能)
3)インタラクティブモード
sudo nft -i
nft> add table ip filter
nft> list tables
nft> delete table ip filter
- nftables chain,setの削除
nftables を設定する場合には既存の nftables chain,setを削除してから行う。
下記は削除スクリプト
-----------------------------------
#!/bin/bash
Tables="ip ip6 inet arp bridge"
function nft_flush_delete() {
for T in $(nft list tables $1 | cut -d ' ' -f 2) ; do
#echo "flush $1 $T"
nft flush table $1 $T
nft list table $1 $T -nn | awk '/^[ \t]+chain/{ print $2 }' | xargs -r -L 1 nft delete chain $1 $T
#echo "flush set $1 $T"
nft list table $1 $T -nn | awk '/^[ \t]+set/{ print $2 }' | xargs -r -L 1 nft delete set $1 $T
nft delete table $1 $T > /dev/null
done
}
for P in $Tables; do
nft_flush_delete $P
done
-----------------------------------
iptables が起動している場合には stop しテーブルをクリアする
Fedora系)
sudo systemctl --system stop firewalld.service
sudo systemctl --system disable firewalld.service
Ubuntu系)
sudo initctl stop iptables
- 設定手順
直下のsub-chainを設定する
nft -f /etc/nftables/ipv4-filter を読み込む
又は設定ファイルを作成する
add table ip filter {
chain prerouting { type filter hook prerouting priority 0;}
chain postrouting{ type filter hook postrouting priority 0;}
chain output { type filter hook output priority 0;}
chain input { type filter hook input priority 0;}
chain forward { type filter hook forward priority 0;}
}
ip は省略出来る(default設定)
add table ip filter
==> add table filter
設定の一覧表示
sudo nft list tables [ip| ip6 | inet | arp | bridge]
sudo nft list ip table [filter| nat] -nn
sudo nft list set ip filter [blacklists | tcp_ports | ... ] -n
-n ipaddress を名前に変換しない
-nn port番号をサービス名に変換しない
サンプルコード (lnft.sh)
- シンボリック変数
define ext_if = eth0
define ext_ifs = { $ext_if }
filter input iifname $ext_ifs
アドレスで使用する場合には注意)
define private_addr2 = {192.168.2.126-192.168.255.255}
define private_addr1 = {192.168.0.0/16}
define private_addr0 = {10.0.0.0/8,172.16.0.0/12,192.0.2.0/24,192.0.0.0/24,192.88.99.0/24,169.254.0.0/16}
define private_addr_all = {$private_addr2, $private_addr0 }
add rule filter postrouting oif $ext_if1 ip daddr $private_addr_all log prefix "Drop_post_private_addr_all:" drop
==> Error: Core dump
下記はOK
add rule filter postrouting oif $ext_if1 ip daddr $private_addr0 log prefix "Drop_post_private_addr_0:" drop
add rule filter postrouting oif $ext_if1 ip daddr $private_addr2 log prefix "Drop_post_private_addr_2:" drop
includeしたファイル内では使用出来る
## ephmeral-ports
define ephmeral_min = 49152
define ephmeral_max = 61000
include "local_printer.nft"
local_printer.nft
add rule filter jetdirect_out ct state new,established tcp sport >= $ephmeral_min tcp sport = $ephmeral_max tcp dport $jetdirect_tcp accept
- 比較
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 input test test tcp dport != 22
nft add rule input test test tcp dport >= 1024
- アドレス指定
add rule filter OUTPUT ip daddr 192.168.0.0/24
add rule filter OUTPUT ip daddr 192.168.0.0/255.255.255.0
add rule filter OUTPUT ip saddr . ip daddr 192.168.0.0/24 . 192.168.0.0/24
add rule filter OUTPUT ip daddr { 192.168.0.0/24, 192.168.1.0/24}
nft add rule filter input ip daddr 192.168.0.1-192.168.0.250 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
nft 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
- メタ表現
nftables-2.0 からは meta を記述しなくてもよい様であるが
記述しないとエラーになるものもある。
nft filter output meta skuid root accept
==> nft filter output skuid root accept
# meta: skb length
add rule filter outgoing_udp udp dport @dns_port ip daddr @dns_server meta length < 256 accept
add rule filter outgoing_udp udp dport @ntp_port udp sport @ntp_port ip daddr @ntp_server meta length 76 accept
# meta: protocol
add rule ip filter output meta protocol 0x0800 counter
# meta: iifname,oifname :: input,output iface_index
add rule ip filter output meta iifname "eth0" counter
add rule ip filter output meta oifname "eth0" counter
add rule ip filter output meta iifname $ext_ifs # define 設定の場合
# meta: iif,oif ::
add rule ip filter output meta iif lo counter
add rule ip filter output meta oif lo counter
add rule ip filter output meta oif @ext_ifs # sets 設定の場合
# meta: uid
nft add rule filter output meta skuid pablo counter
nft add rule filter output meta skuid 1000 counter
# meta: gid
add rule ip filter output meta skgid 1000 counter
# meta: mark
add rule ip filter output meta mark 0 counter
nft add rule filter output meta mark 123 counter
# meta: secmark
add rule ip filter output meta secmark 0 counter
# meta: nftrace
add rule ip filter output meta nftrace 1 counter
# meta: rtclassid (see /etc/iproute2/rt_realms)
add rule ip filter output meta rtclassid cosmos counter
- conntrack (CT)
State information: new, established, related and invalid.
# ct: state
ct state {new,established} accept
ct state invalid drop
# ct: helper
add rule filter tcp_helper ct helper "ftp" accept
add rule filter tcp_helper ct helper "irc" accept
add rule filter tcp_helper return
add rule filter outgoing_tcp tcp dport 1024-65535 ct state {established,related} jump tcp_helper
# ct: direction original/reply
add rule ip filter output ct direction original counter
add rule ip filter output ct direction reply counter
# ct: mark
nft add rule filter input ct mark 123 counter
nft add rule ip filter output ct mark 0 counter
nft filter output mark set ct mark
nft filter output ct mark set 0x1
# ct: secmark
add rule ip filter output ct secmark 0 counter
# ct: expiration
add rule ip filter output ct expiration 30 counter
- log
log option
prefix string
group number (log-level ?)
snaplen number
queue-threshold number
sudo modprobe xt_LOG と nft_log モジュールを事前に読込む。
add rule filter incoming_icmp ct state {established,related} icmp type @icmp_incoming log prefix "Accept_icmp_incoming:" accept
log prefix の長さ制限はない (iptables:29 文字)
Apr 21 13:42:31 dac77 kernel: [18865.439788] Accept_icmp_incoming_1234567890_12345:IN=p2p1 OUT=
MAC=08:00:27:b0:53:68:52:54:00:12:35:02:08:00 SRC=8.8.8.8 DST=10.0.2.15 LEN=84 TOS=0x00 PREC=0x00
TTL=63 ID=3749 DF PROTO=ICMP TYPE=0 CODE=0 ID=15682 SEQ=3
add rule filter prerouting ip saddr @blacklists log prefix "Drop_pre_blacklist:" drop
は 下記 iptables と同じ log を出力する
iptables xxx -j LOG --log-prefix "Drop_pre_blacklist:" --log-ip-options
- sets
サポートするデータタイプ
IPv4 address
IPv6 address
Ethernet address
Protocol type
Mark type
名前なし sets
nft add rule filter output tcp dport { 22, 23 } counter drop
名前付 sets
nft add set filter blacklists { type ipv4_addr;}
setsの定義、格納するデータタイプを指定する
add set ip filter eth_ifs { type iface_index;} # eth0
add set ip filter dns_port { type inet_service;} # 53,80,443
add set ip filter icmp_outgoing { type icmp_type;} # echo-reply,echo-request
add set ip filter blacklists { type ipv4_addr;} # 1.2.3.4
sets の定義場所
add set ip filter ext_ifs { type iface_index;}
add element filter ext_ifs { $ext_ifs }
と定義の後、続けてデータを設定すると環境によってはエラーになる
対応 1:filter 定義内に記述する
add table ip filter {
chain prerouting { type filter hook prerouting priority 0;}
..
set ext_ifs { type iface_index;}
}
対応 2: 事前に別ファイルで定義する
add set ip filter ext_ifs { type iface_index;}
データを設定する
define,set に要素数の制限はない (iptables の multiports はMAX 14)
nft add element filter eth_ifs { eth0,eth1 }
nft delete element filter blacklists { 192.168.1.5 }
nft delete set filter blacklists
# Concat expression
add rule ip filter output ip daddr . tcp dport { \
192.168.0.1 . 22, \
192.168.0.1 . 80, \
}
iif or oif @eth_ifs ( iifname @eth_ifs はダメ)
setsは包含関係のみ下記はダメ
iif < @eth_ifs
iif != @eth_ifs
set private_addr { type ipv4_addr;}
192.168.0.0/16, 10.0.0.0-10.0.128.255 等なダメ
アドレス範囲指定は define では有効
- map (Dictionary)
名前付 map
add map filter verdict_map { type ipv4_addr : verdict; }
add element filter verdict_map { 1.2.3.5 : drop}
add element filter verdict_map { 1.2.3.4 : accept}
add rule filter output ip daddr vmap @verdict_map
delete element filter verdict_map 1.2.3.5
delete set filter verdict_map
名前で追加、削除が出来る
名前なし map
nft add rule ip filter input ip protocol vmap { \
tcp : jump tcp-chain, \
udp : jump udp-chain, \
icmp : jump icmp-chain }
add filter input ip saddr vmap { \
10.0.0.0/24 : jump chain1, \
10.0.0.0/8 : jump chain2, \
8.8.8.8 : jump chain3 \
}
nft add rule filter output ip daddr vmap { \
192.168.0.0/24 : drop, \
192.168.0.1 : accept}
- Debug
## scanner, parser, eval, netlink, mnl, proto-ctx, segtree, all
nft --debug parser -I $nftDir -f $nftDir/nft_ip4.nft
- Mark
add rule filter OUTPUT meta mark 123/0x000000ff
nft filter input mark set 0x1
nft filter input mark set mark | 0x1
will OR the current value with 0x1.
nft filter input mark set ip saddr map {
192.168.0.0/24 : 0x1,
192.168.1.0-192.168.1.64 : 0x2,
192.168.2.1 : 0x3,
* : 0x4
}
- MAC address
define if1_mac = 00:1b:21:02:6f:ad
add rule filter prer_eth iif $ext_if1 ether daddr $if1_mac return
add rule filter prer_eth oif $ext_if1 ether saddr $if1_mac return
- Rate limiting
Rate limiting matchings
nft add rule filter input icmp type echo-request limit rate 10/second accept
ip protocol icmp limit rate 10/second accept
ip protocol icmp drop
tcp dport ssh limit rate 15/minute accept
- NAT
include "ipv4-nat.nft"
nft add rule nat postrouting ip saddr $local_net oifname $ext_if snat [ xx.xx.xx.xx | xx.xx.xx.xx:port ]
nft add rule nat prerouting iif $int_ifs udp dport @udp_proxies dnat $udp_proxy_ipaddr
nft filter input tcp dport ssh accept comment "SSH access"
- connlabel support
Support for connection tracking labels (connlabels) has been added.
connlabel.conf is parsed and the values can be used as symbolic
constants in combination with the "ct label" expression.
/etc/xtables/connlabel.conf
nft filter input ct label clients,servers accept
- tcp flags
pre-defined symbolic constants:
fin 0x01
syn 0x02
rst 0x04
psh 0x08
ack 0x10
urg 0x20
ecn 0x40
cwr 0x80
tcp flags & (fin|syn) == (fin|syn) drop
tcp flags & (syn|rst) == (syn|rst) drop
tcp flags & (fin|syn|rst|psh|ack|urg) < (fin) drop # == 0 would be better, not supported yet.
tcp flags & (fin|syn|rst|psh|ack|urg) == (fin|psh|urg) drop