1、nftables是干什么的?
取代iptables、ip6tables、ebtables、arptables,在方便性、特性和性能方面有了许多改进:
- 查表取代线性处理
- ipv4 ipv6使用同一个框架
- 以原子方式应用规则,而不是获取、更新和存储完整的规则集
- 支持在规则集中debug和trace
- 更一致紧凑的语法,没有特定协议的扩展
- 为第三方应用提供Netlink API
2、如何开始使用?
环境准备:
- 内核3.13以上版本
- 内核模块为nf_tables
- 用户空间库为libmnl和libnftnl
安装工具包
yum install -y nftables
删除iptables规则
iptables -F -t filter
iptables -F -t nat
iptables -F -t mangle
iptables -F -t raw
iptables -F -t security
iptables -X
新建一个简单的nftable策略,过滤由192.168.232.1到192.168.232.110的TCP 80端口的连接
#新建ip表iptable1
nft add table ip iptable1
#新建chain属于表iptable1,位置为input、类型为filter、优先级为0,缺省策略为accept
nft 'add chain ip iptable1 filter-input-ens33-p0 { type filter hook input priority 0 ; policy accept;}'
#在iptable1表的filter-input-ens33-p0链中添加rule,drop掉从192.168.232.1到192.168.232.110的80端口的包
nft add rule iptable1 filter-input-ens33-p0 ip saddr 192.168.232.1 ip daddr 192.168.232.110 tcp dport 80 drop
查看配置
# nft list table iptable1 -s
table ip iptable1 {
chain filter-input-ens33-p0 {
type filter hook input priority 0; policy accept;
ip saddr 192.168.232.1 ip daddr 192.168.232.110 tcp dport http drop
}
}
3、nftables概念
3.1、table
table是chains、sets和有状态对象的容器。可以有多个table,每个table包含多个chain,table的主要参数为协议栈(nftables families)和名称。协议栈有:
- ip
- ip6
- netdev 主要用于ingress勾子
- arp
- inet (ipv4+ipv6)双栈,v4和v6不影响,L4协议在v4和v6上同时生效
- bridge
3.2、chain
chain是rules的容器。一个table包含多个chain,chain分基础链(base chain)和规则链(regular chain),基础链的主要参数有: type、hook、priority和policy,其中除了policy缺省为accept,其他均为强制要求。在创建netdev表下的链时必须指定网卡。
- type 做哪类事
- filter
- route
- nat
- hook 在哪里做
- prerouting
- input
- forward
- output
- postrouting
- ingress
- priority 多个chain如何处理,有符号整数值。下面为iptables中的各种类型链(type)的优先级,越小越优先:
- CONNTRACK_DEFRAG (-400): 分片
- RAW (-300): 连接跟踪之前的处理
- SELINUX_FIRST (-225): SELinux操作
- CONNTRACK (-200): 连接跟踪
- MANGLE (-150): mangle操作
- NAT_DST (-100): DNAT
- FILTER (0): 过滤
- SECURITY (50): 安全表
- NAT_SRC (100): SNAT
- SELINUX_LAST (225): 包出hook时的SELinux操作
- CONNTRACK_HELPER (300): connection tracking at exit
- policy 不匹配任何rule如何处理
- 缺省策略为accept
规则链无需指定基础链的元素,主要用于跳转。
- 缺省策略为accept
3.3、rules
3.4、SETS
3.5、MAPS
3.6、FLOWTABLES
3.7、STATEFUL OBJECTS
3.8、CT
3.9、COUTNER
3.10、QUOTA
3.11、EXPRESSIONS
3.12、DATA TYPE
3.13、PRIMARY EXPRESSIONS
3.14、PAYLOAD EXPRESSIONS
3.15、STATEMENTSADDITIONAL COMMANDS
- MONITOR
3.16、ERROR REPORTING
3.17、退出码
- 0 成功
- 1 未知错误
- 2 内存分配错误
- 3 不能打开netlink socket
3.4、各个组件的关系
不是所有的families可以使用所有类型的chain:
type | families | |||||
---|---|---|---|---|---|---|
ip | ip6 | inet | arp | bridge | netdev | |
filter | Y | Y | Y | Y | Y | Y |
route | Y | Y | Y | - | - | - |
nat | Y | Y | Y | - | - | - |
hook表示位置,不是所有的families可以使用所有的hook:
type | families | |||||
---|---|---|---|---|---|---|
ip | ip6 | inet | arp | bridge | netdev | |
prerouting | Y | Y | Y | - | Y | - |
input | Y | Y | Y | Y | Y | - |
forward | Y | Y | Y | - | Y | - |
output | Y | Y | Y | Y | Y | - |
postrouting | Y | Y | Y | - | Y | - |
ingress | - | - | - | - | - | Y |
并不是所有的type可以使用在所有的hook上:
type | families | |||||
---|---|---|---|---|---|---|
prerouting | input | forward | output | postrouting | ingress | |
filter | Y | Y | Y | Y | Y | Y |
route | - | - | - | Y | - | - |
nat | Y | Y | - | Y | Y | - |
netdev只支持type filter和hook ingress
4、基本操作
4.1、table操作
add和create意义相同,如果table已存在create会报错。
{add | create} table [family] table [ { flags flags } ]
{delete | list | flush} table [family] table
list tables
delete table [family] handle handle
flush tables
4.2、chain操作
{add | create} chain [family] table chain [ { type type hook hook [device device] priority priority ; [policy policy ;] } ]
{delete | list | flush} chain [family] table chain
list chains
delete chain [family] table handle handle
rename chain [family] table chain newname
在创建netdev table下的chain时必须指定网卡。
4.3、rule操作
[add | insert] rule [family] table chain [ handle handle | index index ] statement...
replace rule [family] table chain handle handle statement...
delete rule [family] table chain handle handle
add Add a new rule described by the list of statements. The rule is appended to the given chain unless a handle is specified, in which case the rule is ap‐
pended to the rule given by the handle.
insert Similar to the add command, but the rule is prepended to the beginning of the chain or before the rule with the given handle.
replace
Similar to the add command, but the rule replaces the specified rule.
delete Delete the specified rule.
add a rule to ip table input chain
nft add rule filter output ip daddr 192.168.0.0/24 accept # 'ip filter' is assumed
# same command, slightly more verbose
nft add rule ip filter output ip daddr 192.168.0.0/24 accept
delete rule from inet table
# nft -a list ruleset
table inet filter {
chain input {
type filter hook input priority 0; policy accept;
ct state established,related accept # handle 4
Manual page nft(8) line 286 (press h for help or q to quit)
4.4、原子rule的替换
4.5、常见报错
4.6、通过表达式构建规则
4.7、ruleset操作
4.8、监控ruleset的更新
4.9、Ruleset调试与跟踪
4.10、从iptables迁移到nftables
主要使用以下工具:
- iptables-translate
- iptables-restore-translate
- ip6tables-translate
- ip6tables-restore-translate
将iptables rule转换成nftable rule
# iptables-translate -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT
nft add rule ip filter INPUT tcp dport 22 ct state new counter accept
将ip6tables rule转换成nftable rule
# ip6tables-translate -A FORWARD -i eth0 -o eth3 -p udp -m multiport --dports 111,222 -j ACCEPT
nft add rule ip6 filter FORWARD iifname eth0 oifname eth3 meta l4proto udp udp dport { 111,222} counter accept
保存现有iptables规则到文件save.txt
# iptables-save > save.txt
# cat save.txt
# Generated by iptables-save v1.6.0 on SDec 24 14:26:40 2016
*filter
:INPUT ACCEPT [5166:1752111]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [5058:628693]
-A FORWARD -p tcp -m tcp --dport 22 conntrack --ctstate NEW -j ACCEPT
COMMIT
# Completed on Sat Dec 24 14:26:40 2016
将save.txt转换为nftables规则
# iptables-restore-translate -f save.txt
# Translated by iptables-restore-translate v1.6.0 on Sat Dec 24 14:26:59 2016
add table ip filter
add chain ip filter INPUT { type filter hook input priority 0; }
add chain ip filter FORWARD { type filter hook forward priority 0; }
add chain ip filter OUTPUT { type filter hook output priority 0; }
add rule ip filter FORWARD tcp dport 22 cstate new counter accept
保存转换后的规则,并在nftable中使用
# iptables-restore-translate -f save.txt > ruleset.nft
# nft -f ruleset.nft
# nft list ruleset
table ip filter {
chain INPUT {
type filter hook input priority 0;policy accept;
}
chain FORWARD {
type filter hook forward priorit0; policy accept;
tcp dport ssh ct state new counter packets 0 bytes 0 accept
}
chain OUTPUT {
type filter hook output priority 0; policy accept;
}
}
4.11、从ipset迁移到nftables
4.12、输出文本修饰符
5、选择器selector
Matching packet header fields
Matching packet metainformation
Matching connection tracking stateful metainformation
Rate limiting matchings
Routing information
6、动作action
Accepting and dropping packets
Jumping to chain
Rejecting traffic
Logging traffic
Performing Network Address Translation (NAT)
Setting packet metainformation
Queueing to userspace
Duplicating packets
Mangle packet header fields
Mangle TCP options
Counters
Load balancing
Setting packet connection tracking metainformation
7、脚本
nftables框架提供了一个脚本环境,脚本的执行是原子的。要么应用整个脚本,要么在发生错误时回退。保证始终处于一致状态。还可以增加注释,定义变量,包含rule set文件。
缺省在/etc/nftables/已经有一些定义好的脚本,all-in-one.nft中包含了其他所有nft文件.
# ls /etc/nftables/
all-in-one.nft bridge-filter.nft ipv4-filter.nft ipv4-nat.nft ipv6-filter.nft ipv6-nat.nft netdev-ingress.nft
arp-filter.nft inet-filter.nft ipv4-mangle.nft ipv4-raw.nft ipv6-mangle.nft ipv6-raw.nft
以ipv4-filter.nft为例,可以看到nft脚本和其他脚本类似,需要再第一行设置解释器指令.
#!/usr/sbin/nft -f
table filter {
chain input { type filter hook input priority 0; }
chain forward { type filter hook forward priority 0; }
chain output { type filter hook output priority 0; }
}
The meta expression nfproto keyword
can be used to test which family (IPv4 or IPv6) context the packet is being processed in.