VPS 防火墙端口管理入门:ufw 与 firewalld 的最小安全规则集

VPS(虚拟专用服务器)刚交付的那几小时,最容易埋下隐患:多数系统镜像的防火墙要么完全关闭,要么沿用云厂商偏宽松的默认策略,等到扫描器开始敲 22、3306、6379 端口时才想起来补规则。端口该开哪几个、规则按什么顺序写、改完如何确认外部真的连不上,这三件事决定了后面几个月运维是否省心。这篇入门指南给出一套可以直接照抄的最小规则集:默认拒绝入站、只放行 SSH 与网站端口,用 ufw 或 firewalld 任选一种落地,最后再从外部探测验证效果。

VPS 防火墙最小规则集封面图

先定策略,再挑工具

防火墙的价值不在”开了”,而在”只开该开的”。默认拒绝入站、按白名单放行,这套思路在 ufw 和 firewalld 上是同一回事,区别只在表达方式:ufw 面向命令行的简单规则列表,一条一条追加;firewalld 用 zone(区域)和 service(服务定义)做分层,把规则挂到网卡所属的区域上。

两者底层都调用内核的包过滤机制,所以真正需要守住的只有一条铁律:同一台机器上只启用其中一个。ufw 与 firewalld 同时运行时会互相覆盖对方的规则链,典型症状是 ufw status 显示端口已拒绝,从外部却依然能连上——因为 firewalld 的规则先一步放行了流量。判断当前环境用哪个,看包管理来源就够了:Debian/Ubuntu 系默认 ufw,RHEL、Rocky、AlmaLinux、CentOS Stream 系默认 firewalld。

在动手前先盘点这台机器对外提供的服务。用 ss -lntp 列出所有监听中的 TCP 端口,把”必须给公网”和”只给内网或本机”分开记录,后面写规则时严格按这份清单来,不要凭印象。服务器上常见的对外入口通常只有三个:SSH、HTTP、HTTPS。更多端口暴露面的整理思路可参考站内服务器分类文章。

最小安全规则集包含哪几条

把上面的清单压缩成通用规则,一共五条,覆盖绝大多数建站场景:

  • 入站默认拒绝:ufw default deny incoming,firewalld 则把网卡放进 public 区域并只添加显式 service。
  • 管理通道限定来源:SSH 不一定要对全网开放,ufw allow from 203.0.113.10 to any port 22 proto tcp 只放行固定管理 IP。
  • 业务端口按需放行:站点用 ufw allow 80,443/tcp;临时调试的 8080、9000 验证完当天就删掉。
  • 出站先宽松后收敛:默认 allow outgoing,等业务稳定再按域名或 IP 段收紧,避免一开始就把包管理器和更新源挡住。
  • 保留 ICMP 与 loopback:全面丢弃 echo-request 会破坏路径 MTU 发现,表现为 SSH 能登录但大文件传输卡死。

默认拒绝策略下只放行白名单端口的示意

站点上线后如果还想进一步压缩首字节时间,可以顺着网站性能优化文章的排查顺序做,但前提是端口策略已经稳定,否则性能调优的数据没有可比性。

在 Ubuntu 与 Debian 上用 ufw 落地

ufw 的优点是语法短,几条命令就能从零到可用。下面这段可以直接复制执行,顺序不要调整——先把入站默认策略设成拒绝,再放行 SSH,最后才启用服务;如果反过来先 enable 再放行,当前会话会在下一步断开。

sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw limit 22/tcp
sudo ufw allow 80,443/tcp
sudo ufw --dry-run enable
sudo ufw enable
sudo ufw status numbered

--dry-run 只打印将要写入的规则而不真正生效,适合在改生产机前预览一遍;status numbered 会给出每条规则的序号,删规则时用 sudo ufw delete 3 比对着内容猜更方便。limit 的作用是给同一个来源 IP 的连接频率设上限,默认 30 秒内允许 6 次新连接,超过的包被丢弃,对 SSH 爆破有直接的减速效果,但它不是认证手段,密钥登录和禁用 root 密码登录仍然要做。

站点跑 WordPress 时,真正需要长期对外开放的只有 80 与 443;数据库 3306、缓存 6379 这类端口应当只监听 127.0.0.1,靠 bind-address 或 bind 127.0.0.1 在服务层就挡住,而不是指望防火墙规则一直写对。站内还有一篇WordPress 分类文章整理了常见站点服务的端口与权限配置,可以对照检查。改完规则后别急着关终端,先在另一个窗口验证 SSH 仍然可用,再继续下一步。

在 RHEL 系上用 firewalld 表达同一套规则

firewalld 把规则写进区域文件,--permanent 表示落到磁盘、--reload 才让运行时生效。很多人以为加了 --permanent 就即时生效,其实没有 --reload 之前 --list-all 看到的仍是旧状态,这是排查”规则加了却没挡住”的常见原因。

