如何配置MySQL开启audit_log插件以审计用户登录及非法访问?
- 内容介绍
- 文章标签
- 相关推荐
本文共计981个文字,预计阅读时间需要4分钟。
MySQL默认不记录用户登录行为,必须手动启用`audit_log`插件并配置规则,否则无法查看到谁在什么时间登录过库、连接失败了几次、执行了哪些敏感语句。
确认 MySQL 版本是否支持 audit_log 插件
只有 MySQL 5.7.28+(企业版)或 MySQL 8.0.19+(社区版起内置 audit_log)才原生支持;MariaDB 用的是 server_audit 插件,不能混用。
- 运行
SELECT VERSION();查版本,低于 5.7.28 且是社区版 → 基本没戏,得换方案(比如用general_log+ 日志解析,但性能差、无登录状态区分) - MySQL 8.0.19+ 社区版可直接安装,无需额外下载插件包
- 检查插件是否存在:
SHOW PLUGINS;看输出里有没有audit_log行,Status是ACTIVE或DISABLED
加载 audit_log 插件并持久化配置
插件不随 mysqld 启动自动加载,必须显式安装,且配置写进 my.cnf 才能重启不失效。
- 连接 MySQL 后执行:
INSTALL PLUGIN audit_log SONAME 'audit_log.so';(Linux)或'audit_log.dll'(Windows) - 立即生效但重启会丢失,所以必须改配置文件:在
[mysqld]段加三行:plugin_load_add = audit_log.so audit_log = FORCE_PLUS_PERMANENT audit_log_format = JSON
-
audit_log_format = JSON推荐,比旧的NEWLINE格式更易解析(含时间戳、用户、主机、命令类型、返回码等字段) - 改完配置必须重启 mysqld,仅
FLUSH PRIVILEGES不生效
审计日志默认只写到错误日志目录,不单独存文件
audit_log 默认把日志追加到 MySQL 的 error_log 文件里(不是 general_log),和错误信息混在一起,容易漏看。
- 想分离存储,加配置:
audit_log_file = /var/log/mysql/audit.log(路径需 mysqld 进程有写权限) - 日志滚动靠外部工具(如 logrotate),MySQL 自身不轮转;不设
audit_log_rotate_on_size就一直追加,磁盘可能被打满 - 敏感操作如
DROP DATABASE、GRANT、SET PASSWORD默认都会记,但登录失败(Access denied)也记 —— 注意看日志里的"status": 1045这类 MySQL 错误码 - 不建议开
audit_log_policy = ALL,它会记录每条SELECT,IO 和磁盘压力陡增;用LOGINS或COMMANDS更实际
排查 audit_log 不写入的常见卡点
装了插件、配了参数,但日志文件空或没新增内容,大概率卡在这几个地方:
- 插件名写错:
audit_log.so在某些发行版 MySQL 包里叫audit_log_filter.so(尤其 Percona Server),先查ls -l $MYSQL_HOME/lib/plugin/ | grep audit - 配置写在
[client]或[mysql]段,而不是[mysqld]—— 插件只在服务端加载 - SELinux 或 AppArmor 拦截了写日志行为,临时关 SELinux 测试:
setenforce 0 - 用户没有
AUDIT_ADMIN权限,导致部分操作(如修改审计策略)被静默忽略(但登录记录本身不受影响) - 日志路径父目录不存在,或 mysqld 用户(如
mysql)无写权限,chown mysql:mysql /var/log/mysql再试
真正难的不是打开开关,而是日志量、存储周期、解析脚本和告警联动 —— 比如每天自动压缩归档、用 jq 提取失败登录 IP 并触发封禁,这些得自己搭,MySQL 只管写,不管分析。
本文共计981个文字,预计阅读时间需要4分钟。
MySQL默认不记录用户登录行为,必须手动启用`audit_log`插件并配置规则,否则无法查看到谁在什么时间登录过库、连接失败了几次、执行了哪些敏感语句。
确认 MySQL 版本是否支持 audit_log 插件
只有 MySQL 5.7.28+(企业版)或 MySQL 8.0.19+(社区版起内置 audit_log)才原生支持;MariaDB 用的是 server_audit 插件,不能混用。
- 运行
SELECT VERSION();查版本,低于 5.7.28 且是社区版 → 基本没戏,得换方案(比如用general_log+ 日志解析,但性能差、无登录状态区分) - MySQL 8.0.19+ 社区版可直接安装,无需额外下载插件包
- 检查插件是否存在:
SHOW PLUGINS;看输出里有没有audit_log行,Status是ACTIVE或DISABLED
加载 audit_log 插件并持久化配置
插件不随 mysqld 启动自动加载,必须显式安装,且配置写进 my.cnf 才能重启不失效。
- 连接 MySQL 后执行:
INSTALL PLUGIN audit_log SONAME 'audit_log.so';(Linux)或'audit_log.dll'(Windows) - 立即生效但重启会丢失,所以必须改配置文件:在
[mysqld]段加三行:plugin_load_add = audit_log.so audit_log = FORCE_PLUS_PERMANENT audit_log_format = JSON
-
audit_log_format = JSON推荐,比旧的NEWLINE格式更易解析(含时间戳、用户、主机、命令类型、返回码等字段) - 改完配置必须重启 mysqld,仅
FLUSH PRIVILEGES不生效
审计日志默认只写到错误日志目录,不单独存文件
audit_log 默认把日志追加到 MySQL 的 error_log 文件里(不是 general_log),和错误信息混在一起,容易漏看。
- 想分离存储,加配置:
audit_log_file = /var/log/mysql/audit.log(路径需 mysqld 进程有写权限) - 日志滚动靠外部工具(如 logrotate),MySQL 自身不轮转;不设
audit_log_rotate_on_size就一直追加,磁盘可能被打满 - 敏感操作如
DROP DATABASE、GRANT、SET PASSWORD默认都会记,但登录失败(Access denied)也记 —— 注意看日志里的"status": 1045这类 MySQL 错误码 - 不建议开
audit_log_policy = ALL,它会记录每条SELECT,IO 和磁盘压力陡增;用LOGINS或COMMANDS更实际
排查 audit_log 不写入的常见卡点
装了插件、配了参数,但日志文件空或没新增内容,大概率卡在这几个地方:
- 插件名写错:
audit_log.so在某些发行版 MySQL 包里叫audit_log_filter.so(尤其 Percona Server),先查ls -l $MYSQL_HOME/lib/plugin/ | grep audit - 配置写在
[client]或[mysql]段,而不是[mysqld]—— 插件只在服务端加载 - SELinux 或 AppArmor 拦截了写日志行为,临时关 SELinux 测试:
setenforce 0 - 用户没有
AUDIT_ADMIN权限,导致部分操作(如修改审计策略)被静默忽略(但登录记录本身不受影响) - 日志路径父目录不存在,或 mysqld 用户(如
mysql)无写权限,chown mysql:mysql /var/log/mysql再试
真正难的不是打开开关,而是日志量、存储周期、解析脚本和告警联动 —— 比如每天自动压缩归档、用 jq 提取失败登录 IP 并触发封禁,这些得自己搭,MySQL 只管写,不管分析。

