MySQL的用户权限信息存储在系统库中,定期审计用户权限能够及时发现权限过度授予、权限异常变更等安全风险,是数据库运维过程中必不可少的工作。通过合理的审计方案,可以自动化完成权限检查,减少人工操作的成本和误差。

MySQL用户权限的存储逻辑
MySQL的用户权限相关信息主要存放在mysql系统库和information_schema库中,不同层级的权限存储在不同的表中:
- 全局权限:存储在
mysql.user表,记录所有用户的全局操作权限 - 数据库层级权限:存储在
mysql.db表,记录用户对指定数据库的操作权限 - 表层级权限:存储在
mysql.tables_priv表,记录用户对指定数据表的操作权限 - 列层级权限:存储在
mysql.columns_priv表,记录用户对指定字段的操作权限
我们可以通过查询这些系统表获取所有用户的权限明细,作为审计的基础数据。
权限审计的核心维度
定期审计时通常需要关注以下几个核心维度:
1. 权限授予合理性
检查是否存在授予过高权限的情况,比如普通业务账号被授予SUPER、FILE等高危权限,或者账号拥有超出业务需求的数据库操作权限。
2. 权限变更记录
对比历史权限快照,检查是否有未报备的权限新增、修改或回收操作,及时发现异常权限变更。
3. 闲置账号权限
检查长期未登录的账号是否仍持有有效权限,避免闲置账号被恶意利用。
手动审计权限的查询方法
如果需要临时查看某个用户的权限,可以使用SHOW GRANTS语句,示例如下:
-- 查看当前登录用户的权限 SHOW GRANTS; -- 查看指定用户test_user的权限 SHOW GRANTS FOR 'test_user'@'localhost';
如果需要批量获取所有用户的权限明细,可以查询information_schema库的USER_PRIVILEGES表,示例如下:
-- 查询所有用户的全局权限 SELECT * FROM information_schema.USER_PRIVILEGES;
如果需要获取更细粒度的权限信息,比如用户对某个数据库的权限,可以查询information_schema.SCHEMA_PRIVILEGES表:
-- 查询所有用户对数据库的权限 SELECT * FROM information_schema.SCHEMA_PRIVILEGES;
实现定期自动化审计
手动审计效率较低,更适合临时排查问题,生产环境通常需要实现定期自动化审计,整体流程可以分为三步:
第一步:编写权限采集脚本
我们可以编写一个Shell脚本,定期查询MySQL的权限信息并保存到本地文件中,示例如下:
#!/bin/bash
# MySQL连接配置
MYSQL_USER="audit_user"
MYSQL_PASS="audit_password"
MYSQL_HOST="127.0.0.1"
MYSQL_PORT="3306"
# 权限快照存储目录
SAVE_DIR="/data/mysql_audit"
# 创建存储目录
mkdir -p ${SAVE_DIR}
# 生成时间戳
TIME_STAMP=$(date +"%Y%m%d_%H%M%S")
# 导出所有用户全局权限
mysql -h${MYSQL_HOST} -P${MYSQL_PORT} -u${MYSQL_USER} -p${MYSQL_PASS} -e "SELECT * FROM information_schema.USER_PRIVILEGES;" > ${SAVE_DIR}/user_priv_${TIME_STAMP}.txt
# 导出所有用户数据库层级权限
mysql -h${MYSQL_HOST} -P${MYSQL_PORT} -u${MYSQL_USER} -p${MYSQL_PASS} -e "SELECT * FROM information_schema.SCHEMA_PRIVILEGES;" > ${SAVE_DIR}/schema_priv_${TIME_STAMP}.txt
# 导出所有用户表层级权限
mysql -h${MYSQL_HOST} -P${MYSQL_PORT} -u${MYSQL_USER} -p${MYSQL_PASS} -e "SELECT * FROM information_schema.TABLE_PRIVILEGES;" > ${SAVE_DIR}/table_priv_${TIME_STAMP}.txt
echo "权限快照采集完成,存储路径:${SAVE_DIR}"
第二步:配置定时任务
在Linux系统中可以使用crontab配置定期执行上述脚本,比如每周一凌晨2点执行审计采集:
# 编辑crontab任务 crontab -e # 添加如下内容,每周一凌晨2点执行脚本 0 2 * * 1 /bin/bash /data/scripts/mysql_priv_audit.sh
第三步:权限对比与告警
可以编写额外的对比脚本,将新采集的权限快照和历史快照进行对比,如果发现异常权限变更,通过邮件或者内部告警渠道通知运维人员。对比逻辑示例如下:
#!/bin/bash
# 历史快照路径
OLD_SNAPSHOT="/data/mysql_audit/user_priv_20240101_020000.txt"
# 最新快照路径
NEW_SNAPSHOT="/data/mysql_audit/user_priv_latest.txt"
# 对比两个快照的差异
DIFF_RESULT=$(diff ${OLD_SNAPSHOT} ${NEW_SNAPSHOT})
if [ -n "${DIFF_RESULT}" ]; then
echo "检测到权限变更,差异内容:${DIFF_RESULT}"
# 此处可以添加告警发送逻辑
fi
审计注意事项
在实施定期权限审计时需要注意以下几点:
- 执行审计的账号只需要授予查询
information_schema和mysql库相关权限即可,不需要授予其他高危权限,避免审计账号本身带来安全风险 - 权限快照文件需要设置合理的访问权限,避免权限信息泄露
- 审计周期需要根据业务需求调整,核心业务数据库可以缩短审计周期,非核心数据库可以适当延长
- 审计规则需要定期更新,根据业务变更调整权限合理性的判断标准
定期审计用户权限是MySQL安全运维的基础工作,结合自动化工具可以大幅提升审计效率,及时发现权限相关的安全隐患,保障数据库的稳定运行。
MySQL用户权限审计定期任务权限管理information_schema修改时间:2026-07-10 12:27:26