sudo systemctl enable --now firewalld
sudo firewall-cmd --get-default-zone
sudo firewall-cmd --permanent --add-service=ssh
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --permanent --add-port=8080/tcp
sudo firewall-cmd --reload
sudo firewall-cmd --list-all

如果 SSH 只想对固定管理 IP 开放,用 rich rule 更精确:

sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="203.0.113.10" port port="22" protocol="tcp" accept'
sudo firewall-cmd --reload

默认区域一般是 public,它本身已经是”默认拒绝入站、放行已声明服务”的语义,所以不需要额外写拒绝规则。反过来,如果某张网卡被错误地放进了 trusted 区域,那台机器上所有端口都会对全网开放——firewall-cmd --get-active-zones 能直接看出每张网卡归属哪个区域,这是接手一台陌生机器时先跑的命令。临时改动想保留,用 --runtime-to-permanent 把运行时配置整体写回磁盘;只想撤销某条规则,把 --add-* 换成 --remove-* 再 reload。

ufw 与 firewalld 规则表达方式对比示意

改完从外部验证,不要只看命令回显

防火墙命令执行成功,只说明规则写进了内核,不说明端口真的对外关闭。先在本机确认服务监听情况,再从另一台机器做外部探测,两步都要做:ss -lntp 看到的是服务在不在听,nmap 或 nc 看到的是流量能不能进来,这两件事互相独立,只做一半就很容易误判。

# 本机:确认监听地址与进程
ss -lntp

# 外部机器:只探测关心的端口
nmap -Pn -p 22,80,443,8080 203.0.113.25
nc -vz 203.0.113.25 22

结果要分三种读法。open 表示服务在听且规则放行,符合预期;closed 表示包到达了主机但被拒绝并回了 RST,通常是服务没启动或规则用了 reject;filtered 表示没有任何回包,说明包被静默丢弃,这正是 ufw default deny 的默认效果,也是对外最省事的姿态。把 22 之外的端口从 open 变成 filtered,就等于把这台机器的扫描面压到只剩一个入口。

需要提醒的一点:把端口关掉不等于把服务停掉。数据库仍然在 3306 上监听,只是外面连不进来;一旦哪天防火墙规则被误删或容器重建绕过规则,暴露就是瞬间的事。所以能改监听地址的服务就改监听地址,防火墙只是其中一层,不是唯一一层。

从外部探测端口状态的验证流程示意

四个容易翻车的边界

  • 顺序反了会把自己锁在门外:先 ufw enable 再放行 22,当前 SSH 会话在规则生效瞬间断开,只能去控制台或 VNC 救援,这类事故在新建机器上出现频率最高。
  • Docker 发布的端口会绕过系统防火墙:docker run -p 8080:80 在 nat 表写 DNAT 并在 FORWARD 链放行,ufw 的入站规则根本看不到这些流量,端口就成了一条隐藏通道。要么改成 -p 127.0.0.1:8080:80 由反向代理转发,要么用专门的 docker 链管理方案接管。
  • 云安全组与系统防火墙是两层独立开关:安全组放行、系统防火墙拒绝时表现为 filtered;两边都放行才是真正开放。只改一边,排查时很容易误判成规则没生效。
  • 同时启用 ufw 与 firewalld 会让两套规则互相打架:命令说端口已经关了,外部却连得上。装系统后先确认只留一个,再开始写规则。

从零到可用的落地顺序

这套流程套到新机器上大约二十分钟:先用 ss -lntp 盘点监听端口,写下必须对公网开放的清单;接着按镜像来源选 ufw 或 firewalld,写入默认拒绝与放行规则;然后在另一个窗口验证 SSH、再验证 80/443;最后从外部机器跑一次 nmap,确认清单外的端口全部是 filtered 状态。这套动作做完,机器就有了一个可以长期维持的最小暴露面。

后续维护的重点是”规则要跟着服务走”。关掉一个临时服务时顺手删掉对应规则,用 ufw status numbered 或 firewall-cmd --list-all 每月对一次账,比事后翻日志省力。

给新手的配置建议

如果你需要一套省心的起点,我们的建议是:默认拒绝入站、只放行 22(限定管理 IP)、80、443,其余端口一律不开口,然后每个月复查一次规则与监听状态。这条路径能挡住扫描器与多数自动化爆破,也给后续加规则留了位置。

如果你还没决定服务器形态,可以先看 Hostease VPS 方案了解端口与资源配额的实际情况;站点还在单站点阶段、又不想自己维护补丁与防火墙时,虚拟主机方案把这一层托管给了服务商,把精力留给业务本身更划算。

发表评论