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中允许用户自定义表,而且表是创建规则管理的第一步
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 |
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-request 、echo-reply )。 |
icmpv6 | type <icmpv6 type> | 匹配 ICMPv6 类型(如 echo-request 、echo-reply )。 |
ip | protocol <protocol> | 匹配 IP 协议类型(如 tcp 、udp )。 |
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> | 匹配连接状态(如 new 、established 、related 、invalid )。 |
动作
动作 | 描述 |
---|---|
accept | 接受数据包 |
drop | 丢弃数据包 |
queue | 将数据包排队到用户空间 |
continue | 继续执行下一条规则 |
return | 从当前链返回并继续上一个链的下一条规则 |
jump <chain> | 跳转到指定链,执行完该链后返回原链 |
goto <chain> | 跳转到指定链,执行完后不再返回原链 |
常用的一些规则配置
# 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: 还没写完,后续在补充~
参考:
- https://dev.to/farshad_nick/iptables-vs-nftables-whats-new-in-linux-firewalling-4a36
- https://cryptsus.com/blog/setting-up-nftables-firewall.html
- https://docs.redhat.com/zh-cn/documentation/red_hat_enterprise_linux/8/html/securing_networks/getting-started-with-nftables_securing-networks#getting-started-with-nftables_securing-networks
- https://www.yisu.com/ask/313080.html
- https://icloudnative.io/posts/using-nftables/#nftables-vs-iptables
- https://blog.csdn.net/hougang/article/details/133393806