尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

从iptables到nftables:Linux防火墙统一框架实战指南

从iptables到nftables:Linux防火墙统一框架实战指南
📅 发布时间:2026/7/8 16:37:17

1. 项目概述:为什么是nftables?

如果你在Linux服务器上待过一段时间,肯定和iptables打过交道。它就像一位功勋卓著的老兵,守护了Linux网络二十多年。但老兵也有老兵的局限:规则多了性能下降、语法复杂、IPv4和IPv6还得分开管理。所以,当nftables在Linux内核3.13版本中悄然登场,并在后续版本中逐渐成熟,最终成为主流发行版的默认防火墙后端时,我知道,是时候该换换脑子了。

nftables不是对iptables的简单修补,而是一次彻底的重构。它用一个统一的框架,取代了原先iptables、ip6tables、arptables和ebtables这“四大金刚”。这意味着,无论你处理的是IPv4、IPv6还是ARP包,都只需要学习和使用一套语法和工具——nft命令。内核层面的优化,比如规则集的编译和基于Netfilter的钩子(hook)高效执行,让它在处理大量规则时,性能表现往往更优。更重要的是,它的配置语法更清晰、更富有表达力,像写一个简单的脚本一样去定义防火墙策略,这在管理复杂网络环境时,优势是决定性的。

这篇内容,就是把我从iptables“移民”到nftables的实战经验,以及这几年在生产环境里摸爬滚打攒下的配置心得,系统地整理出来。我的目标很明确:让你看完之后,不仅能理解nftables的核心思想,更能直接上手,用我提供的示例去搭建、调试和管理你自己的防火墙。无论你是刚接触Linux网络安全的运维新人,还是想从iptables平滑过渡的老手,这里都有你需要的“干货”。

2. nftables核心概念与架构解析

要玩转nftables,死记硬背命令是没用的,必须从根上理解它的设计哲学。它把防火墙规则看作是对网络数据包的一次“审判”流程,而这个流程由几个核心部件精密协作完成。

2.1 规则集、表、链与规则:四层结构

你可以把nftables的配置想象成一本书。

  • 规则集:就是整本书。它是所有nftables配置的顶层容器,系统启动时从/etc/nftables.conf(通常)加载的就是它。
  • 表:书里的各个章节。表是链的容器,并且与特定的“地址族”绑定。主要的地址族有:
    • ip:处理IPv4数据包(对应旧的iptables)。
    • ip6:处理IPv6数据包(对应旧的ip6tables)。
    • inet:同时处理IPv4和IPv6数据包。这是最常用、最高效的选择,一套规则管两种协议。
    • arp:处理ARP协议数据包。
    • bridge:处理桥接网络的数据包。
    • netdev:在数据包进入网络协议栈之前进行处理,用于早期过滤。
  • 链:章节里的具体段落。链是规则的容器,它被绑定在Netfilter内核框架的特定“钩子点”上。数据包流经网络协议栈时,会触发这些钩子,从而进入对应的链进行处理。主要的钩子点有:
    • prerouting:数据包进入网卡后,进行路由决策之前。
    • input:数据包目的地是本机。
    • forward:数据包需要被转发到其他机器。
    • output:由本机进程产生的数据包,准备发送出去。
    • postrouting:数据包离开本机之前,路由决策之后。
  • 规则:段落里的句子。规则是具体的行动指令,由表达式和语句构成。表达式用于匹配数据包(比如源IP、目标端口),语句则定义匹配后的动作(比如接受、丢弃、跳转)。

一个简单的结构示例在脑海中应该是这样的:一本叫规则集的书,里面有一个叫inet的章节(表),这个章节里有一段叫filter_input的段落(链),段落里写着“如果数据包来自192.168.1.0/24网段且目标端口是22,那么就接受它”这样一条句子(规则)。

2.2 地址族与钩子:理解数据包的生命周期

选择正确的地址族和钩子,是编写有效规则的前提。我强烈建议,除非有特殊需求,否则新建表时优先使用inet地址族。它创建的链能同时看到IPv4和IPv6的数据包,极大地简化了配置。

理解钩子,就是理解数据包在你机器里的“旅行路线”:

  1. 一个外部数据包到达网卡,首先进入prerouting钩子。这里通常做网络地址转换或连接跟踪。
  2. 内核查看数据包目标IP,如果是本机,则送入input钩子。你的防火墙规则在这里决定是否允许这个包交给本地进程。
  3. 如果目标IP不是本机,且内核启用了转发功能,则送入forward钩子。你的防火墙规则在这里决定是否允许转发这个包。
  4. 本地进程产生的数据包,首先进入output钩子。
  5. 无论是转发还是本地发出的包,在离开网卡前,都会经过postrouting钩子,通常在这里做源地址转换。

