能,GRANT 支持 IP 段字符串通配如 '192.168.1.%',但仅作前缀匹配而非子网匹配,不支持 CIDR;需禁用 DNS 解析(skip_name_resolve=ON)并确保客户端使用 IP 连接。
GRANT 语句里用 IP 段通配符(如
)能生效吗?
能,但仅限于标准的主机名通配规则,不支持 CIDR(如
)或子网掩码语法。MySQL 的
对
参数只认两种模式:精确匹配(如
)和简单通配(
或
),其中
匹配任意长度字符串(包括空),
匹配单个字符。
所以
是合法且常用的做法,它会匹配
、
,甚至
(如果 DNS 反解出这种名字)——这本身已是隐患。
→ 匹配所有以
开头的 IPv4 地址或主机名(注意:不是“该网段”,而是“字符串前缀”)
→ 表面想覆盖
,但也会误放
(因为
不限制位数)
→ 直接报错:
,MySQL 根本不解析 CIDR
为什么
有时连不上?
常见原因不是语法错,而是 MySQL 的主机名解析逻辑在作祟。默认开启
时,MySQL 会对客户端 IP 做反向 DNS 查询,再正向查一次,确保正反解析一致;若失败,就拒绝连接,哪怕你写的
是 IP 通配符。
检查是否真在用 IP 连接:如果客户端用的是域名(如
),而你授权的是
,那完全不匹配
确认 MySQL 是否做了 DNS 查:执行
,值为
就会查 DNS;设为
可强制只比对 IP 字符串(推荐生产环境开启)
防火墙或代理可能修改了源 IP:比如 Nginx 代理没传
,后端看到的是
,而非真实内网 IP
替代方案:用
表直接插入带子网掩码的记录可行吗?
不行。
表的
字段仍是字符串类型,没有字段存子网掩码;MySQL 服务层根本不识别 CIDR,所有所谓“子网授权”都得靠应用层或网络层控制。
MySQL(Linux)
MySQL 9.6.0是面向Linux平台的2026年创新版本,核心架构迎来重大革新。其将外键约束与级联操作从InnoDB引擎层上移至SQL层,确保所有数据变更均被完整记录至Binlog,彻底解决了CDC(变更数据捕获)与主从复制中的数据不一致难题。此外,该版本引入container_aware启动选项以原生适配容器环境,并对审计日志进行了组件化重构,为追求极致数据一致性与云原生体验的开发者提供了全新选择。
下载
不要手动 INSERT 到
并指定
—— 这条记录会被当作字面量,只匹配主机名为该字符串的客户端(几乎不可能)
不要指望
能成功,语法直接报错
真正可控的边界在:防火墙(iptables/nftables)、云厂商安全组、MySQL Proxy、或前置连接池(如 ProxySQL)做 IP 白名单
实际部署建议:最小权限 + 明确范围 + 验证方式
别把授权粒度押在
字符串上。一个稳健的组合是:精确 IP 段通配 + 禁用 DNS 解析 + 连接时强制用 IP + 登录后验证
和
。
执行
(需重启或动态生效取决于版本),然后
用
,而不是
或
验证是否生效:从目标机器用
连,成功后立即执行
—— 前者显示你“声称”的用户,后者才是 MySQL 实际匹配到的授权行
注意:MySQL 8.0+ 默认认证插件是
,老客户端可能连不上,必要时加
IP 段授权表面简单,实际依赖 DNS 行为、网络路径、客户端调用方式三者对齐;漏掉任一环,
就只是个摆设。
192.168.1.%192.168.1.0/24GRANTHOST'192.168.1.10'%_%_'192.168.1.%'192.168.1.1192.168.1.255192.168.1.123abc'192.168.1.%'192.168.1.'192.168.%.%'192.168.x.y192.1680.1.1%'192.168.1.0/24'ERROR 1133 (HY000): Can't find any matching row in the user tableGRANT ... ON *.* TO 'u'@'192.168.1.%'skip_name_resolve=OFFHOSTapp-server.internal'192.168.1.%'SHOW VARIABLES LIKE 'skip_name_resolve';OFFONX-Real-IP127.0.0.1usermysql.userHostmysql.userHost='192.168.1.0/24'CREATE USER 'u'@'192.168.1.0/24'HOSTUSER()CURRENT_USER()SET GLOBAL skip_name_resolve = ON;FLUSH PRIVILEGES;GRANT SELECT ON mydb.* TO 'reporter'@'10.0.5.%';'10.0.%.%''%'mysql -h db-host -u reporter -pSELECT USER(), CURRENT_USER();caching_sha2_passwordIDENTIFIED WITH mysql_native_password@'192.168.1.%'