数据库安全一直是运维工作的重中之重。想象一下,如果有人半夜偷偷修改了核心业务表的数据,或者删除了重要记录,我们却浑然不知,这场景光是想想就让人后背发凉。MySQL自带的日志功能虽然强大,但针对合规审计的场景还是略显单薄。这时候,专业的审计插件就派上用场了。
我在实际运维中遇到过好几次需要追溯数据库操作的情况。有一次业务部门反馈数据异常,我们花了整整两天时间排查,最后才发现是某个临时账号执行了未经授权的UPDATE操作。如果当时启用了审计日志,可能十分钟就能定位问题。这就是为什么我现在给所有生产环境的MySQL都会部署审计插件。
Trellix(原McAfee)的audit-plugin是目前最成熟的MySQL审计解决方案之一。它能记录所有关键操作,包括:
这些记录会以JSON格式保存,方便后续分析和报警。对于需要满足等保、GDPR等合规要求的场景,这个插件简直是救命稻草。
在开始之前,我们必须确认MySQL的准确版本。这个插件对版本非常敏感,用错版本会导致各种奇怪错误。执行这个命令查看版本:
bash复制mysql -V
或者登录MySQL后执行:
sql复制SELECT VERSION();
我用的环境是MySQL 5.7.37,这也是目前企业中最常见的长期支持版本之一。如果你用的是5.7的其他版本,操作流程基本相同,但要注意插件版本匹配。
插件的官方仓库在GitHub上:
code复制https://github.com/trellix-enterprise/mysql-audit/releases
这里有个小技巧:不要直接在服务器上用wget下载zip包,因为GitHub的下载链接有时会变。我建议先在本机浏览器打开页面,复制真实的下载链接。对于我的环境,下载命令是:
bash复制cd /opt
wget --no-check-certificate https://github.com/trellix-enterprise/mysql-audit/releases/download/v1.1.10/audit-plugin-mysql-5.7-1.1.10-980-linux-x86_64.zip
下载完成后解压:
bash复制unzip audit-plugin-mysql-5.7-1.1.10-980-linux-x86_64.zip
解压后会看到一个包含lib目录和utils目录的文件夹,这里存放着核心的插件文件和偏移量计算工具。
MySQL有专门的插件存放目录,我们需要先把.so文件放到正确位置。先查看插件目录:
sql复制SHOW GLOBAL VARIABLES LIKE 'plugin_dir';
典型路径可能是/usr/lib64/mysql/plugin/。把插件文件复制过去:
bash复制cp audit-plugin-mysql-5.7-1.1.10-980/lib/libaudit_plugin.so /usr/lib64/mysql/plugin/
chmod +x /usr/lib64/mysql/plugin/libaudit_plugin.so
chown mysql:mysql /usr/lib64/mysql/plugin/libaudit_plugin.so
这里特别注意权限问题,很多安装失败都是因为mysql用户没有读取权限。
登录MySQL执行安装命令:
sql复制INSTALL PLUGIN audit SONAME 'libaudit_plugin.so';
如果一切顺利,你会看到Query OK的提示。可以用以下命令验证:
sql复制SHOW PLUGINS;
SHOW GLOBAL STATUS LIKE 'AUDIT_version';
先临时开启审计,测试功能是否正常:
sql复制SET GLOBAL audit_json_file=ON;
查看当前配置:
sql复制SHOW VARIABLES LIKE '%audit%'\G;
重点关注audit_json_log_file这个参数,它决定了审计日志的存放位置。默认可能在MySQL的数据目录下,建议改为专门的日志目录:
sql复制SET GLOBAL audit_json_log_file='/var/log/mysql_audit.json';
这是最常见的安装错误,通常是因为偏移量计算不正确。解决方法如下:
首先找到mysqld的路径:
bash复制whereis mysqld
然后用插件包中的工具计算偏移量:
bash复制./audit-plugin-mysql-5.7-1.1.10-980/utils/offset-extract.sh /usr/sbin/mysqld
你会得到一长串数字,把它们复制下来。编辑MySQL配置文件(通常是/etc/my.cnf或/etc/mysql/my.cnf),添加以下内容:
ini复制[mysqld]
# 审计offsets
audit_offsets=7832, 7880, 3640, 4800, 456, 360, 0, 32, 64, 160, 544, 7996, 4368, 3648, 3656, 3660, 6080, 2072, 8, 7064, 7104, 7088, 13480, 148, 672, 0
# 审计操作命令
audit_record_cmds='select,insert,delete,update,create,drop,alter,grant,truncate'
# 审计开关
audit_json_file=on
# 加载审计第三方库
plugin-load=AUDIT=libaudit_plugin.so
# 审计日志路径
audit_json_log_file=/var/log/mysql_audit.json
保存后重启MySQL:
bash复制systemctl restart mysqld
如果还是报错,很可能是SELinux在作祟。检查SELinux状态:
bash复制sestatus
临时关闭SELinux(重启后失效):
bash复制setenforce 0
永久关闭需要修改配置文件:
bash复制vi /etc/selinux/config
将SELINUX=enforcing改为SELINUX=disabled,然后重启服务器。
默认配置会记录所有操作,这可能导致日志量过大。我们可以通过以下参数进行过滤:
sql复制-- 只审计特定的数据库
SET GLOBAL audit_record_dbs='important_db';
-- 忽略某些用户的操作
SET GLOBAL audit_whitelist_users='monitor_user,backup_user';
-- 设置日志轮转大小(单位:MB)
SET GLOBAL audit_json_file_rotate_size=100;
审计日志会不断增长,需要配置日志轮转。创建logrotate配置:
bash复制vi /etc/logrotate.d/mysql-audit
内容如下:
code复制/var/log/mysql_audit.json {
daily
rotate 30
compress
delaycompress
missingok
notifempty
create 640 mysql mysql
postrotate
mysql -e "SET GLOBAL audit_json_file_flush=ON;"
endscript
}
这样配置后,日志会每天轮转一次,保留30天,并且自动压缩旧日志。
审计插件会对性能有一定影响,特别是在高并发场景。以下是我总结的几个优化点:
sql复制SET GLOBAL audit_sample_rate=0.1; -- 只记录10%的操作
审计日志的价值在于及时发现异常操作。我们可以用简单的shell脚本监控日志:
bash复制#!/bin/bash
# 监控最近5分钟的高危操作
PATTERN='"(command":"(drop|alter|grant|revoke)|user":"unknown_user")'
LOG_FILE="/var/log/mysql_audit.json"
if grep -a "$PATTERN" "$LOG_FILE" --since="5 minutes ago"; then
echo "发现高危数据库操作!" | mail -s "MySQL审计告警" admin@example.com
fi
把这个脚本加入crontab,每分钟执行一次。当然,更专业的做法是用ELK或者Splunk搭建完整的日志分析平台。
我在实际使用中发现,大多数数据安全问题都发生在非工作时间。建议特别关注晚上10点到凌晨4点的操作记录,这个时间段的人工操作往往最可疑。