Loading... ## 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中允许用户自定义表,而且表是创建规则管理的第一步 ```bash 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 | ```bash 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>` | 跳转到指定链,执行完后不再返回原链 | 常用的一些规则配置 ```bash # 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 Last modification:April 25, 2025 © Allow specification reprint Support Appreciate the author Like 如果觉得我的文章对你有用,请随意赞赏