新VPS到手,第一件事不是装面板、不是搭网站,而是配防火墙。一台暴露在公网的VPS,默认所有端口开放,自动化扫描器会在你上线几分钟内发现它,然后开始探测SSH、测试默认密码、寻找暴露的服务。
Linux防火墙工具家族庞大:iptables、ufw、firewalld、nftables……新手最常问的问题是:我该学哪个?
答案是:看系统、看场景、看需求。本文不让你背命令,而是给出一套"拿到VPS直接复制粘贴"的完整配置方案。
一、四个工具的关系:别被名字绕晕
层级关系
------------------------------------------------------------------------------------------
用户层 ufw (Ubuntu) firewalld (CentOS)
↓ ↓
中间层 iptables-restore iptables-restore / nftables
↓ ↓
内核层 iptables (legacy) nftables (新一代)
↓ ↓
Netfilter Netfilter框架 Netfilter框架
工具定位速查
工具 适用系统 学习曲线 核心特点
------------------------------------------------------------------------------------------
ufw Ubuntu/Debian 极低 命令最简单,三行搞定基础防护
firewalld CentOS/RHEL/Rocky 中等 区域概念强大,动态更新不中断连接
iptables 所有Linux 高 最底层最精细,但语法复杂已逐步淘汰
nftables Debian 12+/新系统 中等 iptables继任者,语法清晰,Docker兼容
2026年的建议:
- Ubuntu/Debian用户 → ufw 快速上手,有Docker需求再切 nftables
- CentOS/RHEL用户 → firewalld 是默认选择,功能足够
- 追求极致控制 → 直接学 nftables,iptables已处于维护模式不再更新
二、ufw实战:Ubuntu/Debian三行搞定基础防护
ufw(Uncomplicated Firewall)是Ubuntu默认预装的防火墙前端。它的设计哲学就一个字:简单。
第一步:先放行SSH,再启用防火墙(关键!)
# 查看当前状态
ufw status verbose
# 先放行SSH,否则启用后你自己被锁在外面
ufw allow 22/tcp comment 'SSH'
# 如果SSH端口改成了其他(比如2222),用实际端口
# ufw allow 2222/tcp comment 'SSH'
# 启用防火墙
ufw enable
# 确认规则
ufw status verbose
致命陷阱:很多新手直接 ufw enable,没先放行SSH,结果把自己锁在VPS外面。如果已经中招,通过服务商的VNC/串行控制台登录,执行 ufw disable 恢复。
第二步:配置Web服务器规则
# 放行HTTP和HTTPS
ufw allow 80/tcp comment 'HTTP'
ufw allow 443/tcp comment 'HTTPS'
# 或者直接用服务名(ufw内置了常见服务映射)
ufw allow 'Nginx Full'
# 放行其他常用端口
ufw allow 3306/tcp comment 'MySQL(建议仅允许特定IP)'
ufw allow 6379/tcp comment 'Redis(建议仅允许特定IP)'
ufw allow 8080/tcp comment '宝塔面板'
ufw allow 8888/tcp comment '其他管理后台'
第三步:限制SSH暴力破解
# 对SSH进行速率限制:30秒内超过6次连接尝试自动封禁
ufw limit 22/tcp comment 'SSH防爆破'
# 如果改了SSH端口
# ufw limit 2222/tcp comment 'SSH防爆破'
第四步:按IP精细化控制
# 仅允许特定IP访问SSH(最高安全级别)
ufw allow from 192.168.1.100 to any port 22 proto tcp comment '办公室IP'
# 仅允许IP段访问数据库
ufw allow from 10.0.0.0/8 to any port 3306 proto tcp comment '内网MySQL'
# 拒绝特定IP的所有访问
ufw deny from 192.168.1.200 comment '黑名单IP'
# 删除某条规则
ufw delete allow 8080/tcp
# 或者按编号删
ufw status numbered
ufw delete 3
ufw完整配置示例(一台典型建站VPS)
# 重置为干净状态
ufw reset
# 默认策略:拒绝入站,允许出站
ufw default deny incoming
ufw default allow outgoing
# 放行SSH并限速
ufw limit 22/tcp comment 'SSH防爆破'
# 放行Web
ufw allow 80/tcp comment 'HTTP'
ufw allow 443/tcp comment 'HTTPS'
# 放行宝塔(如果用)
# ufw allow 8888/tcp comment '宝塔面板'
# 启用
ufw enable
# 查看最终规则
ufw status verbose
预期输出:
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), disabled (routed)
To Action From
-- ------ ----
22/tcp LIMIT Anywhere # SSH防爆破
80/tcp ALLOW Anywhere # HTTP
443/tcp ALLOW Anywhere # HTTPS
22/tcp (v6) LIMIT Anywhere (v6) # SSH防爆破
80/tcp (v6) ALLOW Anywhere (v6) # HTTP
443/tcp (v6) ALLOW Anywhere (v6) # HTTPS
ufw的致命缺陷:Docker兼容性
这是ufw最大的坑。Docker直接操作iptables底层规则,完全绕过ufw。即使你执行了 ufw deny 3306,Docker容器的 -p 3306:3306 映射依然会暴露在公网。
ufw显示:3306被拒绝
Docker实际:3306完全开放
解决方案:
方案A:不用ufw,改用nftables(推荐)
方案B:修改Docker默认行为(复杂且易出错)
方案C:使用 --iptables=false 启动Docker(影响容器网络)
如果你运行Docker,建议直接跳到下面的nftables章节。
三、firewalld实战:CentOS/RHEL的区域化防护
firewalld是Red Hat系(CentOS 7+/RHEL 7+/Rocky/AlmaLinux)的默认防火墙。它的核心概念是区域(Zone),根据网络接口的信任程度应用不同策略。
基础命令
# 查看状态
firewall-cmd --state
# 查看当前活跃区域
firewall-cmd --get-active-zones
# 查看public区域的规则
firewall-cmd --zone=public --list-all
# 放行服务
firewall-cmd --permanent --add-service=ssh
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
# 放行端口
firewall-cmd --permanent --add-port=8080/tcp
# 重载生效
firewall-cmd --reload
区域概念详解
区域 信任度 默认行为 适用场景
------------------------------------------------------------------------------------------
drop 极低 拒绝所有入站,无响应 互联网公网接口
block 低 拒绝所有入站,有明确拒绝 不受信任的网络
public 中低 允许选定的入站连接 VPS默认区域
external 中 允许NAT和选定的服务 对外路由器
dmz 中 允许有限的服务 隔离区服务器
work 中高 允许更多服务 办公网络
home 高 信任大多数服务 家庭网络
trusted 最高 允许所有连接 内部管理网络
典型VPS配置(public区域)
# 设置默认区域为public(通常已是默认)
firewall-cmd --set-default-zone=public
# 放行SSH
firewall-cmd --permanent --add-service=ssh
# 放行Web
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
# 放行自定义端口
firewall-cmd --permanent --add-port=8080/tcp
# 限制SSH来源IP(可选)
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" service name="ssh" accept'
# 富规则:速率限制SSH
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" service name="ssh" accept limit value="6/m"'
# 重载
firewall-cmd --reload
# 验证
firewall-cmd --list-all
四、nftables实战:新一代防火墙,Docker兼容
nftables是iptables的继任者,Debian 12+已将其作为默认防火墙框架。它的优势:语法统一(IPv4/IPv6一套规则)、性能更好、与Docker兼容。
完整配置方案(Debian 12/Ubuntu 24.04)
# 如果之前启用了ufw,先禁用
ufw disable
systemctl disable --now ufw
# 确保nftables已安装
apt update && apt install -y nftables
# 备份默认配置
cp /etc/nftables.conf /etc/nftables.conf.bak
# 写入配置
cat > /etc/nftables.conf << 'NFTEOF'
#!/usr/sbin/nft -f
flush ruleset
table inet firewall {
# SSH速率限制动态集合
set ssh_ratelimit {
type ipv4_addr
flags dynamic
timeout 60s
}
set ssh_ratelimit6 {
type ipv6_addr
flags dynamic
timeout 60s
}
chain inbound_ipv4 {
# 允许有限制的ping
icmp type echo-request limit rate 5/second accept
}
chain inbound_ipv6 {
# IPv6邻居发现必需
icmpv6 type { nd-neighbor-solicit, nd-router-advert, nd-neighbor-advert } accept
icmpv6 type echo-request limit rate 5/second accept
}
chain inbound {
type filter hook input priority filter; policy drop;
# 允许已建立的连接返回
ct state established,related accept
ct state invalid drop
# 允许本地回环
iifname "lo" accept
# IPv4/IPv6分流
meta protocol vmap { ip : jump inbound_ipv4, ip6 : jump inbound_ipv6 }
# SSH:允许但速率限制(每IP每分钟3次新连接,突发5个)
tcp dport 22 ct state new add @ssh_ratelimit { ip saddr limit rate 3/minute burst 5 packets } accept
tcp dport 22 ct state new add @ssh_ratelimit6 { ip6 saddr limit rate 3/minute burst 5 packets } accept
# HTTP/HTTPS
tcp dport { 80, 443 } accept
# 宝塔面板(如需要)
# tcp dport 8888 accept
# 记录并丢弃其他所有入站
log prefix "[nftables] Dropped: " limit rate 10/minute counter drop
}
chain forward {
type filter hook forward priority filter; policy drop;
}
chain outbound {
type filter hook output priority filter; policy accept;
}
}
NFTEOF
# 检查语法
nft -c -f /etc/nftables.conf
# 应用配置
nft -f /etc/nftables.conf
# 设置开机启动
systemctl enable --now nftables
# 验证
nft list ruleset
为Docker添加兼容规则
nftables与Docker的DOCKER-USER链配合工作,不会被绕过:
# 编辑配置,在inbound链中添加Docker相关规则
cat >> /etc/nftables.conf << 'EOF'
table inet docker {
chain docker_user {
type filter hook forward priority filter; policy accept;
}
}
EOF
nft -f /etc/nftables.conf
nftables常用运行时命令
# 查看完整规则集
nft list ruleset
# 查看速率限制当前状态(哪些IP被跟踪)
nft list set inet firewall ssh_ratelimit
# 临时添加规则(重启失效)
nft add rule inet firewall inbound tcp dport 8080 accept
# 查看带handle编号的规则(用于删除)
nft -a list chain inet firewall inbound
# 通过handle删除规则
nft delete rule inet firewall inbound handle 15
# 保存运行时更改到配置文件
nft list ruleset > /etc/nftables.conf
sed -i '1i #!/usr/sbin/nft -f' /etc/nftables.conf
五、iptables: legacy时代的遗产,还能用但不必学
iptables是Linux防火墙的"老祖宗",直接操作Netfilter框架。但2026年的现状是:
现状
------------------------------------------------------------------------------------------
- 内核5.x后,iptables底层逐步被nftables取代
- Debian 12/Ubuntu 24.04默认使用nftables作为iptables后端
- 新系统上执行iptables命令,实际是在操作nftables的兼容层
- 规则复杂、语法晦涩、IPv4/IPv6要分别写两套规则
除非你在维护老系统(CentOS 6/Debian 10),否则不建议新学iptables。ufw、firewalld、nftables已经足够覆盖所有场景。
如果你遇到必须使用iptables的情况,记住最基础的三条:
# 查看规则
iptables -L -n -v
# 放行端口
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# 保存规则(Debian/Ubuntu)
iptables-save > /etc/iptables/rules.v4
六、常见服务端口速查表
服务 端口 协议 ufw命令 nftables规则
------------------------------------------------------------------------------------------
SSH 22 TCP ufw allow 22/tcp tcp dport 22 accept
HTTP 80 TCP ufw allow 80/tcp tcp dport 80 accept
HTTPS 443 TCP ufw allow 443/tcp tcp dport 443 accept
DNS 53 TCP/UDP ufw allow 53 tcp dport 53 accept; udp dport 53 accept
MySQL 3306 TCP ufw allow 3306/tcp tcp dport 3306 accept
PostgreSQL 5432 TCP ufw allow 5432/tcp tcp dport 5432 accept
Redis 6379 TCP ufw allow 6379/tcp tcp dport 6379 accept
MongoDB 27017 TCP ufw allow 27017/tcp tcp dport 27017 accept
SMTP 25 TCP ufw allow 25/tcp tcp dport 25 accept
SMTPS 465 TCP ufw allow 465/tcp tcp dport 465 accept
IMAPS 993 TCP ufw allow 993/tcp tcp dport 993 accept
WireGuard 51820 UDP ufw allow 51820/udp udp dport 51820 accept
OpenVPN 1194 UDP ufw allow 1194/udp udp dport 1194 accept
宝塔面板 8888 TCP ufw allow 8888/tcp tcp dport 8888 accept
安全提醒:数据库端口(3306/5432/6379/27017)永远不要直接暴露到公网。如需远程管理,使用SSH隧道或限制为特定IP。
七、防火墙配置避坑指南
坑1:把自己锁在VPS外面
症状:启用防火墙后SSH断开,无法重新连接
原因:没先放行SSH端口就启用了防火墙
解决:通过服务商VNC/串行控制台登录,执行 ufw disable 或 nft flush ruleset
预防:永远先放行SSH,再启用防火墙;修改SSH端口时先添加新端口规则再改配置
坑2:ufw和nftables/iptables同时运行
症状:规则互相冲突,部分端口莫名其妙开放或关闭
原因:ufw、nftables、iptables三套规则同时生效,内核按优先级叠加
解决:只保留一套,彻底禁用其他
systemctl stop ufw && systemctl disable ufw
systemctl stop iptables && systemctl disable iptables
systemctl enable --now nftables
坑3:Docker绕过ufw
症状:ufw显示某端口被拒绝,但外部仍能访问
原因:Docker直接操作iptables,绕过ufw规则
解决:改用nftables;或修改Docker daemon配置(不推荐)
验证:nmap扫描VPS公网IP,对比ufw status和实际开放端口
坑4:规则不持久化
症状:重启后防火墙规则丢失,所有端口又开放了
原因:运行时添加的规则没保存到配置文件
解决:
ufw:ufw enable 时自动持久化
firewalld:--permanent 参数 + firewall-cmd --reload
nftables:nft list ruleset > /etc/nftables.conf
iptables:iptables-save > /etc/iptables/rules.v4
坑5:IPv6被遗忘
症状:IPv4防护严密,IPv6全端口暴露
原因:只配置了IPv4规则,IPv6默认放行
解决:
ufw:默认自动处理双栈,确认/etc/default/ufw中IPV6=yes
nftables:使用inet族(上面配置示例已包含)
firewalld:默认同时处理IPv4和IPv6
iptables:需同时配置ip6tables
坑6:日志占满磁盘
症状:/var/log目录暴涨,磁盘空间告警
原因:启用了防火墙日志且服务器遭受大量扫描
解决:
ufw:ufw logging low
nftables:为log规则添加 limit rate 10/minute
定期清理:find /var/log -name "*log*" -mtime +7 -delete
八、快速决策:你的VPS该用哪个?
场景 推荐工具 理由
------------------------------------------------------------------------------------------
Ubuntu/Debian纯建站,不跑Docker ufw 三行命令搞定,最简单
Ubuntu/Debian跑Docker nftables Docker兼容,不被绕过
CentOS/RHEL/Rocky/AlmaLinux firewalld 系统默认,区域概念强大
需要精细控制(按IP段、按接口) nftables 语法清晰,功能最全
老系统维护(CentOS 6/Debian 10) iptables 兼容旧环境
追求极致性能(高并发防火墙) nftables 内核原生,性能最优
九、一键配置脚本(复制即用)
Ubuntu/Debian + ufw(无Docker)
#!/bin/bash
# ufw基础配置脚本
ufw reset
ufw default deny incoming
ufw default allow outgoing
ufw limit 22/tcp comment 'SSH防爆破'
ufw allow 80/tcp comment 'HTTP'
ufw allow 443/tcp comment 'HTTPS'
ufw enable
ufw status verbose
Debian 12/Ubuntu 24.04 + nftables(推荐,兼容Docker)
#!/bin/bash
# nftables完整配置脚本
# 禁用ufw
ufw disable 2>/dev/null
systemctl disable --now ufw 2>/dev/null
# 安装nftables
apt update && apt install -y nftables
# 写入配置
cat > /etc/nftables.conf << 'EOF'
#!/usr/sbin/nft -f
flush ruleset
table inet firewall {
set ssh_ratelimit { type ipv4_addr; flags dynamic; timeout 60s; }
set ssh_ratelimit6 { type ipv6_addr; flags dynamic; timeout 60s; }
chain inbound_ipv4 { icmp type echo-request limit rate 5/second accept; }
chain inbound_ipv6 {
icmpv6 type { nd-neighbor-solicit, nd-router-advert, nd-neighbor-advert } accept
icmpv6 type echo-request limit rate 5/second accept
}
chain inbound {
type filter hook input priority filter; policy drop;
ct state established,related accept
ct state invalid drop
iifname "lo" accept
meta protocol vmap { ip : jump inbound_ipv4, ip6 : jump inbound_ipv6 }
tcp dport 22 ct state new add @ssh_ratelimit { ip saddr limit rate 3/minute burst 5 packets } accept
tcp dport 22 ct state new add @ssh_ratelimit6 { ip6 saddr limit rate 3/minute burst 5 packets } accept
tcp dport { 80, 443 } accept
log prefix "[nftables] Dropped: " limit rate 10/minute counter drop
}
chain forward { type filter hook forward priority filter; policy drop; }
chain outbound { type filter hook output priority filter; policy accept; }
}
EOF
# 应用并启用
nft -f /etc/nftables.conf
systemctl enable --now nftables
nft list ruleset
echo "nftables配置完成!"
总结
防火墙是VPS安全的第一道防线,但配置错了比没配置更危险——把自己锁在外面、Docker绕过规则、IPv6暴露,都是新手常踩的坑。
- 最快上手:ufw,三行命令基础防护
- 最稳选择:nftables,兼容Docker、语法清晰、性能最好
- CentOS系:firewalld,区域化管理企业级场景
- 别碰:iptables,legacy工具,新系统不必学
记住核心原则:默认拒绝所有入站,按需允许少数端口。宁可漏配一个功能,也不要多开一个攻击面。


