最推荐的做法是直接在 MySQL 用户表中删除远程 root 记录,配合配置文件绑定本地地址,并通过系统防火墙封锁 3306 端口的外网访问,仅保留本地或特定内网 IP 的业务账号。
先说结论:禁止远程连接不能只靠单一配置,需同时从账号权限、网络监听和系统防火墙三层收口。
- 先判断:确认业务是否真的需要远程访问,生产环境严禁 root 远程登录。
- 优先做:删除 mysql.user 表中的远程 root 记录,并设置 bind-address 为 127.0.0.1。
- 再验证:使用外部机器尝试连接,确保无法建立 TCP 连接或认证失败。
- 必重启:修改配置文件后必须重启 MySQL 服务,否则监听设置不会生效。
命令速用版
以下是禁止远程 root 和限制监听的核心命令,请在测试环境验证后再用于生产:
-- 删除远程 root 用户 DROP USER 'root'@'%'; FLUSH PRIVILEGES; -- 配置文件 /etc/my.cnf 或 /etc/mysql/mysql.conf.d/mysqld.cnf [mysqld] bind-address = 127.0.0.1 -- 重启 MySQL 服务使配置生效 sudo systemctl restart mysql # 注意:部分 Linux 发行版服务名可能为 mysqld -- 防火墙封锁 3306 端口 (Ubuntu/Debian) sudo ufw deny 3306 -- 防火墙封锁 3306 端口 (CentOS/RHEL) sudo firewall-cmd `--remove-port`=3306/tcp `--permanent` sudo firewall-cmd `--reload`
为什么会这样
MySQL 的访问控制分为三层:应用层权限、网络层监听和系统层防火墙。只修改用户表而开放端口,攻击者仍可尝试暴力破解;只改监听而不删用户,若配置被还原则风险依旧。root 账号拥有最高权限,一旦泄露可导致数据丢失或服务器被控,因此必须限制其仅本地访问,业务连接应使用最小权限的专用账号。
分步处理
1. 检查现有账号权限
登录 MySQL 后执行查询,确认是否存在允许远程登录的 root 记录:
SELECT User, Host FROM mysql.user WHERE User = 'root';
若 Host 字段为 % 或具体公网 IP,说明存在远程登录风险。
2. 删除远程 root 记录
不要直接 UPDATE 用户表,推荐使用 DROP USER 命令:
DROP USER 'root'@'%'; FLUSH PRIVILEGES;
3. 修改监听地址
编辑 MySQL 配置文件,找到 [mysqld] 段,设置:
bind-address = 127.0.0.1
若需内网访问,可绑定内网 IP。修改后必须重启 MySQL 服务才能生效:
sudo systemctl restart mysql
4. 配置系统防火墙
即使数据库配置正确,也需防止端口暴露在公网。使用 iptables、ufw 或云服务商的安全组规则,禁止外部 IP 访问 3306 端口。
5. 创建专用业务账号
为应用创建独立账号,仅授予必要权限:
CREATE USER 'app_user'@'192.168.1.%' IDENTIFIED BY '强密码'; GRANT SELECT, INSERT ON mydb.* TO 'app_user'@'192.168.1.%';
怎么验证是否生效
1. 检查监听状态
在服务器执行以下命令,确认 3306 端口仅监听本地:
sudo ss -tlnp | grep :3306
正常应显示 127.0.0.1:3306,若显示 0.0.0.0:3306 则说明仍监听所有接口。
2. 验证用户权限
再次查询用户表,确认 root 仅剩 localhost 记录:
SELECT User, Host FROM mysql.user WHERE User = 'root';
3. 外部连接测试
使用另一台机器尝试连接数据库,应无法建立连接或提示访问拒绝。
常见坑
1. localhost 与 127.0.0.1 的区别
localhost 通常走 socket 连接,127.0.0.1 走 TCP 连接。配置 bind-address 时需注意两者差异,确保本地管理不受影响。
2. 直接修改 user 表的风险
在 MySQL 8.0+ 版本中,直接 UPDATE mysql.user 可能失败或触发安全机制,建议使用 DROP USER 或 CREATE USER 命令管理账号。
3. 云安全组忽略
云服务器除了系统防火墙,还需在控制台检查安全组规则,确保 3306 端口未对 0.0.0.0/0 开放。
4. 配置修改未重启
修改 my.cnf 后忘记重启服务是常见失误,会导致 bind-address 配置不生效,务必执行 systemctl restart 命令。