firewalld放行3306端口必须用--permanent加--reload才持久生效,且需确保mysql绑定0.0.0.0:3306、selinux允许mysql_port_t端口、用户授权远程访问并刷新权限。

firewalld 放行 3306 端口必须用 --permanent 才持久生效
AlmaLinux 9 默认启用 firewalld,临时放行 firewall-cmd --add-port=3306/tcp 在重启或重载后会丢失。生产环境必须走永久规则,否则服务一重启就连不上。
- 永久添加:运行
firewall-cmd --add-port=3306/tcp --permanent - 重载配置:必须紧接着执行
firewall-cmd --reload,否则规则不生效 - 验证是否写入:
firewall-cmd --list-ports应输出3306/tcp;若为空,说明没 reload 或命令漏了--permanent - 不要用
--add-service=mysql—— 这个 service 在 AlmaLinux 9 的 firewalld 配置中通常未定义或映射错误端口,硬写端口号最可靠
MySQL 必须先监听 0.0.0.0:3306,firewalld 放行才起作用
firewalld 只管“端口通不通”,不管 MySQL 自己绑没绑定到外部地址。如果 ss -tlnp | grep :3306 只显示 127.0.0.1:3306,那即使防火墙全开,远程也连不上。
- 检查当前监听:运行
ss -tlnp | grep :3306,确认输出含*:3306或0.0.0.0:3306 - 修改配置:编辑
/etc/my.cnf(或/etc/my.cnf.d/mysql-server.cnf),确保有bind-address = 0.0.0.0;若该行被注释或值为127.0.0.1,需改掉 - 重启服务:改完必须运行
systemctl restart mysqld,否则配置不加载 - 注意:有些 RPM 包默认启用了
skip-networking,需在配置中显式删掉或设为skip-networking = OFF
SELinux 不关也要允许 mysqld 绑定 3306 端口
firewalld 开了、MySQL 也绑对了地址,但连接仍超时?很可能是 SELinux 拦住了端口绑定,而非网络层问题。
- 查拒绝日志:运行
ausearch -m avc -ts recent | grep mysqld,看到avc: denied { name_bind }就是它 - 确认端口类型:运行
semanage port -l | grep mysql_port_t,正常应有mysql_port_t tcp 3306 - 若无映射:手动添加
semanage port -a -t mysql_port_t -p tcp 3306 - 无需重启 mysqld,SELinux 策略立即生效;但若之前启动失败过,建议
systemctl restart mysqld清状态
远程用户权限和 skip-name-resolve 是两个独立但常被混淆的点
防火墙、绑定地址、SELinux 全通了,还是连不上?大概率卡在 MySQL 权限层或 DNS 解析环节。
- MySQL 用户必须显式授权远程访问:不能只靠
CREATE USER 'root'@'localhost',得加'root'@'%'或具体 IP,并执行GRANT ALL ON *.* TO 'root'@'%' IDENTIFIED BY 'xxx' WITH GRANT OPTION,再FLUSH PRIVILEGES -
skip-name-resolve建议开启:在[mysqld]段加入该配置项,避免客户端 IP 反向解析失败导致连接卡顿甚至拒绝;它不影响授权逻辑,只加速连接建立 - 测试连通性顺序:本地用
mysql -h 127.0.0.1 -u root -p→ 同网段机器用mysql -h <alma_ip> -u root -p</alma_ip>→ 最后再试跨网段或公网
实际部署时,最容易被跳过的不是某条命令,而是“改完配置没重启服务”或“忘了 reload firewall”。尤其 mysqld 启动失败后,systemd 可能缓存旧状态,systemctl status mysqld 看似 active,其实进程已僵死——务必配合 ss -tlnp | grep :3306 和 journalctl -u mysqld -n 50 --no-pager 交叉验证。