你的防火墙链,就需要挂载在这些关键的“检查点”上。

2.3 匹配器、语句与动作:构建规则的基石

一条规则的威力,全在于匹配器和语句的组合。

  • 匹配器:使用nft命令的表达式语法,非常灵活。
    • ip saddr 192.168.1.0/24:匹配IPv4源地址。
    • ip6 daddr fe80::/10:匹配IPv6目标地址。
    • tcp dport { 22, 80, 443 }:匹配TCP目标端口(支持端口集合)。
    • ct state new,established:匹配连接跟踪状态为“新建”或“已建立”。
    • meta iifname “eth0”:匹配输入网络接口名。
  • 语句与动作:
    • accept:接受数据包。
    • drop:丢弃数据包,不发送任何响应。
    • reject:拒绝数据包,并发送拒绝响应(如TCP RST)。
    • log:将数据包信息记录到内核日志。
    • counter:对匹配的数据包进行计数。
    • jump/goto:跳转到另一个用户自定义链。

注意:drop和reject的区别很重要。drop是“静默丢弃”,对方会一直等待超时,像石沉大海。reject是“明确拒绝”,会立刻告诉对方“不行”,比如对TCP连接发送RST复位包。在对外服务时,根据安全策略谨慎选择。对内网管理流量误用drop,可能会导致排障时非常困惑。

3. 从零开始:nftables安装与基础配置

理论说再多,不如动手敲一行命令。我们从一个干净的环境开始,搭建一个可用的nftables防火墙。

3.1 安装与启停

在主流发行版上,安装nftables通常很简单:

# 对于基于RHEL/CentOS/Fedora的系统 sudo dnf install nftables -y # 或 sudo yum install nftables -y # 对于基于Debian/Ubuntu的系统 sudo apt update && sudo apt install nftables -y

安装后,需要设置开机自启并启动服务:

sudo systemctl enable nftables sudo systemctl start nftables

关键点来了:nftables服务启动时,会自动从/etc/nftables.conf(或其他发行版指定的默认路径,如/etc/sysconfig/nftables.conf可能指向它)加载规则。所以,我们后续的所有配置,最终都要持久化到这个文件里。

检查服务状态和当前规则集:

sudo systemctl status nftables sudo nft list ruleset # 查看当前内存中的所有规则

3.2 你的第一个nftables规则集

让我们清空默认规则,从头创建一个简单的、允许SSH和Ping,拒绝其他所有入站流量的防火墙。

首先,备份现有配置,然后清空规则集:

sudo cp /etc/nftables.conf /etc/nftables.conf.bak sudo nft flush ruleset # 清空内存中所有规则

现在,我们通过nft命令交互式地创建规则,最后再保存到配置文件。

  1. 创建一个inet族(同时处理IPv4/IPv6)的表,命名为filter:

    sudo nft add table inet filter
  2. 在filter表中创建三条链:

    • input链:处理发送到本机的数据包。策略设为drop(默认拒绝)。
    • forward链:处理转发的数据包。策略设为drop。
    • output链:处理本机发出的数据包。策略设为accept(默认允许,通常更安全且方便)。
    sudo nft add chain inet filter input { type filter hook input priority 0\; policy drop\; } sudo nft add chain inet filter forward { type filter hook forward priority 0\; policy drop\; } sudo nft add chain inet filter output { type filter hook output priority 0\; policy accept\; }

    这里priority 0是链的优先级,数字越小优先级越高。对于filter表,0是标准值。

  3. 为input链添加规则:

    • 允许本地回环接口流量:这是系统内部通信必需的。
      sudo nft add rule inet filter input iif “lo” accept
    • 允许已建立和相关联的连接:这是状态化防火墙的核心,允许对外请求的回应包进来。
      sudo nft add rule inet filter input ct state established,related accept
    • 允许ICMP协议(Ping):网络诊断需要。
      sudo nft add rule inet filter input ip protocol icmp accept sudo nft add rule inet filter input ip6 nexthdr icmpv6 accept
    • 允许TCP端口22(SSH):为了我们能远程管理服务器。
      sudo nft add rule inet filter input tcp dport 22 accept

    实操心得:规则的顺序就是防火墙的检查顺序,从上到下执行,一旦匹配就执行动作并停止。所以,一定要把最常用、匹配范围最广的规则(如established,related)放在前面,把最具体的规则(如开放某个端口)放在后面,最后才是默认的拒绝策略。这能显著提升防火墙处理性能。

  4. 保存配置: 现在内存中的规则已经生效了。为了永久保存,我们需要将当前规则集导出到配置文件。

    sudo nft list ruleset > /etc/nftables.conf

    现在,你的/etc/nftables.conf文件里应该已经有了完整的规则定义。下次系统重启或nftables服务重启时,会自动加载这些规则。

  5. 验证配置:

    • 尝试从另一台机器Ping你的服务器,应该能通。
    • 尝试SSH到你的服务器,应该能连接。
    • 尝试用nmap扫描一个未开放的端口(如80),应该显示被过滤或关闭。
    • 随时使用sudo nft list ruleset来查看完整规则。

