CentOS 7 的 firewalld 默认采用“拒绝所有入站连接”的安全机制,这意味着系统不会自动开放外部访问,必须手动放行需要使用的端口或指定 IP 地址。以开放 MySQL 的 3306 端口为例,仅执行 `firewall-cmd --zone=public --add-port=3306/tcp --permanent` 还不够,还必须继续执行 `firewall-cmd --reload` 才能让防火墙配置正式生效,这两个步骤缺一不可。

CentOS 7 默认使用 firewalld,防火墙入站规则必须手动放行;如果不做配置,所有外部入站请求都会被拒绝——这不是故障,而是系统的默认安全设计。
firewalld 默认拒绝所有入站连接
firewalld 的 public 区域(也就是系统默认 zone)采用的是严格的“白名单”策略:只允许已知服务(例如 ssh)以及你手动开放的端口通过,其他未明确允许的入站流量都会被直接丢弃。这与旧版 iptables 常见的“默认放行”思路完全不同。因此在 CentOS 7 新环境中,如果出现 ping 不通,或者使用 curl 访问网页提示 connection refused,这通常属于正常现象,并不一定是服务器异常。
常见的误判情况包括:
systemctl status firewalld显示 active,但网站或服务依旧无法被外网访问firewall-cmd --list-ports返回为空,并不代表没有防火墙规则——也可能是通过--add-service或--add-source配置的- 临时开放了端口但忘记加
--permanent,导致系统重启后规则失效,排查时又难以第一时间发现原因
开放单个 TCP/UDP 端口的正确写法
在 CentOS 7 中配置 firewalld 开放端口时,必须同时满足三个前提:指定区域、明确协议类型、永久保存规则。少了任何一项,防火墙配置都可能无法达到预期效果。
例如开放 3306(MySQL)端口:
firewall-cmd --zone=public --add-port=3306/tcp --permanent firewall-cmd --reload
需要特别注意的关键点:
--zone=public不能省略——即使它是默认 zone,也不要假设 firewalld 会自动回退到正确区域/tcp或/udp必须完整写出,像firewall-cmd --add-port=3306这样的命令会直接报错- 如果没有添加
--permanent,那么这条规则只会作为运行时配置存在,执行systemctl restart firewalld后就会消失 --reload是使防火墙规则生效的必要步骤,不执行即使已经加了--permanent,新规则也不会立即启用
按 IP 段或单 IP 放通入站(比开整个端口更安全)
相比直接对外开放 80、22 或数据库端口,只允许特定 IP 或网段访问通常会更安全,尤其适用于运维后台、SSH 管理入口、MySQL 等敏感服务端口。
例如只允许 192.168.10.0/24 访问 22 端口:
firewall-cmd --permanent --zone=public --add-source=192.168.10.0/24 firewall-cmd --permanent --zone=public --add-port=22/tcp firewall-cmd --reload
这里要注意命令的顺序和实际逻辑:
--add-source的作用是将该 IP 段加入对应的publiczone,并不是直接开放某个端口- 后续仍然需要通过
--add-port或--add-service显式放行目标端口,因为 source 本身不包含端口访问策略 - 多个
--add-source可以同时存在;可使用--list-sources查看当前已生效的来源地址列表 - 删除 source 时应使用
--remove-source=xxx,而不是错误地使用--remove-port
查规则、验效果、排故障的实操命令
排查 CentOS 7 防火墙问题时,不要只执行一次 --list-all 就结束,很多访问异常实际上都出在 zone 绑定错误,或 runtime 与 permanent 配置不一致这类细节上。
快速验证可以按以下三步进行:
- 确认当前实际生效的 zone:
firewall-cmd --get-active-zones(重点查看输出中 interface 绑定到了哪个 zone) - 查看该 zone 下已经开放的所有端口:
firewall-cmd --zone=public --list-ports - 检查该 zone 是否确实绑定了你的来源 IP 或网段:
firewall-cmd --zone=public --list-sources
实际操作中最容易忽略的几个坑:
firewall-cmd --state返回running并不等于规则已经正确加载——有时--reload执行失败但没有明显提示- 你修改的是
publiczone 的规则,但服务器网卡实际上绑定在workzone,结果导致配置完全不生效 --query-port=80/tcp返回no,不一定说明端口没开放,也可能是规则被添加到了其他 zone 中
