Linux 防火墙三国杀:ufw / firewalld / iptables / nftables 怎么选
很多人在 Linux 上配防火墙时是懵的:装了 ufw,又听说要用 iptables,新系统又说要换 nftables,红帽系上还有个 firewalld,到底是什么关系?
这篇先把它们的层级关系画清楚,然后再讲怎么选。
一、四层结构:从内核到用户#
| 层级 | 角色 | 是什么 |
|---|---|---|
| 内核 | Netfilter | Linux 内核自带的包过滤框架,所有发行版都有 |
| 管理 | iptables / nftables 命令 | 用户态命令行工具,把你的规则翻译成内核能懂的语言 |
| 前端 | ufw / firewalld | 更友好的封装,帮你写 iptables/nftables 规则 |
核心结论:
- Netfilter 是内核功能,不可选,永远在。
- iptables vs nftables:iptables 是老工具,nftables 是 2014 年出现的替代品(语法更统一、性能更好)。新发行版默认都是 nftables(Ubuntu 20.04+、Debian 10+、CentOS 8+)。
- ufw vs firewalld:两者都是”前端”,只是不同发行版预装的不同:
| 发行版 | 默认预装 |
|---|---|
| Ubuntu / Debian 系 | ufw |
| CentOS / RHEL / Fedora 系 | firewalld |
| Arch | 都不装,用户自己选 |
💡 注意:ufw 和 firewalld 不绑定发行版,Ubuntu 上也能装 firewalld,Fedora 上也能装 ufw。
二、“假 iptables”:兼容层是怎么回事#
新发行版上敲 iptables,它其实是 iptables-nft——把 iptables 语法翻译成 nftables 规则执行,底层根本不是真的 iptables。
1iptables --version2# iptables v1.8.7 (nf_tables) ← 兼容层(背后是 nftables)3# iptables v1.8.7 (legacy) ← 真正的 iptables🪤 这就是为什么有时候用老教程的
iptables命令在新系统上行为不一致——你以为是 iptables,其实是 nftables 翻译过来的。
三、“为什么 ufw 显示没规则,但还是有规则在拦截?”#
这是新手最高频的疑问,答案是:
✅ ufw 只管 ufw 自己写入的规则。Docker、fail2ban 等程序会直接往 iptables/nftables 里写规则,ufw 看不到。
1# ufw 看到的(只是 ufw 自己的)2sudo ufw status3
4# iptables 看到的(所有规则,包括 docker、fail2ban 写的)5sudo iptables -L -n -v6sudo iptables -t nat -L -n -v7
8# nftables 看到的(新发行版)9sudo nft list ruleset实战中最常踩的两个例子:
| 现象 | 原因 |
|---|---|
ufw deny 80 了,docker 容器还能从公网访问 | Docker 自己在 nat 表里写了 DNAT 规则,绕开了 ufw 的 INPUT 链 |
| fail2ban 封了 IP,但 ufw status 看不到 | fail2ban 走的是自己创建的链 |
四、规则的持久化#
| 工具 | 持久化方式 |
|---|---|
| ufw | 自带(重启自动恢复) |
| firewalld | 自带(runtime + permanent 双套规则) |
| 裸 iptables | 默认重启清空,需装 iptables-persistent |
| 裸 nftables | 默认重启清空,需写入 /etc/nftables.conf |
iptables-persistent 的配置文件:
1/etc/iptables/rules.v4 # IPv4 规则2/etc/iptables/rules.v6 # IPv6 规则apt purge iptables-persistent会删除上面的配置文件。apt remove iptables-persistent会保留配置文件,下次重装能复用。
五、ufw 速查(最推荐新手用)#
ufw(Uncomplicated Firewall)是 Debian/Ubuntu 上最简单的防火墙前端,但它在所有 Linux 上都能装。
5.1 基础操作#
1# 启用 / 关闭2sudo ufw enable3sudo ufw disable4
5# 看状态6sudo ufw status7sudo ufw status numbered # 带规则编号(删除时用)8
9# 重新加载10sudo ufw reload11
12# 重置(清空所有规则)13sudo ufw --force reset5.2 默认策略#
1# 默认拒绝所有入站(强烈推荐)2sudo ufw default deny incoming3
4# 默认允许所有出站5sudo ufw default allow outgoing5.3 添加规则#
1# 按端口2sudo ufw allow 223sudo ufw allow 80/tcp4sudo ufw allow 4435
6# 按服务名(看 /etc/services)7sudo ufw allow ssh8
9# 按 IP 限制10sudo ufw allow from 192.168.1.10011sudo ufw allow from 192.168.1.100 to any port 2212
13# 拒绝14sudo ufw deny 225.4 删除规则#
1# 按编号删(先用 numbered 查编号)2sudo ufw status numbered3sudo ufw delete 34
5# 按内容删6sudo ufw delete allow 807sudo ufw delete deny 225.5 典型 VPS 配置#
1sudo ufw default deny incoming2sudo ufw default allow outgoing3sudo ufw allow 22000/tcp # 改了的 SSH 端口4sudo ufw allow 80/tcp5sudo ufw allow 443/tcp6sudo ufw allow from <办公室 IP> to any port 9090 # 面板限制 IP7sudo ufw enable六、firewalld 速查#
红帽系上常见,特点是”区域(zone)“概念:
1# 状态2sudo firewall-cmd --state3sudo systemctl status firewalld4
5# 看当前 zone6sudo firewall-cmd --get-default-zone7sudo firewall-cmd --get-active-zones8
9# 看 zone 里的规则10sudo firewall-cmd --list-all11
12# 加端口(runtime + 永久)13sudo firewall-cmd --add-port=8080/tcp14sudo firewall-cmd --add-port=8080/tcp --permanent15
16# 加服务17sudo firewall-cmd --add-service=http --permanent18
19# 重新加载20sudo firewall-cmd --reload21
22# 删除规则23sudo firewall-cmd --remove-port=8080/tcp --permanent⚠️ firewalld 区分 runtime 和 permanent,不加
--permanent重启就丢,改完都要firewall-cmd --reload。
七、原生 nftables 速查#
新系统的”正经”方式:
1# 看所有规则2sudo nft list ruleset3
4# 看某个表5sudo nft list table inet filter6
7# 加一个 inet 类型的 filter 表8sudo nft add table inet filter9
10# 加 input 链(默认 drop)11sudo nft add chain inet filter input { type filter hook input priority 0\; policy drop\; }12
13# 允许已建立的连接14sudo nft add rule inet filter input ct state established,related accept15
16# 允许 SSH17sudo nft add rule inet filter input tcp dport 22 accept18
19# 保存到 /etc/nftables.conf(持久化)20sudo nft list ruleset > /etc/nftables.conf21sudo systemctl enable --now nftables/etc/nftables.conf 完整模板:
1#!/usr/sbin/nft -f2
3flush ruleset4
5table inet filter {6 chain input {7 type filter hook input priority 0; policy drop;8 ct state established,related accept9 iifname lo accept10 tcp dport 22 accept11 tcp dport { 80, 443 } accept12 }13 chain forward {14 type filter hook forward priority 0; policy drop;15 }16 chain output {17 type filter hook output priority 0; policy accept;18 }19}八、原生 iptables 速查#
老系统 / 兼容层都能用:
1# 看规则2sudo iptables -L -n -v --line-numbers3
4# 清空规则5sudo iptables -F6sudo ip6tables -F7
8# 设置默认策略9sudo iptables -P INPUT DROP10sudo iptables -P FORWARD DROP11sudo iptables -P OUTPUT ACCEPT12
13# 允许 loopback14sudo iptables -A INPUT -i lo -j ACCEPT15
16# 允许已建立连接17sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT18
19# 允许 SSH / HTTP / HTTPS20sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT21sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT22sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT23
24# 保存(需要 iptables-persistent)25sudo netfilter-persistent save九、如何选#
| 场景 | 推荐 |
|---|---|
| 新手 / 简单 VPS | ufw |
| 红帽系生产环境 | firewalld |
| 容器 / 复杂规则 / 写脚本 | 直接 nftables |
| 维护老系统 | iptables |
| 想要可视化 / 配合面板 | 装 ufw 让 1Panel/宝塔托管 |
💡 不要同时启用 ufw 和 firewalld。两者会互相冲突,规则乱掉之后排查是噩梦。
十、清掉所有”奇怪规则”的标准动作#
VPS 拿到手发现防火墙规则乱七八糟想从头开始时:
1# 1. 停掉 / 卸载所有防火墙前端2sudo systemctl stop ufw3sudo systemctl disable ufw4sudo apt purge -y iptables-persistent ufw5
6# 2. 清空内存中的规则7sudo iptables -F8sudo iptables -X9sudo iptables -t nat -F10sudo iptables -t nat -X11sudo ip6tables -F12sudo ip6tables -X13
14# 3. 重置默认策略为 ACCEPT(避免清空后断 SSH)15sudo iptables -P INPUT ACCEPT16sudo iptables -P FORWARD ACCEPT17sudo iptables -P OUTPUT ACCEPT18
19# 4. 重启确认20sudo reboot21
22# 5. 重启后再装回想用的工具23sudo apt install -y ufw⚠️ 清空策略前先把 INPUT 默认改成 ACCEPT,否则一清空就断 SSH,下场是去厂商面板用 VNC 救机器。
十一、几条实用经验#
- VPS 上配防火墙顺序:先 allow SSH 再 enable,反着来就是自己锁外面了。
- 改 SSH 端口务必同步加防火墙规则,否则改完 ssh -p 新端口连不上。
- Docker 容器端口对外可达是 Docker 自己写的 iptables 规则,不归 ufw 管——要限制 Docker 容器对外暴露,得改 docker-compose 的 ports 写法(绑 127.0.0.1)。
- fail2ban 的封禁也是直接写 iptables,看封禁状态用
fail2ban-client status sshd,不是 ufw status。 - 新系统直接学 nftables 就行,iptables 是历史包袱。
理解到这个层级,再去看任何”防火墙规则没生效”的问题,都能直接定位到底是哪一层在拦。