审计人员的“只读”需精确控制元数据可见性、连接加密与日志访问路径,禁用process/show databases权限,按实际日志存储位置授最小select权,并强制ssl及人工管理账号生命周期。

审计人员的“只读”不是禁止写操作就完事,而是必须精确控制元数据可见性、连接加密和日志访问路径——否则 SHOW CREATE TABLE、INFORMATION_SCHEMA 查询或明文传输的审计流量,都可能绕过所谓“只读”防线。
为什么不能直接 GRANT SELECT ON *.* 给审计用户
这会让审计用户看到所有库名、表结构、索引定义甚至 mysql.user 密码哈希字段。审计场景下,这不是便利,是信息泄露。MySQL 不会因你没授 INSERT 就自动隐藏系统元数据。
-
GRANT SELECT ON *.*会暴露mysql、performance_schema、information_schema里的全部表名和列类型 - 即使只查业务库,
SHOW DATABASES仍会列出所有库——这不是权限问题,是 MySQL 默认行为;但配合SELECT ON information_schema.TABLES,就能推导出未授权库的表结构 - 审计真正需要的往往只是日志表(如
mysql.audit_log)或performance_schema.events_statements_history_long,而非整个实例的读能力
必须显式禁用 PROCESS 和 SHOW DATABASES 权限
这两个权限不涉及数据修改,却能暴露关键拓扑信息:PROCESS 可见所有活跃连接和原始 SQL,SHOW DATABASES 直接列出全部库名——对审计合规反而是风险点。
- 创建用户时加
REQUIRE SSL:例如CREATE USER 'auditor_q2'@'10.20.30.%' IDENTIFIED BY 'Aud1t2026!' REQUIRE SSL - 显式撤销高危权限:
REVOKE PROCESS, SHOW DATABASES ON *.* FROM 'auditor_q2'@'10.20.30.%' - 检查是否生效:
SHOW GRANTS FOR 'auditor_q2'@'10.20.30.%'输出里不应出现PROCESS或SHOW DATABASES - 确认服务端 SSL 已启用:
SHOW VARIABLES LIKE 'have_ssl'必须返回YES,否则REQUIRE SSL形同虚设
审计日志表权限要按实际存储位置单独授权
MySQL 8.0+ 的 audit_log 插件默认写文件,不进数据库;只有用第三方方案(如 audit_log_filter_linux)或开启 performance_schema 审计才需要授表级 SELECT。别一概而论。
- 若日志存文件,审计人员只需文件系统读取权,MySQL 内无需任何
SELECT授权 - 若日志存表(如
audit_log_db.audit_events),则只授该表:GRANT SELECT ON `audit_log_db`.`audit_events` TO 'auditor_q2'@'10.20.30.%' - 若依赖
performance_schema查行为记录,必须显式授权:GRANT SELECT ON performance_schema.* TO 'auditor_q2'@'10.20.30.%'(该库默认对普通用户不可见) -
AUDIT_ADMIN权限完全不需要给审计人员——它用于停用/重载插件,属于管理动作,不是查询动作
临时权限必须靠人工生命周期管理,别信“自动过期”
MySQL 没有 EXPIRE AFTER 语法,所谓“临时”全靠命名约定和定期清理。审计账号一旦创建,就得有人负责到期回收。
- 账号名带时间标识:如
'auditor_q2_2026'或'auditor_jun2026',避免模糊命名 - 权限变更后开新会话验证:
INSERT INTO xxx必须报错ERROR 1142,且SELECT能查到预期数据 - 不要依赖
FLUSH PRIVILEGES:MySQL 8.0+ 中GRANT/REVOKE自动生效,但旧部署或容器环境仍建议执行以防缓存残留 - 最易被忽略的是:审计用户若从
%主机接入,而你只 revoke 了'auditor_q2'@'10.20.30.%',残留的'auditor_q2'@'%'记录仍可能生效











