Linux防火墙体系经过多年发展,目前主流的四种工具分别是iptablesnftablesfirewalldUFW。它们底层都基于内核的Netfilter框架,但设计哲学、操作方式和适用场景各有不同。

下面的对比表格可以帮你快速了解它们的核心差异:

特性 iptables nftables firewalld UFW
核心定位 传统的底层规则管理工具 iptables的现代替代品,新一代内核框架 动态防火墙管理服务(守护进程) iptables/nftables的前端简化工具
设计哲学 基于表(tables)链(chains)规则(rules) 的线性匹配 基于声明式规则集(ruleset),引入集合(sets)映射(maps) 等高级数据结构 基于区域(zones)服务(services) 的抽象管理 极简主义,命令接近自然语言,隐藏底层细节
主要优势 极其灵活,功能强大,支持复杂的NAT和包修改 性能更高(优化了规则遍历),语法更统一,支持动态更新和批量操作,可脚本化 动态管理:修改规则无需重启服务,不中断连接;区域化:为不同网络环境(如家庭、公共)快速切换策略集 简单易用:语法简洁,适合Linux初学者、桌面用户或快速配置基本策略
主要劣势 语法晦涩,规则变更通常需要全部重载,规则量大时性能下降 学习曲线陡峭,理解其声明式语法和数据结构需要一定时间 概念相对抽象,若需要配置非常底层的、复杂的NAT规则,不如直接操作iptables/nftables灵活 功能相对有限,不适合处理极其复杂的网络拓扑和防火墙策略
常见发行版 几乎所有Linux发行版,曾是RHEL 6/CentOS 6及更早版本的核心 较新发行版,如Debian 10+、Fedora、RHEL 9+已将其作为底层默认 RHEL/CentOS 7+、Fedora的默认防火墙管理工具 Ubuntu、Debian桌面的默认防火墙管理工具
底层关系 直接与Netfilter交互 直接与Netfilter交互,旨在完全替代iptables 底层可以使用iptables或nftables作为后端 底层可以使用iptables或nftables作为后端

以下是每种工具的详细介绍:

🛠️ iptables:传统而强大的底层工具

iptables是Linux防火墙界的"老兵"。它直接与内核中的Netfilter框架对话,通过维护一系列规则来工作。这些规则被组织在(如filter表用于过滤,nat表用于地址转换)和(如INPUTOUTPUTFORWARD)中。

🚀 nftables:iptables的现代继任者

为了解决iptables的一些固有限制(如语法混乱、性能瓶颈、代码重复),nftables应运而生。它也被设计为Linux内核的新一代包过滤框架。

🔥 firewalld:动态区域管理专家

firewalld是Red Hat家族(RHEL/CentOS/Fedora)力推的防火墙管理工具。它最大的特点是动态区域化

😊 UFW:简单易用的代名词

UFW的名字"Uncomplicated Firewall"(不复杂的防火墙)就揭示了它的全部使命——让防火墙配置变得简单。

1. 查看现有规则集(避免重复添加)

bash
复制
sudo nft list ruleset

2. 开放 TCP 端口(例如 80)

假设你已经有一个 inet filter 表,并且其中包含一个挂载在 input 钩子上的基链:

bash
复制
sudo nft add rule inet filter input tcp dport 80 accept

3. 开放 UDP 端口(例如 53)

bash
复制
sudo nft add rule inet filter input udp dport 53 accept

4. 开放端口范围(例如 1000-2000)

bash
复制
sudo nft add rule inet filter input tcp dport 1000-2000 accept

5. 同时开放 TCP 和 UDP 的同一端口(例如 53)

可以分别添加两条规则,或使用集合简化:

bash
复制
# 分别添加
sudo nft add rule inet filter input tcp dport 53 accept
sudo nft add rule inet filter input udp dport 53 accept

# 或者使用集合(更简洁)
sudo nft add rule inet filter input meta l4proto { tcp, udp } th dport 53 accept

th dport 是传输层目标端口的通用表达式,适用于 TCP 和 UDP。

6. 如果表或链不存在,需要先创建

bash
复制
# 创建 inet 家族的 filter 表
sudo nft add table inet filter

# 创建 input 基链(类型 filter,钩子 input,优先级 0;默认策略可以先设为 accept 以免锁住自己)
sudo nft add chain inet filter input { type filter hook input priority 0 \; policy accept \; }