4. 进阶实战:常见场景配置示例

基础框架搭好了,我们来看看在实际工作中,如何用nftables解决具体问题。以下示例均基于上面创建的inet filter表。

4.1 示例一:Web服务器防火墙配置

假设你有一台运行Nginx/Apache的Web服务器,需要开放HTTP/HTTPS,同时允许SSH管理,并做一些基本的安全加固。

# 清空input链原有规则(谨慎操作,最好在已有允许SSH的规则基础上添加) # 假设我们基于之前的配置继续 # 1. 允许HTTP (80) 和 HTTPS (443) sudo nft add rule inet filter input tcp dport { 80, 443 } accept # 2. 限制SSH访问源IP(强烈建议!) # 假设你的管理IP是 203.0.113.10 sudo nft insert rule inet filter input position 3 tcp dport 22 ip saddr 203.0.113.10 accept # 注意:这里用了‘insert’和‘position 3’,是为了把这条更具体的规则插入到‘允许所有22端口’规则之前,并覆盖它。 # 你需要先找到‘tcp dport 22 accept’规则的位置(用‘sudo nft list chain inet filter input’查看行号)。 # 3. 防御SYN Flood攻击(简易版) # 创建一个名为‘syn_flood’的独立链来处理 sudo nft add chain inet filter syn_flood sudo nft add rule inet filter syn_flood limit rate 10/second burst 20 packets return sudo nft add rule inet filter syn_flood drop # 在input链中,将TCP SYN包跳转到这个链处理 sudo nft insert rule inet filter input position 4 tcp flags syn ct state new jump syn_flood # 4. 记录并丢弃非法状态包 sudo nft add rule inet filter input ct state invalid log prefix “Invalid packet: “ group 0 drop

配置解析:

  • 端口集合:{ 80, 443 }语法可以一次匹配多个端口,比写两条规则更简洁高效。
  • 规则顺序管理:insert和position参数是精细化管理规则顺序的利器。一定要善用list chain查看现有规则顺序后再插入。
  • 限速与防攻击:limit rate语句是nftables的“神器”之一,可以轻松实现包速率限制。上面的例子限制了每秒最多10个新SYN连接,突发允许20个,超过则丢弃。这能有效缓解简单的SYN洪水攻击。
  • 连接跟踪与日志:ct state invalid匹配那些不符合任何已知连接的数据包(比如没有三次握手的TCP包),记录日志并丢弃,是很好的安全实践。

4.2 示例二:配置网络地址转换

如果你的服务器充当网关或路由器,需要为内网设备提供NAT上网服务,配置如下:

  1. 启用内核IP转发:

    echo “net.ipv4.ip_forward=1” | sudo tee -a /etc/sysctl.conf echo “net.ipv6.conf.all.forwarding=1” | sudo tee -a /etc/sysctl.conf sudo sysctl -p
  2. 创建nat表并添加规则:

    # 创建nat表 sudo nft add table ip nat # 创建postrouting链(SNAT:源地址转换,内网出外网) sudo nft add chain ip nat postrouting { type nat hook postrouting priority 100\; } # 假设外网网卡是eth0,内网网段是192.168.100.0/24 sudo nft add rule ip nat postrouting ip saddr 192.168.100.0/24 oifname “eth0” masquerade

    masquerade动作会自动使用外网接口的IP作为源地址进行转换,特别适合动态获取IP(如PPPoE)的环境。如果是固定IP,也可以用snat to 你的公网IP。

  3. 在filter表中允许转发(基于之前的filter表):

    # 允许内网到外网的转发(状态化,已建立和相关的连接自动允许) sudo nft add rule inet filter forward ct state established,related accept # 允许从内网接口(假设是eth1)发起的新连接转发到外网 sudo nft add rule inet filter forward iifname “eth1” oifname “eth0” ct state new accept

    别忘了将/etc/nftables.conf中的filter表的forward链默认策略从drop改为accept,或者确保你的允许规则在默认拒绝之前。更安全的做法是保持policy drop,但用明确的规则允许特定流量。

