作为一个 Linux 用户,你肯定经历过这样的时刻:
想开个 80 端口,搜到一条命令是 iptables -I INPUT -p tcp --dport 80 -j ACCEPT
换了台 Ubuntu 服务器,教程又让你用 ufw allow 80
到了 CentOS 7/8,系统告诉你 iptables 过时了,请用 firewall-cmd --add-port=80/tcp

这时候你可能会想:为什么 Linux 有这么多防火墙?它们是竞争关系?替代关系?还是根本就是同一个东西换了层皮?

今天我们就来把这团乱麻彻底理清楚。


一、 核心真相:它们都只是“遥控器”

首先要揭露一个真相:iptables、ufw、firewalld,严格来说都不是真正的防火墙。

Linux 真正的防火墙藏在操作系统内核里,它的名字叫 Netfilter

  • **Netfilter (内核态)**:它是 Linux 内核的一个框架,负责在网络协议栈中“抓包”、修改包、过滤包。它是真正的干活人,住在内核空间,普通用户接触不到。
  • 用户态工具:iptables、ufw、firewalld 都是运行在用户空间的工具。它们的作用是提供一个操作界面(CLI),让你输入规则,然后它们把这些规则“翻译”给 Netfilter 听。

打个比方:
Netfilter 是空调外机(核心制冷),而 iptables/ufw/firewalld 是空调遥控器。虽然遥控器长得不一样,有的按键多,有的按键少,但最终控制的都是同一台空调。


二、 演变史:从“汇编”到“高级语言”

要理清它们的关系,我们需要看一看 Linux 防火墙管理的进化史。

1. 统治者:iptables

在很长一段时间里(Linux 2.4/2.6 内核时代),iptables 是唯一的王者。

  • 地位:它是最接近内核的工具。你写的每一条 iptables 规则,几乎都是直接对应 Netfilter 的钩子。
  • 特点:功能极其强大,但也极其复杂。你需要理解“四表五链”(Filter/NAT 表,INPUT/OUTPUT 链等),命令参数晦涩难懂。
  • 问题
    • 配置难:新手很容易把自己锁在外面。
    • 静态:每次修改规则,都需要重新加载整个规则集,会导致短暂的网络连接中断(对于有状态防火墙是致命的)。

2. 简化派:UFW (Uncomplicated Firewall)

Debian 和 Ubuntu 的开发者觉得 iptables 太难用了,于是开发了 UFW

  • 定位iptables 的前端封装
  • 关系:UFW 并不是取代了 iptables,当你执行 ufw allow 80 时,它后台默默地把这条命令转换成了复杂的 iptables 规则,然后交给内核。
  • 特点:主打“简单”。没有复杂的链表概念,只有“允许”和“拒绝”。
  • 适用:Ubuntu/Debian 系默认工具,适合只需要简单开关端口的用户。

3. 动态派:Firewalld

RedHat(CentOS/Fedora)阵营则开发了 Firewalld

  • 定位iptables 的下一代前端(后来后端切到了 nftables)
  • 关系:它也是一个管理器。早期版本底层调用 iptables,新版本底层调用 nftables。
  • 核心创新
    1. 区域(Zone):引入了类似 Windows 防火墙的“家庭网络”、“公共网络”概念。你可以给不同的网卡绑定不同的区域,应用不同的规则。
    2. 动态更新(Dynamic):修改规则不需要重载整个防火墙,不会断开现有的连接。这对于服务器运维非常重要。
    3. D-Bus 接口:允许其他程序通过 API 动态调整防火墙规则(比如 libvirt 虚拟化工具)。

4. 继承者:nftables

这是 Netfilter 项目组自己搞出来的“亲儿子”,旨在彻底取代 iptables。

  • 定位新一代的内核包过滤框架 + 用户态工具
  • 现状:现代 Linux 发行版(如 CentOS 8+, Debian 10+)的内核其实已经用 nftables 替代了 iptables 的内核模块。
  • 尴尬的兼容:为了兼容旧脚本,现在的 iptables 命令实际上是一个软链接,指向 iptables-nft,它会把 iptables 语法翻译成 nftables 字节码执行。

三、 关系图谱:一图看懂

如果我们把它们排个序,大概是这样的层级关系:

场景 A(经典 Ubuntu):
用户 -> ufw 命令 -> iptables 命令 -> Netfilter (内核)

场景 B(经典 CentOS 7):
用户 -> firewall-cmd 命令 -> firewalld 守护进程 -> iptables 命令 -> Netfilter (内核)

场景 C(现代 Linux):
用户 -> firewall-cmd 命令 -> firewalld 守护进程 -> nftables 接口 -> Netfilter (内核)


四、 到底该用哪个?

弄明白了关系,选择就变得很简单了:

  1. 如果你是 Ubuntu/Debian 用户,且只需要简单的“开个 80 端口”、“关个 SSH”,请用 UFW

    • 命令:ufw enable, ufw allow 80/tcp
    • 理由:简单,心智负担小。
  2. 如果你是 CentOS/RedHat/Fedora 用户,或者你的环境比较复杂(有虚拟化、容器、多网卡),请用 Firewalld

    • 命令:firewall-cmd --add-port=80/tcp --permanent
    • 理由:它已经集成在系统里,且支持动态更新,适合复杂的运维场景。
  3. 如果你是网络工程师、老派运维,或者需要做极其底层的包转发、NAT 骚操作,可以直接用 nftables(或 iptables)

    • 理由:没有中间商赚差价,性能最好,控制粒度最细。
  4. Docker 用户注意

    • Docker 会直接操作 iptables 规则来做端口映射。所以有时候你发现明明 UFW 关了端口,Docker 容器还能访问,就是因为 Docker 绕过了 UFW 直接改了底层的 iptables。

总结

  • Netfilter 是老板(内核)。
  • iptables 是老管家,事必躬亲但脾气古怪。
  • UFW 是老管家的秘书,只处理简单的事,复杂的还要找管家。
  • Firewalld 是新聘的职业经理人,管理方式更现代,底层既能指挥老管家(iptables),也能指挥新管家(nftables)。

下次再配置防火墙,先看发行版默认给的是什么(Ubuntu 给 UFW,CentOS 给 Firewalld),直接用默认的就好,不用纠结。它们最终都是殊途同归。