host为'%'、空字符串或含%通配符即属高危配置,需立即定位并删除,同时联动bind-address与防火墙实现四层闭环控制。

直接结论:Host字段为%、空字符串''或通配符(如192.168.%)且未配合网络层控制时,基本等于开放攻击面。
查出所有高危Host配置的用户
MySQL权限模型中,user表的Host列决定连接来源,不是“允许谁登录”,而是“允许从哪来登录”。不加限制的Host值是多数入侵的第一跳板。
- 执行
SELECT user, host FROM mysql.user WHERE host = '%' OR host = '' OR host LIKE '%\%%' ESCAPE '\';——快速定位%、空值、含%通配符的记录 - 特别注意
root账户是否出现在host = '%'行;若存在,几乎可判定为高危配置 - 避免用
SELECT * FROM mysql.user全量扫描,容易漏掉host字段的语义细节(比如localhost和127.0.0.1在Unix socket下行为不同)
区分localhost和127.0.0.1的实际影响
这两个值看起来都指本地,但MySQL底层处理机制完全不同:localhost强制走socket文件,127.0.0.1走TCP回环。若bind-address被设为127.0.0.1而用户Host是localhost,反而可能连不上。
- 生产环境建议统一用
'root'@'127.0.0.1'而非'root'@'localhost',便于与防火墙策略对齐 - 如果必须保留
localhost,确认skip-networking未启用,否则TCP连接会被彻底禁用 - 检查
SHOW VARIABLES LIKE 'socket';路径是否受权限保护(如非root不可读),否则socket文件本身也可能被劫持
修复时别只改Host字段,要DROP+CREATE
很多人试图用UPDATE mysql.user SET host = '192.168.1.100' WHERE user = 'app' AND host = '%';,这不仅无效(MySQL不支持直接UPDATE权限表),还会导致FLUSH PRIVILEGES后权限错乱甚至拒绝服务。
- 正确做法是先
DROP USER 'app'@'%';,再CREATE USER 'app'@'192.168.1.100' IDENTIFIED BY '...'; - 重建后必须重新
GRANT,不能依赖旧权限残留——GRANT操作会重写mysql.tables_priv等关联表 - 执行前用
SHOW GRANTS FOR 'app'@'%';备份原权限,避免误删后无法还原
Host配置必须和bind-address及防火墙联动
单独收紧Host字段只是纸面安全。若my.cnf里bind-address = 0.0.0.0,且系统防火墙放行了3306端口,那么'app'@'192.168.1.100'形同虚设——攻击者只要在内网伪造IP就能连上。
- 检查
SELECT @@bind_address;或直接看/etc/my.cnf中的bind-address值,生产环境禁止为0.0.0.0 - 用
iptables -L -n | grep :3306确认防火墙规则是否精确到源IP段,而非仅限端口开放 - 如果应用部署在容器或云环境,还要检查安全组/Network Policy是否覆盖了数据库实例的实际入口IP
真正卡住风险的不是某一行Host值,而是user表配置、MySQL网络监听、操作系统防火墙、基础设施访问控制这四层是否形成闭环。漏掉任何一层,Host字段再严谨也只是单点防御。











