当前位置:首页>Linux>Linux 系统运维工程师必备工具箱(第13篇)之防火墙工具对比:iptables vs firewalld vs ufw

Linux 系统运维工程师必备工具箱(第13篇)之防火墙工具对比:iptables vs firewalld vs ufw

  • 2026-10-11 08:30:13
Linux 系统运维工程师必备工具箱(第13篇)之防火墙工具对比:iptables vs firewalld vs ufw

作为一位在运维一线摸爬滚打多年的老兵,我深知在Linux系统上管理网络流量,选对工具并理解其背后的逻辑,是保障服务稳定运行的关键一环。今天,我想借这篇“交付排坑记”,聊聊我在iptables、firewalld和ufw这三个网络边界防护工具之间切换、踩坑、最终游刃有余的真实经历。

初入行:与iptables的“硬核”对话

我的职业生涯是从直接编辑iptables规则开始的。那时候,系统还是CentOS 6,firewalld尚未普及。坦白说,iptables的学习曲线非常陡峭,但它的强大和灵活也让我着迷。

一个典型的“交付”场景:我们需要为刚上线的Web服务开放80和443端口,同时控制SSH访问来源。

我的“排坑”过程是这样的:

  1. 先清空规则,避免冲突:这是新手最容易忽略的。直接追加规则,如果前面有默认DROP策略,可能把自己锁在门外。

    # 先放行当前SSH连接,防止断连
    iptables -I INPUT 1 -p tcp --dport 22 -j ACCEPT
    # 清空filter表规则
    iptables -F
    # 删除自定义链(如果有)
    iptables -X
  2. 设置默认策略:通常设置为DROP所有入站流量,再逐一放行。

    iptables -P INPUT DROP
    iptables -P FORWARD DROP
    iptables -P OUTPUT ACCEPT
  3. 放行必要流量:

    # 允许回环接口
    iptables -A INPUT -i lo -j ACCEPT
    # 允许已建立的连接(关键!否则SSH、HTTP响应会断)
    iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
    # 放行Web服务
    iptables -A INPUT -p tcp --dport 80 -j ACCEPT
    iptables -A INPUT -p tcp --dport 443 -j ACCEPT
    # 控制SSH仅来自内网
    iptables -A INPUT -p tcp -s 10.0.0.0/8 --dport 22 -j ACCEPT

踩坑点:最痛苦的是规则顺序。iptables是线性匹配,一旦匹配就停止。我曾把“拒绝所有”的规则放在了“放行SSH”之前,结果自己把自己关在机房门外,最后只能通过带外管理卡(如iLO、iDRAC)重启恢复。另一个坑是规则持久化。iptables命令修改的是内存中的规则,重启后失效。必须手动执行service iptables save(CentOS 6)或安装iptables-persistent(Debian/Ubuntu)来保存规则。

拥抱时代:firewalld的“区域”思维

当CentOS 7成为主流,firewalld作为默认网络边界防护工具登场。起初我内心是拒绝的,觉得它“多此一举”。但深入使用后,我意识到它的设计哲学——动态管理和区域划分,非常适合现代数据中心和云环境。

排坑案例:有一次,我们搭建了一个Docker应用,需要动态开放端口。如果用iptables,我需要先查Docker创建的链,再小心翼翼地插入规则。而firewalld的--add-port命令则优雅得多。

核心概念:firewalld引入了“区域”(zone)的概念。比如,public区域用于外网,internal区域用于内网。每个区域可以有不同的规则集。

常用命令对比:

  • 查看当前默认区域和规则:
    firewall-cmd --get-default-zone
    firewall-cmd --list-all
  • 开放端口(立即生效,并持久化):
    # 临时生效(重启或reload后失效)
    firewall-cmd --add-port=8080/tcp
    # 永久生效(需reload)
    firewall-cmd --permanent --add-port=8080/tcp
    firewall-cmd --reload
  • 控制SSH来源(使用富规则):
    firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="10.0.0.0/8" service name="ssh" accept'
    firewall-cmd --reload

踩坑点:最大的坑是规则冲突。firewalld底层仍然是iptables,但它会维护自己的规则集。如果你同时使用firewall-cmd和iptables命令,很容易导致规则混乱。比如,你用iptables -I INPUT ...插入了一条规则,firewalld下次reload时可能会覆盖它。最佳实践是:要么全用firewalld,要么全用iptables,不要混用。 另一个坑是服务定义。firewalld通过/usr/lib/firewalld/services/下的XML文件定义服务。如果你需要自定义端口组合(如某些应用同时用TCP和UDP),最好创建一个自定义服务文件,而不是每次都写富规则。

化繁为简:ufw的“优雅”之道

在管理Ubuntu服务器时,我遇到了ufw(Uncomplicated Firewall)。正如其名,它旨在简化iptables的操作,特别适合个人开发环境或设置简单的服务器。

排坑场景:为一个内部API服务快速设置网络边界防护。需求很简单:只允许特定IP访问,其他全部拒绝。

ufw的“一行命令”哲学:

# 启用网络边界防护(默认拒绝入站,允许出站)
ufw enable
# 允许SSH(默认允许,但最好显式声明)
ufw allow ssh
# 允许来自特定IP的API访问
ufw allow from 192.168.1.100 to any port 3000 proto tcp
# 查看状态和规则
ufw status verbose

踩坑点:ufw最大的问题是抽象层次过高,导致排查问题困难。有一次,我发现某个端口明明用ufw allow放行了,但应用还是连不上。最后用iptables -L -n查看底层规则,才发现ufw在INPUT链之前插入了自己的ufw-user-input链,而该链的默认策略是DROP。原因是ufw enable后,我手动执行了iptables -F清空了规则,导致ufw的链被破坏。教训:使用ufw后,就不要再手动操作iptables了。 另一个坑是日志管理。ufw默认不记录被拒绝的流量。如果需要调试,必须手动开启日志:ufw logging on,然后查看/var/log/ufw.log。

我的选择与建议

经过多年实践,我的选择策略如下:

  • iptables:适合需要极致性能和高度定制化的场景,比如核心路由器、负载均衡器、或需要编写复杂匹配规则(如connlimit、hashlimit)的环境。但必须配合脚本或设置管理工具(如Ansible)来管理,否则人工维护成本极高。
  • firewalld:是企业级服务器的首选。它的区域概念、动态更新、与NetworkManager的集成(如自动切换区域),以及通过firewall-cmd进行标准化管理,非常适合多网卡、多区域的复杂网络环境。强烈推荐在CentOS/RHEL 7+、Fedora上使用。
  • ufw:是个人开发者、小型项目或快速原型验证的利器。它上手快,设置简单,能让你专注于应用本身。但在生产环境中,尤其是需要精细控制或频繁变更时,其抽象层可能会成为排查问题的障碍。

最终建议:无论你选择哪个工具,理解其背后的iptables原理是成为合格运维工程师的必修课。当firewalld或ufw出现“灵异事件”时,最终还是要回到iptables -L -n -v和iptables-save来诊断。记住,工具是手段,理解网络包过滤的本质才是目的。

👨‍💻 运维兵经验:根据实际生产环境,以上步骤建议先在测试环境验证,并做好备份。参数值需根据服务器设置调整,不要盲目照搬。

如果喜欢,点个「在看」分享给朋友吧。

最新文章

随机文章