注意:在链中设置 policy accept 表示默认允许,然后再添加 drop 规则来限制。更常见的做法是将默认策略设为 drop,然后显式开放需要的端口。但若远程操作,请务必先添加允许自己当前连接的规则(如 SSH 端口),再将策略改为 drop,以免失联。


规则持久化

上述命令添加的规则重启后会丢失。要使规则永久生效,需要将当前规则集保存到配置文件,并启用 nftables 服务。

  1. 保存规则

    bash
    复制
    sudo nft list ruleset > /etc/nftables.conf
  2. 启用并启动服务

    bash
    复制
    sudo systemctl enable nftables.service
    sudo systemctl start nftables.service

之后每次开机都会自动加载 /etc/nftables.conf 中的规则。


常用变体


提示


nftables 中实现“仅允许22端口,禁止其他所有入站流量”的核心策略是:设置默认丢弃(drop)策略,然后显式添加允许(accept)规则

这里有两条路径可以达到目的:一是通过命令行快速配置,适合临时调试;二是通过编写脚本文件进行原子性加载,这是生产环境(尤其是远程操作)唯一推荐的安全方式

💡 核心配置步骤

无论哪种方式,一个健壮的最小化安全规则集都至少包含以下三条规则,它们必须按此顺序出现在默认丢弃策略之前:

  1. 放行回环接口:确保本机内部通信正常。
  2. 放行已建立的连接:保证你当前SSH会话(以及后续响应)不会中断。
  3. 放行新的SSH连接:明确允许外部访问22端口。

🛠️ 方案一:命令行逐条添加(适合本地或测试环境)

如果你可以直接在机器前操作,或者想快速测试,可以按以下步骤执行。请注意,如果是远程操作,千万不要在最后一步之前执行设置默认策略的命令,否则会立刻断连!

bash
复制
# 1. 假设你已经有了 inet filter 表和 input 链(如果没有,参考上一轮回复创建)
# 2. 添加基础放行规则(顺序重要!)
sudo nft add rule inet filter input iifname "lo" accept
sudo nft add rule inet filter input ct state established,related accept
sudo nft add rule inet filter input tcp dport 22 accept

# 3. 【高风险!远程操作慎行】将input链的默认策略设置为drop
#    只有在前三条规则成功添加后,才能执行这一步
sudo nft chain inet filter input '{ policy drop ; }'

# 4. 验证规则
sudo nft list ruleset

📜 方案二:脚本原子加载(生产环境标准)

这是最安全的方法。我们将所有规则写在一个文件中,然后一次性加载,整个过程是原子的,要么全部成功,要么失败回滚,不会出现中间状态导致断连。

  1. 创建规则文件 (例如 ~/my-firewall.nft):

    bash
    复制
    cat > ~/my-firewall.nft << EOF
    #!/usr/sbin/nft -f
    
    # 原子性地清空当前所有规则
    flush ruleset
    
    table inet filter {
        chain input {
            type filter hook input priority 0; policy drop;
    
            # 允许本地回环接口通信
            iifname "lo" accept
            # 允许已建立的连接及相关连接(保证SSH会话不中断)
            ct state established,related accept
            # 明确放行 TCP 22 端口 (SSH)
            tcp dport 22 accept
    
            # (可选)在此处添加其他允许的规则,例如 80, 443
            # tcp dport {http, https} accept
    
            # 所有未被上面规则匹配的流量,最终都会被链的默认策略 "drop" 处理
            # 可以添加一条日志规则来记录被丢弃的包(调试用)
            # log prefix "Dropped by firewall: " counter drop
        }
    
        chain forward {
            type filter hook forward priority 0; policy drop;
        }
    
        chain output {
            type filter hook output priority 0; policy accept;
        }
    }
    EOF

    这段配置清晰地定义了我们的目标:默认丢弃输入,只开放22端口。

  2. 原子性加载规则

    bash
    复制
    sudo nft -f ~/my-firewall.nft

    这条命令会一次性应用整个规则集。如果文件中有语法错误,它会拒绝加载并保持你原有的防火墙状态,这是保护远程连接的关键

  3. 验证并持久化

    bash
    复制
    # 查看当前生效的规则
    sudo nft list ruleset
    
    # 如果一切正常,将其保存为系统启动时的默认规则
    sudo cp ~/my-firewall.nft /etc/nftables.conf
    # 确保 nftables 服务已启用并启动
    sudo systemctl enable nftables.service
    sudo systemctl start nftables.service

⚠️ 远程操作的“救命”提醒

你当前是通过SSH远程操作吗?如果是的话,强烈建议使用方案二来确保安全。