4.3 示例三:利用集合与命名集管理IP和端口

当需要管理大量IP或端口时,一条条写规则是噩梦。nftables的命名集功能完美解决了这个问题。集合可以存储IP、端口、MAC地址等,并且支持动态更新。

场景:我们需要允许一个IP列表访问管理端口(22),并阻止一个黑名单IP列表访问任何服务。

# 1. 创建两个IP地址集合 sudo nft add set inet filter admin_whitelist { type ipv4_addr\; flags interval\; } sudo nft add set inet filter attacker_blacklist { type ipv4_addr\; } # 2. 向集合中添加元素 sudo nft add element inet filter admin_whitelist { 192.168.1.100, 192.168.1.200-192.168.1.210 } sudo nft add element inet filter attacker_blacklist { 10.0.0.5, 10.0.0.77 } # 3. 在规则中引用集合 # 将允许白名单IP访问SSH的规则放在前面(假设input链已有基础规则) sudo nft insert rule inet filter input position 3 ip saddr @admin_whitelist tcp dport 22 accept # 在链的靠前位置(在允许某些服务之前)丢弃黑名单IP sudo nft insert rule inet filter input position 1 ip saddr @attacker_blacklist drop # 4. 动态管理集合(无需重载整个规则集) # 临时添加一个IP到黑名单 sudo nft add element inet filter attacker_blacklist { 10.0.0.99 } # 从黑名单中删除一个IP sudo nft delete element inet filter attacker_blacklist { 10.0.0.77 }

优势:

  • 管理高效:IP列表变化时,只需更新集合,无需修改和重载规则。
  • 性能优异:nftables内部对集合查询进行了高度优化,即使集合很大,匹配速度也很快。
  • 灵活:支持单个地址、范围、网络段等多种格式。

4.4 示例四:流量统计与日志记录

监控和审计是安全运维的重要部分。

# 1. 为特定端口的流量添加计数器 # 统计HTTP和HTTPS端口的入站流量 sudo nft add rule inet filter input tcp dport { 80, 443 } counter accept # 之后可以用 ‘sudo nft list ruleset’ 查看计数器数值 # 2. 记录被拒绝的SSH尝试(记录到内核日志,如/var/log/kern.log) sudo nft add rule inet filter input tcp dport 22 log prefix “SSH Reject: “ group 0 level info drop # 这条规则需要放在‘允许SSH’规则之后,默认策略之前。 # 3. 创建一个专门的日志链(更清晰的管理) sudo nft add chain inet filter log_chain sudo nft add rule inet filter log_chain log prefix “Dropped: “ group 0 sudo nft add rule inet filter log_chain drop # 然后在input链末尾跳转到这个链 sudo nft add rule inet filter input jump log_chain

使用counter可以很方便地查看流量情况。而log语句对于调试防火墙规则、发现攻击尝试至关重要。prefix参数可以帮助你在系统日志中快速定位防火墙日志。

5. 运维与排障:让防火墙稳定可控

配置好了不是结束,日常管理和问题排查才是真正的开始。

5.1 规则管理最佳实践

  • 配置文件是王道:所有修改最终都应反映在/etc/nftables.conf中。交互式命令用于测试,测试无误后务必sudo nft list ruleset > /etc/nftables.conf保存。
  • 使用注释:nftables配置文件支持以#开头的注释。为复杂的规则或集合添加注释,几个月后你一定会感谢自己。
    # 允许办公室IP段访问管理服务 add rule inet filter input ip saddr @office_ips tcp dport { 22, 9090 } accept
  • 版本控制:将/etc/nftables.conf纳入Git等版本控制系统,每次变更都有记录,可以轻松回滚。
  • 测试规则:在应用新规则集前,可以先将其保存到一个临时文件(如new_rules.nft),然后用sudo nft -f new_rules.nft加载测试。确认无误后再覆盖正式配置。

5.2 常见问题与排查技巧

