mysql权限模型以“用户+主机”二元组为核心,创建用户时应直接指定host(如'192.168.1.100'),避免手动修改mysql.user表;须配合防火墙限制并实测验证。

直接用 CREATE USER 'user'@'host' 指定来源主机
MySQL 的权限模型本质是 “用户+主机” 二元组,host 字段不是附加配置,而是账户身份的一部分。想限制只能从某台机器访问,最稳妥的方式就是在创建时就写死:CREATE USER 'appuser'@'192.168.1.100' IDENTIFIED BY 'p@ssw0rd';。这比事后改权限更安全,也避免了因缓存或结构校验导致的异常。
- 只允许本地 Unix socket 连接?用
'user'@'localhost'(注意:它不等价于'user'@'127.0.0.1') - 允许整个内网段?用通配符
'user'@'192.168.1.%',但别写成'192.168.1.0/24'—— MySQL 不支持 CIDR - 域名可用,但默认开启
skip_name_resolve=OFF时会做反向 DNS 查询,可能卡住连接或匹配错 host
别手改 mysql.user 表,用 RENAME USER 或重建
看到网上有 UPDATE mysql.user SET Host='xxx' WHERE User='yyy' 的做法?别碰。MySQL 8.0+ 对系统表结构强校验,手动 UPDATE 可能破坏权限缓存一致性,甚至让账户无法登录。真要改已有用户的 host,优先走官方路径:
云模块_YunMOK网站管理系统采用PHP+MYSQL为编程语言,搭载自主研发的模块化引擎驱动技术,实现可视化拖拽无技术创建并管理网站!如你所想,无限可能,支持创建任何网站:企业、商城、O2O、门户、论坛、人才等一块儿搞定!永久免费授权,包括商业用途; 默认内置三套免费模板。PC网站+手机网站+适配微信+文章管理+产品管理+SEO优化+组件扩展+NEW Login界面.....目测已经遥遥领先..
- 安全迁移:用
RENAME USER 'olduser'@'%' TO 'olduser'@'192.168.1.100'; - 彻底清理:先
DROP USER 'olduser'@'%';,再CREATE USER ... GRANT ... - 切记:改完必须
FLUSH PRIVILEGES;,否则新规则不生效
防火墙才是真正的第一道门
仅靠 MySQL 层的 host 限制,拦不住连接建立阶段的扫描、爆破或连接数耗尽攻击。操作系统防火墙(如 iptables 或 ufw)必须同步配置,作为兜底防线:
- Ubuntu 上只放行指定 IP:
sudo ufw allow from 192.168.1.100 to any port 3306 - CentOS 7+ 用 firewalld:
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.100" port port="3306" protocol="tcp" accept' - 规则加完记得 reload,且确认默认策略是 deny —— 否则等于没设
验证是否真生效:从目标 IP 连,别只在本机试
很多人改完以为好了,结果应用连不上才发现被锁在外面。验证必须从被允许的那台机器上实测:mysql -u appuser -p -h your-mysql-server-ip。如果报 Access denied for user 'appuser'@'192.168.1.100',说明密码错或 host 不匹配;如果报 Connection refused 或超时,大概率是防火墙或 bind-address 没配对。
- 查当前所有用户:
SELECT User, Host FROM mysql.user;,确认Host列精确匹配你写的值 - 检查 MySQL 是否监听对外地址:
netstat -tlnp | grep :3306,若只显示127.0.0.1:3306,那即使权限开了也没用 - 错误日志位置因安装方式而异,常见的是
/var/log/mysql/error.log,拒绝原因通常就写在里面
'user'@'localhost' 和 'user'@'127.0.0.1' 被当成同一个账户来管理,以及防火墙规则没 reload 就以为生效了。









