这篇实战指南会告诉你,如何用 firewalld 把一台新服务器的端口规则一次性配好,避免反复重启就丢规则的坑。对跑在 VPS(Virtual Private Server,虚拟专用服务器)或独服(整台独占的物理服务器)上的业务来说,防火墙配置直接影响服务能不能被外部正常访问,也决定恶意扫描能不能直达应用层。很多运维第一次上手,最担心的就是端口没开导致 SSH(Secure Shell,安全远程登录协议)连不上,或者反过来端口开得太宽给攻击者留了门。本文不空谈概念,直接从区域机制、放行写法、富规则和回滚这几条主线,讲清楚每一步该验证什么。
一、区域到底是什么,默认区如何生效
firewalld 与旧式 iptables 最大的差异,是引入了「区域(zone)」这一层抽象。简单理解,区域就是一套事先定义好的端口放行策略集合,你把某张网卡归属到某个区域,这个区域里允许的端口和协议就会自动应用到这张网卡上的所有流量。相比直接往 iptables 里追加一串链条规则,用区域组织策略更容易维护,也更难出错。
firewalld 自带多个预定义区域,从最保守到最开放依次是 drop、block、public、external、dmz、work、home、internal 和 trusted。其中 public 是大多数服务器默认绑定的区域,只放行与外界交互必需的少量端口,其余一律拒绝;trusted 则几乎放行所有进站流量,适合内网专用网卡。记住一个原则:区域越开放,越只应该用在可信网络接口上。如果一台机器同时有公网网卡和内网网卡,就应该把内网网卡划到 trusted、公网网卡留在 public,而不是共用一个宽松策略。
把一个网卡改绑到指定区域,用 change-interface 指定网卡名和目标区域:
firewall-cmd --zone=trusted --change-interface=eth1
firewall-cmd --reload
查看当前默认区域和网卡归属,用下面两条命令:
firewall-cmd --get-default-zone
firewall-cmd --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,端口只在当前会话开放,机器重启或 firewalld 重启后就会丢失,这正是很多「端口明明加了却连不上」现象的根源。除直接指定端口外,firewalld 也支持按服务名放行,例如 http、https、ssh,用 add-service 即可;服务名背后是一组预设端口映射,管理起来比记端口号更直观。

如果服务不只监听在 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 命令更容易读。实际运维里最典型的就是数据库端口只在内网或办公网开放,避免暴露到公网被暴力破解扫描。富规则同样支持 drop 动作,例如把某个异常来源整体拒之门外。
需要注意,富规则与普通端口规则是叠加关系,不是互斥。如果同一个端口既通过 add-port 放行、又通过富规则限制来源,最终行为可能超出预期,出现「明明写了拒绝却仍然能访问」的困惑。建议同类控制只用一种写法。查询当前已生效的富规则用 list-rich-rules,排查冲突时先看 list-all 与 list-rich-rules 的叠加结果,再决定从哪个方向调整。
四、持久化与回滚,避免把防火墙改死
所有规则的最终状态,都要经过「临时验证 + 永久写入 + 复读确认」三步。临时验证指不加 permanent 先改运行时,用实际访问确认没问题,再补一条 permanent 版本。这样可以避免把一条会踢掉自己 SSH 会话的规则直接写进持久配置,重启后连不上机器。
如果不小心把规则改坏,firewalld 提供了回滚途径。用 reload 会把当前运行时重置为持久配置,等于放弃所有未持久化的临时改动;若持久配置本身也错了,则需要先备份 /etc/firewalld/zones/ 目录下的 zone 配置文件,再用备份还原。稳妥的做法是在改动前先执行 cp 备份整个 /etc/firewalld 目录,改动后把验证命令写进操作记录。

对公网服务器的 SSH 端口,建议不要直接暴露默认 22,可以先用 add-port 换成高位端口,确认能登录后再关闭原端口。这类变更要多做一步回滚演练,确保任何一步出错都能退回可访问状态,而不是把自己锁在服务器外。选型阶段如果对机器本身性能与线路心里没底,可以先跑一遍这篇海外VPS与境内VPS性能对比里提到的验证手段,再决定在哪个节点上做端口收敛。
五、排障:端口放行后为什么还是不通
防火墙规则看起来都放行了,外部却仍然连不上,这类问题通常有几个来源。第一是持久化没做,端口只存在于运行时,服务一重启就丢;第二是放行到了错误的区域,比如把公网端口加到了内网区域的 trusted,而实际请求走的是 public;第三是协议没配对,放行了 tcp 却漏掉 udp。排查时先用 list-all 复读默认区,再用 list-ports 与 list-rich-rules 核对具体规则,最后用 tcpdump 或 nc 从外部发包看包是否被丢弃。
总结与验证指标清单
配置完一套 firewalld 规则,建议逐项核对下面这份验证指标清单:默认区域是否是你期望的那一个、每张网卡归属的区域是否正确、放行端口是否加了 permanent 且 reload 后仍在 list-ports 里、富规则的来源限制是否生效、以及改坏后能否通过 reload 或备份回滚。每一步都拿到真实命令输出,而不是凭印象判断。
建议把「临时验证 → 永久写入 → 复读确认 → 备份回滚」这四步固化进你的服务器初始化脚本里。如果你需要一套已经踩过这些坑、能直接上手的防火墙配置流程,也可以考虑在测试机上先跑一遍再上生产,避免在线上机器上反复试错。需要一台能自由测试 firewalld 区域切换又不会影响线上业务的机器时,Hostease 的中文客服与可自定义端口的方案可以作为备选参考。

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