别再只知道iptables和firewalld了,最新的nftables不可不知。
2025-08-29 09:12:02
RAIZ
核心结构速览
ip:IPv4 流量 ip6:IPv6 流量 inet:同时处理 IPv4 和 IPv6 流量(双栈管理是其一大优势) arp:ARP 协议数据包 bridge:桥接数据包 netdev:在数据包进入网络设备后非常早的阶段进行处理(Linux kernel 4.2 引入)
例,创建一个名为 my_filter的表来处理 IPv4 和 IPv6 流量:nft add table inet my_filter
type:链类型,如 filter(过滤)、nat(网络地址转换)、route(路由) hook:挂钩点,定义数据包在哪个处理阶段进入该链。例如 input(进入本机)、output(从本机发出)、forward(转发)、prerouting(路由前)、postrouting(路由后) priority:优先级,决定同一挂钩点上多个链的执行顺序。数值越小,优先级越高,越先执行。可以使用预定义名称(如 filter, mangle)或具体数值 policy:链的默认策略,即当所有规则都不匹配时如何处理数据包。常用 accept(接受)或 drop(丢弃)
例,在 inet my_filter表中创建一个名为 input的过滤链,处理进入本机的数据包,优先级为0,默认丢弃:nft add chain inet my_filter input { type filter hook input priority 0 \; policy drop \; }规则是具体的匹配条件和执行动作,存在于链中。
协议匹配:ip、ip6、tcp、udp、icmp等 源/目标地址:ip saddr 192.168.1.100, ip daddr 192.168.1.0/24 源/目标端口:tcp dport 22, udp sport 53 网络接口:iifname "eth0"(入站接口), oifname "eth1"(出站接口) 连接状态:ct state 【established(已链接的),related(相关的),new(新链接的)】 支持多种表达式进行复杂匹配
accept:接受数据包 drop:丢弃数据包,不返回任何信息 reject:拒绝数据包,可返回错误信息(如端口不可达) jump:跳转到指定常规链执行,执行完毕后返回 goto:跳转到指定常规链执行,执行完毕后不返回 return:从当前链返回至上一条规则继续处理 counter:计数器,记录匹配的数据包数量和字节数,用于监控和调试 log:记录数据包日志 masquerade:动态源地址转换(SNAT),常用于出口网关 dnat:目标地址转换 snat:源地址转换
# 允许已建立的和相关的连接nft add rule inet my_filter input ct state established,related accept# 允许来自lo接口的所有流量(本地回环)nft add rule inet my_filter input iifname "lo" accept# 允许SSH连接(端口22)nft add rule inet my_filter input tcp dport 22 ct state new accept# 记录并丢弃所有其他输入流量nft add rule inet my_filter input log prefix "Dropped: " drop
4. 集合 (Set)
集合用于存储一组值(如IP地址、端口号、网络接口等),可以在规则中被引用,使规则更简洁高效,尤其适合管理动态或大量的对象。
•
命名集合:需要先创建,后可动态增删元素。
# 创建一个名为bad_ips的IPv4地址集合nft add set inet my_filter bad_ips { type ipv4_addr \; }# 向集合中添加IP地址nft add element inet my_filter bad_ips { 10.0.0.5, 192.168.1.100 }# 在规则中引用集合(丢弃来自bad_ips集合中IP的流量)nft add rule inet my_filter input ip saddr @bad_ips drop5. 映射 (Map)
映射是键值对的集合,允许根据匹配的键动态选择动作,实现更复杂的策略路由或策略决策。
# 创建一个映射,将目标端口映射到允许的源IP网段nft add map inet my_filter port_to_src { type inet_service : ipv4_addr \; } nft add element inet my_filter port_to_src { 80 : 192.168.1.0/24, 22 : 10.0.0.0/8 }# 规则:检查目标端口,并验证源IP是否在映射定义的对应网段内nft add rule inet my_filter input tcp dport vmap @port_to_src查看规则集:
nft list ruleset列出所有当前生效的规则、表、链和集合。
删除规则:需要先使用
nft -a list ruleset查看规则的handle(句柄,唯一标识),然后nft delete rule [family] [table] [chain] handle [handle_num]。
清空链/表:
nft flush chain [family] [table_name] [chain_name] # 清空链nft flush table [family] [table_name] # 清空表nft flush ruleset # 清空所有规则
持久化保存:规则默认在内存中,重启会丢失。需导出到配置文件并启用服务。
nft list ruleset > /etc/nftables.conf # 导出当前规则systemctl enable nftables --now # 启用并立即启动nftables服务(重启后自动加载规则)
也可在 /etc/nftables.conf中直接编写规则,语法与命令行一致。
流量限速:使用 limit语句限制匹配速率,防止暴力破解或DoS。
# 限制SSH连接尝试速率(每分钟5次,突发5个)nft add rule inet my_filter input tcp dport 22 ct state new limit rate 5/minute burst 5 drop
基于时间的规则:使用 hour和 day字段限制流量在特定时间段。
# 只在工作日9点到17点允许SSHnft add rule inet my_filter input tcp dport 22 time hour 09:00-17:00 day mon,tue,wed,thu,fri accept
NAT(网络地址转换):
# 创建nat表nft add table ip nat# 创建postrouting链做SNAT(Masquerade)nft add chain ip nat postrouting { type nat hook postrouting priority 100 \; } nft add rule ip nat postrouting oifname "eth0" masquerade# 创建prerouting链做DNAT(端口转发)nft add chain ip nat prerouting { type nat hook prerouting priority -100 \; } nft add rule ip nat prerouting iifname "eth0" tcp dport 8080 dnat to 192.168.1.10:80nftables 的核心思想是“表 -> 链 -> 规则”的层级结构,配合丰富的匹配条件和动作,以及高效的集合和映射。建议从简单的规则开始,逐步尝试更复杂的功能。多使用 nft list ruleset查看当前配置,并善用持久化保存。