防火墙配置不当,最容易导致“服务器失联”。这里有几个救命锦囊:

  1. 规则不生效?检查顺序和默认策略。

    • 使用sudo nft list ruleset或sudo nft list chain <表> <链>仔细查看规则顺序。记住,数据包从上到下匹配,第一条匹配的规则决定其命运。
    • 确认链的默认策略(policy)。如果你的规则都是accept,但链的默认策略是drop,并且没有规则匹配,数据包就会被丢弃。
  2. 把自己关在门外了?配置“逃生舱”规则或使用本地控制台。

    • 方法一(推荐):在input链的最前面,添加一条允许来自本地某个“管理VLAN”或特定安全IP的SSH流量的规则。这样即使后面的规则配置错误,你还能从这个受信的入口进入。
    • 方法二:在物理服务器上,可以配置一个cron任务,每隔几分钟检查SSH端口是否可达,如果不可达,则自动回滚到一个已知的安全配置。这是一个高风险操作,需谨慎设计。
    • 方法三:如果以上都没做,只能通过云服务商的控制台、IPMI、或物理接触服务器来修复了。
  3. 使用日志定位问题。

    • 在怀疑被错误阻止的规则前插入log语句。
    • 使用sudo tail -f /var/log/kern.log或sudo journalctl -f实时查看内核日志,观察数据包被匹配和处理的轨迹。
  4. 连接跟踪相关问题。

    • 如果FTP、SIP等复杂协议的服务不正常,可能是需要加载特定的连接跟踪辅助模块。
    • 检查/proc/sys/net/netfilter/nf_conntrack_max,如果服务器并发连接数很高,可能需要调大这个值,防止连接跟踪表满导致新连接被丢弃。

5.3 性能监控与优化

  • 查看规则统计:使用sudo nft list ruleset可以看到每条规则匹配的计数器(如果添加了counter语句)。这有助于了解哪些规则最活跃,优化规则顺序(将匹配频率高的规则上移)。
  • 简化规则:尽量使用集合、端口范围、IP网段来合并规则,减少规则总数。
  • 谨慎使用log:在高流量环境下,日志记录会带来巨大性能开销。生产环境中,通常只对可疑或拒绝的流量进行抽样记录,而不是全部记录。

从iptables切换到nftables,初期会有些不习惯,但一旦熟悉了它统一、清晰的语法和强大的功能,你就再也回不去了。它带来的管理效率和性能提升,在复杂的网络环境中尤其明显。我个人的经验是,将旧的iptables脚本用iptables-translate工具转换,可以作为起点,但亲手用nftables的逻辑重新设计和编写规则,才能真正发挥它的威力。最后,永远记住防火墙的金科玉律:默认拒绝,最小权限开放。

相关新闻

  • QMcDump工具全解析:解密QQ音乐加密音频与跨平台格式转换
  • pyodbc深度解析:高性能Python ODBC桥接架构设计与企业级数据库集成方案
  • MATLAB写的脑电实时采集小工具:串口接硬件、界面看波形、一键存数据

最新新闻

  • 3D 点云语义分割模型轻量化:从 RandLA-Net 1.2M 参数量到实时推理的 4 步优化
  • CobaltStrike二次开发实战:从反编译到流量与载荷免杀全流程解析
  • 终极指南:5个技巧快速掌握Lan Mouse跨设备键鼠共享
  • 3步解决电脑存储空间告急:用dupeguru智能清理重复文件
  • Java加密开发实战:Bouncy Castle核心架构、国密算法与性能调优指南
  • SQL注入纵深防御实战:从参数化查询到四层安全模型

日新闻

  • PROPKA 3深度解析:蛋白质pKa预测的实战指南与算法原理
  • 微信小程序 globalData 监听:基于 Object.defineProperty 的 3 种实现方案对比
  • MySQL 8.0 数据清洗实战:3类异常值识别与 UPDATE/DELETE 批量处理

周新闻

  • 基于YOLOv12的番茄成熟度智能检测系统开发
  • 终极RimWorld模组管理指南:用RimSort告别模组冲突烦恼
  • AI Agent框架开发:从理论到实践的完整指南

月新闻

  • 2026年6月公司网站搭建最新热门渠道测评:四大低成本/零代码平台对比+避坑
  • 【Linux】Linux arm 编译QT程序,出现expected “}“报错
  • 【MATLAB例程】四基站二维AOA定位与距离辅助增强对比仿真。基于角度观测和测距修正的固定目标平面定位精度分析

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号