iptables替代品 nftables

我们在管理 linux上的防火墙规则时基本一直都在用的是iptables吧,最近发现了一位 ”新警长“ nftables ,从linux kernel 3.15版本开始 nftables优先级高于iptables,成为了默认的防护墙规则管理工具,比iptables更灵活,更高效,nftables与iptables都用于实现netfilter提供的钩子函数,用于真正处理网络数据包。

下方表是目前不同操作系统版本以及默认的防火墙软件

系统名称 版本 默认防火墙软件 备注
Ubuntu 20.04 iptables 默认使用 iptables
Ubuntu 22.04 nftables 默认使用 nftables
RHEL/CentOS 7 iptables 默认使用 iptables 不支持 nftables
RHEL/CentOS 8-9 nftables 默认使用 nftables 可以通过安装 iptables 来兼容旧规则

簇 Family

nftables引入了簇的概念,统一了之前的xtables,簇是 nftables 的基础,定义了规则集可以操作的协议范围,iptables是通过不同的表,mangle filter等 进行区分

簇名称 描述
ip 仅处理 ipv4 数据包
ip6 仅处理 ipv6 数据包
inet 双栈 同时处理数据包
arp 处理 arp 数据包
bridge 处理通过网桥设备的数据包
netdev 处理来自网络设备的数据包

表 Tables

表是 nftables 用于存放链的容器,每个表可包含多个链,并且可以指定表的协议簇,在iptables中 表是预定义的,用户不能对其进行修改,但是在nftables中允许用户自定义表,而且表是创建规则管理的第一步

1
2
3
nft add table inet my-table # 创建表
nft list tables # 列出表
nft delete table inet my-table # 删除表

链 chains

链是表中的规则集合,用于处理特定类型的流量,在之前的iptables中,链也是预定义的,只能在现有链中添加规则,,nftables允许用户自定义链,nftables支持如下两种类型的链

  • 基本链: 与内核的网络钩子直接关联,例如 INPUT/OUTPUT/PEROUTING,实现过滤,地址转换等功能
  • 常规链: 一般用于规则跳转,例如将流量从基本链跳转到常规链继续处理,以及模块化规则管理等
基本链的类型
类型 钩子 描述
filter 所有簇 所有钩子 标准链类型
nat IPv4/IPv6/INET PREROUTING、INPUT、OUTPUT、POSTROUTING 用于网络地址转换
route IPv4/IPv6 OUTPUT 如果数据包通过此链并被允许,会执行新的路由查找,否则将被丢弃
钩子 hook

钩子决定了链在网络数据被处理流程中的位置,nftables主要支持下方6种常用钩子

  • **INGRESS**:处理进入网桥设备的数据包,仅支持 netdev 簇,但好像从 kernel5.x 版本开始 inet簇也支持ingress钩子了
  • **PREROUTING**:处理进入网络接口之前的数据
  • **INPUT**:处理进入网络接口的数据
  • **FORWARD**:处理经过网络接口转发的数据
  • **OUTPUT**:处理从本地系统发出的数据
  • **POSTROUTING**:处理离开网络接口之前的数据

优先级

优先级决定了链在网络数据包处理流程中的执行顺序。优先级值越低,执行的越早,下表总结了 nftables 默认的优先级范围

钩子 默认优先级范围
INGRESS -300 ~ -100
PREROUTING -300 ~ -100
INPUT 0
FORWARD 0
OUTPUT 0
POSTROUTING 100 ~ 300
1
2
3
4
5
6
7
8
9
10
11
12
nft add chain inet my-table my-chain { type filter hook input priority 0 \; policy accept \; } # 创建基本链

nft list chains #列出所有链

nft list chain inet my-table my-chain # 列出链中的规则

nft delete chain inet my-table my-chain # 删除链

nft add rule inet my-table input tcp dport 22 jump ssh_chain # 在基本链中跳转到常规链

nft add rule inet my-table ssh_chain accept
nft add rule inet my-table ssh_chain drop # 在常规链中定义规则

规则 rules

规则用于处理数据包的具体策略,例如允许或者拒绝目标端口的流量等,nftables的语法比iptables更简单也更灵活,也支持更为复杂的表达式,且支持动态插入。

表达式
类型 字段 描述
meta oif <INDEX> 匹配输出接口的索引。
iif <INDEX> 匹配输入接口的索引。
oifname <NAME> 匹配输出接口的名称(动态匹配,速度较慢)。
iifname <NAME> 匹配输入接口的名称(动态匹配,速度较慢)。
icmp type <icmp type> 匹配 ICMP 类型(如 echo-requestecho-reply)。
icmpv6 type <icmpv6 type> 匹配 ICMPv6 类型(如 echo-requestecho-reply)。
ip protocol <protocol> 匹配 IP 协议类型(如 tcpudp)。
daddr <address> 匹配目标 IP 地址。
saddr <address> 匹配源 IP 地址。
ip6 daddr <address> 匹配目标 IPv6 地址。
saddr <address> 匹配源 IPv6 地址。
tcp dport <port> 匹配目标 TCP 端口。
sport <port> 匹配源 TCP 端口。
udp dport <port> 匹配目标 UDP 端口。
sport <port> 匹配源 UDP 端口。
sctp dport <port> 匹配目标 SCTP 端口。
sport <port> 匹配源 SCTP 端口。
ct state <state> 匹配连接状态(如 newestablishedrelatedinvalid)。
动作
动作 描述
accept 接受数据包
drop 丢弃数据包
queue 将数据包排队到用户空间
continue 继续执行下一条规则
return 从当前链返回并继续上一个链的下一条规则
jump <chain> 跳转到指定链,执行完该链后返回原链
goto <chain> 跳转到指定链,执行完后不再返回原链

常用的一些规则配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# 1. 允许 SSH 流量
nft add rule inet my-table my_filter_chain tcp dport ssh accept

# 2. 允许 HTTP 流量(插入到链的开头)
nft insert rule inet my-table my_filter_chain tcp dport http accept

# 3. 插入规则到指定位置(使用 index)
nft insert rule inet my-table my_filter_chain index 1 tcp dport nfs accept

# 4. 插入规则到指定位置(使用 handle)
nft add rule inet my-table my_filter_chain handle 7 tcp dport 1234 accept

# 5. 允许特定 IP 地址访问
nft add rule inet my-table my_filter_chain ip saddr 192.168.1.100 accept

# 6. 丢弃所有 ICMP 流量
nft add rule inet my-table my_filter_chain icmp type echo-request drop

# 7. 允许特定端口范围
nft add rule inet my-table my_filter_chain tcp dport 1000-2000 accept

# 8. 使用连接跟踪允许已建立的连接
nft add rule inet my-table my_filter_chain ct state established accept

# 9. 跳转到另一个链进行处理
nft add chain inet my-table ssh_chain
nft add rule inet my-table my_filter_chain tcp dport ssh jump ssh_chain
nft add rule inet my-table ssh_chain accept

# 10. 删除规则(通过 handle)
nft delete rule inet my-table my_filter_chain handle 8

# 11. 清空链中的所有规则
nft flush chain inet my-table my_filter_chain

# 12. 列出链中的所有规则
nft list chain inet my-table my_filter_chain

# 13. 设置链的默认策略为 drop
nft chain inet my-table my_filter_chain { policy drop; }

PS: 还没写完,后续在补充~

参考: