这篇实战指南教你如何用 firewalld 把服务器防火墙的区域与规则真正落地。对运行在 VPS(Virtual Private Server,虚拟专用服务器)或独立服务器上的业务来说,防火墙配置直接决定服务能否被外部正常访问,也决定恶意扫描能否直达应用。很多用户刚拿到机器,第一反应是担心端口没开导致 SSH(Secure Shell,安全远程登录协议)连不上,或者端口开得太宽给攻击者留了门。本文用 firewalld 这套主流工具,把区域与规则的落地步骤和验证指标一次讲清楚。
firewalld 和旧式 iptables 最大的差异,在于它引入了”区域(zone)”这一层抽象。简单理解,区域就是一套事先定义好的端口放行策略集合,你把某张网卡归属到某个区域,这个区域里允许的端口和协议就会自动应用到这张网卡上的所有流量。相比直接往 iptables 里追加一串链条规则,用区域组织策略更容易维护、也更难出错。下面从最常用的区域和命令入手,逐步展开。
一、区域到底是什么,默认区如何生效
firewalld 自带多个预定义区域,从最保守到最开放依次是 drop、block、public、external、dmz、work、home、internal 和 trusted。其中 public 是大多数服务器默认绑定的区域,只放行与外界交互必需的少量端口,其余一律拒绝;trusted 则几乎放行所有进站流量,适合内网专用网卡。记住一个原则:区域越开放,越应该只用在可信网络接口上。如果一台机器同时有公网网卡和内网网卡,就应该把它们分别划到 public 和 trusted 两个区域。
把一个网卡改绑到指定区域,用 --change-interface 指定网卡名和目标区域。下面把内网网卡 eth1 绑定到 trusted,来自内网的流量走宽松放行,来自公网 eth0 的流量仍受 public 约束。
firewall-cmd --zone=trusted --change-interface=eth1 firewall-cmd --reload
查看当前默认区域和网卡归属,用下面两条命令:
firewall-cmd --get-default-zone firewall-cmd --list-all
第一条返回默认区域名,第二条会列出默认区域已绑定的网卡、服务、端口等配置。把默认区域切到别的区域,指定目标区域后重载即可。
firewall-cmd --set-default-zone=work firewall-cmd --reload
这里要特别提醒:--list-all 是验证区域是否生效的第一道指标。很多用户改完区域后不复查,结果流量走的还是旧区域,服务自然连不上。改完任何区域配置,都要用 --list-all 复读一次。

二、放行端口与服务的正确写法
放行端口时,最常见的坑是忘记 --permanent。下面以放行 TCP 8080 为例:
firewall-cmd --zone=public --add-port=8080/tcp --permanent firewall-cmd --reload firewall-cmd --zone=public --list-ports
这里 --permanent 表示写入持久配置,reload 让持久配置生效到运行时。如果不带 --permanent,端口只在当前会话开放,机器重启后就会丢失,这正是很多”端口明明加了却连不上”现象的根源。
如果服务不只监听在 TCP,还需要按协议区分处理。比如 MySQL 默认走 TCP 3306,DNS(Domain Name System,域名解析系统)则同时涉及 TCP 和 UDP 的 53 端口。UDP 端口放行语法与 TCP 一致,把 /tcp 换成 /udp 即可。放行端口后,务必用 --list-ports 或 --list-services 复读一次。
三、富规则:单端口说不清需求时用它
当需要”只允许某个来源 IP 访问某端口”这类更细粒度的控制时,单纯 --add-port 就不够用了,需要用 --add-rich-rule。下面的富规则表示只允许 192.168.1.0/24 网段访问 3306 端口,其余来源一律拒绝。
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" port protocol="tcp" port="3306" accept' firewall-cmd --reload
富规则把来源、目标端口、动作三个要素写在一条 rule 里,比拆分多条 iptables 命令更容易读。实际运维里,最典型的就是数据库端口只在内网或办公网开放,避免暴露到公网被暴力破解扫描。
需要注意,富规则与普通端口规则是叠加关系,不是互斥。如果同一个端口既通过 --add-port 放行,又通过富规则限制来源,最终行为可能超出预期。查询当前已生效的富规则,用 --list-rich-rules。
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="203.0.113.25" reject' firewall-cmd --reload
这条规则会把来自 203.0.113.25 的所有进站连接直接拒绝。富规则里还能加 protocol 或 port 进一步收窄范围,例如只拒绝某个来源对 22 端口的访问,其他端口不受影响。排查规则冲突时,先看 --list-all 与 --list-rich-rules 的叠加结果。
四、持久化与回滚,避免把防火墙改死
所有规则的最终状态,都要经过”临时验证 + 永久写入 + 复读确认”三步。临时验证指不加 --permanent 先改运行时,用实际访问确认没问题,再补一条 --permanent 版本。这样可以避免把一条会踢掉自己 SSH 会话的规则直接写进持久配置。
如果不小心把规则改坏,firewalld 提供了回滚途径。用 firewall-cmd --reload 会把当前运行时重置为持久配置,等于放弃所有未持久化的临时改动。稳妥的做法是在改动前先 cp 备份整个 /etc/firewalld 目录。
对公网服务器的 SSH(安全远程登录协议)端口,强烈建议不要直接使用默认 22 端口暴露,可以先通过 --add-port 换成高位端口,再在确认能登录后关闭原端口。这类变更要多做一步回滚演练,确保任何一步出错都能退回可访问状态。
五、排障:端口放行后为什么还是不通
防火墙规则看起来都放行了,外部却仍然连不上,这类问题通常有几种来源。第一是持久化没做,端口只存在于运行时,服务一重启就丢;第二是放行到了错误的区域,比如把公网端口加到了内网区域的 trusted,而实际请求走的是 public;第三是协议没配对,放行了 tcp 却漏掉 udp。排查时先用 firewall-cmd --list-all 对照当前默认区域的完整状态,再结合 ss -lntp 确认服务本身确实在监听对应端口。
确认本机端口监听正常后,再从外部用工具测连通性,比如用 nc 探测目标端口。如果本机监听存在、防火墙也放行,但外部仍不通,多半还要检查云平台的安全组或独立服务器机房的入站规则。这里容易把问题误判成 firewalld 没生效,实际上是被更外层拦截。把防火墙、安全组、监听状态三者逐层核对,才能准确定位是哪一层挡掉了连接。
# 查看端口监听状态 ss -tnlp | grep 8080 # 本机查看 firewalld 区域放行 firewall-cmd --zone=public --list-ports
这套”先本机监听,再防火墙,再外层安全组”的排查顺序,能大幅缩短定位时间。

总结
firewalld 区域与规则管理的核心是三层配合:区域决定网卡默认放行策略,端口/服务规则决定具体的放行对象,富规则处理来源级细粒度控制。日常运维记住三件事:改动先用不加 --permanent 的方式临时验证,确认后再写持久配置;放行后一定用 --list-ports 复读;任何大改动前先备份 /etc/firewalld,给自己留一条回滚的退路。这些经验对运行在 VPS 或独立服务器上的各类业务都通用。
如果你希望用更省心的托管方案减少这类底层配置的负担,可以考虑 Hostease VPS 主机,把精力放在业务本身而不是反复排查防火墙。关于服务器选型与安全防护的更多实测,可以参考 服务器排名 与 美国虚拟主机安全与 DDoS 防御实战,以及 美国云主机 DDoS 防护能力评测。总结下来,建议你在生产环境动手前,先在测试机把区域、端口、富规则各跑一遍,确认验证指标后再上线,避免把自己锁在服务器外。

微信扫一扫打赏
支付宝扫一扫打赏