背景需求
很多时候项目上,需要过等保3级,以往都是客户提供数据库审计的设备,但免不了碰到一些特殊情况,所以就需要我们自己给满足数据库的审计需求👇。
环境信息
在调研了市场上开源的数据库审计的插件,发现原来在Mysql5.7.33版本中,可使用server_audit.so插件审计日志插件(来源MariaDB )无问题,但从5.7.34版本开始,该插件停止使用,针对5.7.34及之后的版本,mysql社区版官方不支持audit,只能使用第三方插件,现使用另外开源插件audit-plugin实现审计日志, 另外较新版本的mariadb已经默认支持 audit:server-audit
,直接启用即可。
软件名称 | 版本 |
---|---|
Mysql | 5.7.44 |
mysql-audit | 5.7-1.1.13-1008 |
Mysql-Audit 插件安装
- Mysql audit 一个 MySQL 插件,为 MySQL 提供审计功能,其设计侧重于安全性和审计要求。该插件可以用作独立的审计解决方案,也可以配置为将数据提供给外部监控工具。
- 插件下载地址【选择对应版本数据库下载即可】: https://github.com/trellix-enterprise/mysql-audit/releases
解压安装
unzip audit-plugin-mysql-5.7-1.1.13-1008-linux-x86_64.zip
查看Mysq插件目录
mysql> show variables like 'plugin_dir';
+---------------+-----------------------------------------+
| Variable_name | Value |
+---------------+-----------------------------------------+
| plugin_dir | /home/application/mysql/app/lib/plugin/ |
+---------------+-----------------------------------------+
1 row in set (0.00 sec)
复制插件到mysql插件目录下,添加可执行权限,并授权用户
cd audit-plugin-mysql-5.7-1.1.13-1008/lib/libaudit_plugin.so /home/application/mysql/app/lib/plugin/
chmod +x /home/application/mysql/app/lib/plugin/libaudit_plugin.so
chown -Rf mysql:mysql /home/application/mysql/app/lib/plugin/libaudit_plugin.so
执行Mysql-Audit 插件下面的offset-extract.sh 脚本
which mysqld
/home/application/mysql/app/bin/mysqld
bash audit-plugin-mysql-5.7-1.1.13-1008/utils/offset-extract.sh /home/application/mysql/app/bin/mysqld
//offsets for: /home/application/mysql/app/bin/mysqld (5.7.44)
{"5.7.44","69317d5de2fd9a7a95b58a4ce2be0bd1", 7840, 7888, 3648, 4808, 456, 360, 0, 32, 64, 160, 544, 8004, 4376, 3656, 3664, 3668, 6088, 2072, 8, 7072, 7112, 7096, 13488, 148, 672, 0},
#⚠️如果提示没有gdb 则需要 yum install gdb
配置My.cnf
-
audit_offsets=上面脚本执行后的结果
-
audit_record_cmds 表示针对这些语句来审计,这里我们现注释,表示审计所有内容
-
audit_json_log_file 日志存放的路径
/home/application/mysql/logs/mysql-audit.json
⚠️目录需要提前创建好,并且mysql用户对这个目录拥有所有权限#audit
audit_json_file=on
plugin-load=AUDIT=libaudit_plugin.so
#audit_record_cmds='insert,delete,update,create,drop,alter'
audit_json_log_file=/home/application/mysql/logs/mysql-audit.json
audit_offsets= 7840, 7888, 3648, 4808, 456, 360, 0, 32, 64, 160, 544, 8004, 4376, 3656, 3664, 3668, 6088, 2072, 8, 7072, 7112, 7096, 13488, 148, 672, 0
重启Mysql
systemctl restart mysqld
查看审计配置是否生效
#查看插件是否启用
mysql> show plugins;
+----------------------------+----------+--------------------+--------------------+---------+
| Name | Status | Type | Library | License |
+----------------------------+----------+--------------------+--------------------+---------+
| binlog | ACTIVE | STORAGE ENGINE | NULL | GPL |
.............................................................................................
| AUDIT | ACTIVE | AUDIT | libaudit_plugin.so | GPL |
+----------------------------+----------+--------------------+--------------------+---------+
#查看审计插件的版本
mysql> show global status like '%audit%';
+------------------------+-------------+
| Variable_name | Value |
+------------------------+-------------+
| Audit_protocol_version | 1.0 |
| Audit_version | 1.1.13-1008 |
+------------------------+-------------+
2 rows in set (0.01 sec)
#查看审计日志路径
mysql> SHOW GLOBAL VARIABLES LIKE 'audit_json_file';
+-----------------+-------+
| Variable_name | Value |
+-----------------+-------+
| audit_json_file | ON |
+-----------------+-------+
1 row in set (0.00 sec)
模拟SQL数据

-- 1. 创建数据库
CREATE DATABASE IF NOT EXISTS test_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- 2. 创建初始表
CREATE TABLE IF NOT EXISTS test_db.student (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50) NOT NULL,
age INT CHECK (age BETWEEN 18 AND 100)
);
-- 3. 插入初始数据
INSERT INTO test_db.student (name, age) VALUES ('张三', 20);
INSERT INTO test_db.student (name, age) VALUES ('李四', 22);
INSERT INTO test_db.student (name, age) VALUES ('王五', 19);
-- 4. 修改表结构(增加列)
ALTER TABLE test_db.student ADD COLUMN gender VARCHAR(10);
-- 5. 更新数据(结合新列使用)
UPDATE test_db.student SET gender = '男' WHERE name = '张三';
UPDATE test_db.student SET gender = '女' WHERE name = '李四';
UPDATE test_db.student SET gender = '男' WHERE name = '王五';
-- 6. 再次修改表结构(修改列类型)
ALTER TABLE test_db.student MODIFY COLUMN gender CHAR(1);
-- 7. 删除列
ALTER TABLE test_db.student DROP COLUMN gender;
-- 8. 更新数据(剩余有效数据)
UPDATE test_db.student SET age = 21 WHERE name = '张三';
-- 9. 删除数据
DELETE FROM test_db.student WHERE name = '王五';
-- 10. 删除表
DROP TABLE IF EXISTS test_db.student;
-- 11. 删除数据库
DROP DATABASE IF EXISTS test_db;
查看审计日志
通过查看审计日志,可以看到我们需要的审计内容
审计的动作: 包含 登录数据库,创建数据库,创建表,插入数据,更改表结构,更新数据,删除列,删除数据,删除表,删除数据库
{"msg-type":"activity","date":"1744100793350","thread-id":"3","query-id":"0","user":"root","priv_user":"root","ip":"172.16.200.200","host":"172.16.200.200","_os":"Windows","_client_name":"libmariadb","_pid":"27656","_thread":"32420","_platform":"AMD64","_client_version":"3.2.3","_server_host":"172.22.33.207","cmd":"Connect","query":"Connect"}
{"msg-type":"activity","date":"1744100793351","thread-id":"3","query-id":"2","user":"root","priv_user":"root","ip":"172.16.200.200","host":"172.16.200.200","_os":"Windows","_client_name":"libmariadb","_pid":"27656","_thread":"32420","_platform":"AMD64","_client_version":"3.2.3","_server_host":"172.22.33.207","status":"0","cmd":"set_option","query":"SET NAMES utf8mb4"}
{"msg-type":"activity","date":"1744100793352","thread-id":"3","query-id":"3","user":"root","priv_user":"root","ip":"172.16.200.200","host":"172.16.200.200","_os":"Windows","_client_name":"libmariadb","_pid":"27656","_thread":"32420","_platform":"AMD64","_client_version":"3.2.3","_server_host":"172.22.33.207","status":"0","cmd":"set_option","query":"SET PROFILING = 1"}
{"msg-type":"activity","date":"1744100793356","thread-id":"3","query-id":"4","user":"root","priv_user":"root","ip":"172.16.200.200","host":"172.16.200.200","_os":"Windows","_client_name":"libmariadb","_pid":"27656","_thread":"32420","_platform":"AMD64","_client_version":"3.2.3","_server_host":"172.22.33.207","rows":"359","status":"0","cmd":"show_status","objects":[{"db":"","obj_type":"TABLE"},{"db":"performance_schema","name":"session_status","obj_type":"TABLE"}],"query":"SHOW STATUS"}
{"msg-type":"activity","date":"1744100793361","thread-id":"3","query-id":"5","user":"root","priv_user":"root","ip":"172.16.200.200","host":"172.16.200.200","_os":"Windows","_client_name":"libmariadb","_pid":"27656","_thread":"32420","_platform":"AMD64","_client_version":"3.2.3","_server_host":"172.22.33.207","rows":"359","status":"0","cmd":"show_status","objects":[{"db":"","obj_type":"TABLE"},{"db":"performance_schema","name":"session_status","obj_type":"TABLE"}],"query":"SHOW STATUS"}
{"msg-type":"activity","date":"1744100793366","thread-id":"3","query-id":"6","user":"root","priv_user":"root","ip":"172.16.200.200","host":"172.16.200.200","_os":"Windows","_client_name":"libmariadb","_pid":"27656","_thread":"32420","_platform":"AMD64","_client_version":"3.2.3","_server_host":"172.22.33.207","status":"0","cmd":"create_db","query":"-- 1. 创建数据库\r\nCREATE DATABASE IF NOT EXISTS test_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci"}
{"msg-type":"activity","date":"1744100793371","thread-id":"3","query-id":"7","user":"root","priv_user":"root","ip":"172.16.200.200","host":"172.16.200.200","_os":"Windows","_client_name":"libmariadb","_pid":"27656","_thread":"32420","_platform":"AMD64","_client_version":"3.2.3","_server_host":"172.22.33.207","status":"0","cmd":"create_table","objects":[{"db":"test_db","name":"student","obj_type":"TABLE"}],"query":"-- 2. 创建初始表\r\nCREATE TABLE IF NOT EXISTS test_db.student (\r\n id INT PRIMARY KEY AUTO_INCREMENT,\r\n name VARCHAR(50) NOT NULL,\r\n age INT CHECK (age BETWEEN 18 AND 100)\r\n)"}
{"msg-type":"activity","date":"1744100793380","thread-id":"3","query-id":"8","user":"root","priv_user":"root","ip":"172.16.200.200","host":"172.16.200.200","_os":"Windows","_client_name":"libmariadb","_pid":"27656","_thread":"32420","_platform":"AMD64","_client_version":"3.2.3","_server_host":"172.22.33.207","rows":"1","status":"0","cmd":"insert","objects":[{"db":"test_db","name":"student","obj_type":"TABLE"}],"query":"-- 3. 插入初始数据\r\nINSERT INTO test_db.student (name, age) VALUES ('张三', 20)"}
{"msg-type":"activity","date":"1744100793392","thread-id":"3","query-id":"9","user":"root","priv_user":"root","ip":"172.16.200.200","host":"172.16.200.200","_os":"Windows","_client_name":"libmariadb","_pid":"27656","_thread":"32420","_platform":"AMD64","_client_version":"3.2.3","_server_host":"172.22.33.207","rows":"1","status":"0","cmd":"insert","objects":[{"db":"test_db","name":"student","obj_type":"TABLE"}],"query":"INSERT INTO test_db.student (name, age) VALUES ('李四', 22)"}
{"msg-type":"activity","date":"1744100793395","thread-id":"3","query-id":"10","user":"root","priv_user":"root","ip":"172.16.200.200","host":"172.16.200.200","_os":"Windows","_client_name":"libmariadb","_pid":"27656","_thread":"32420","_platform":"AMD64","_client_version":"3.2.3","_server_host":"172.22.33.207","rows":"1","status":"0","cmd":"insert","objects":[{"db":"test_db","name":"student","obj_type":"TABLE"}],"query":"INSERT INTO test_db.student (name, age) VALUES ('王五', 19)"}
{"msg-type":"activity","date":"1744100793428","thread-id":"3","query-id":"11","user":"root","priv_user":"root","ip":"172.16.200.200","host":"172.16.200.200","_os":"Windows","_client_name":"libmariadb","_pid":"27656","_thread":"32420","_platform":"AMD64","_client_version":"3.2.3","_server_host":"172.22.33.207","status":"0","cmd":"alter_table","objects":[{"db":"test_db","name":"student","obj_type":"TABLE"}],"query":"-- 4. 修改表结构(增加列)\r\nALTER TABLE test_db.student ADD COLUMN gender VARCHAR(10)"}
{"msg-type":"activity","date":"1744100793430","thread-id":"3","query-id":"12","user":"root","priv_user":"root","ip":"172.16.200.200","host":"172.16.200.200","_os":"Windows","_client_name":"libmariadb","_pid":"27656","_thread":"32420","_platform":"AMD64","_client_version":"3.2.3","_server_host":"172.22.33.207","rows":"1","status":"0","cmd":"update","objects":[{"db":"test_db","name":"student","obj_type":"TABLE"}],"query":"-- 5. 更新数据(结合新列使用)\r\nUPDATE test_db.student SET gender = '男' WHERE name = '张三'"}
{"msg-type":"activity","date":"1744100793431","thread-id":"3","query-id":"13","user":"root","priv_user":"root","ip":"172.16.200.200","host":"172.16.200.200","_os":"Windows","_client_name":"libmariadb","_pid":"27656","_thread":"32420","_platform":"AMD64","_client_version":"3.2.3","_server_host":"172.22.33.207","rows":"1","status":"0","cmd":"update","objects":[{"db":"test_db","name":"student","obj_type":"TABLE"}],"query":"UPDATE test_db.student SET gender = '女' WHERE name = '李四'"}
{"msg-type":"activity","date":"1744100793432","thread-id":"3","query-id":"14","user":"root","priv_user":"root","ip":"172.16.200.200","host":"172.16.200.200","_os":"Windows","_client_name":"libmariadb","_pid":"27656","_thread":"32420","_platform":"AMD64","_client_version":"3.2.3","_server_host":"172.22.33.207","rows":"1","status":"0","cmd":"update","objects":[{"db":"test_db","name":"student","obj_type":"TABLE"}],"query":"UPDATE test_db.student SET gender = '男' WHERE name = '王五'"}
{"msg-type":"activity","date":"1744100793441","thread-id":"3","query-id":"15","user":"root","priv_user":"root","ip":"172.16.200.200","host":"172.16.200.200","_os":"Windows","_client_name":"libmariadb","_pid":"27656","_thread":"32420","_platform":"AMD64","_client_version":"3.2.3","_server_host":"172.22.33.207","status":"0","cmd":"alter_table","objects":[{"db":"test_db","name":"student","obj_type":"TABLE"}],"query":"-- 6. 再次修改表结构(修改列类型)\r\nALTER TABLE test_db.student MODIFY COLUMN gender CHAR(1)"}
{"msg-type":"activity","date":"1744100793472","thread-id":"3","query-id":"16","user":"root","priv_user":"root","ip":"172.16.200.200","host":"172.16.200.200","_os":"Windows","_client_name":"libmariadb","_pid":"27656","_thread":"32420","_platform":"AMD64","_client_version":"3.2.3","_server_host":"172.22.33.207","status":"0","cmd":"alter_table","objects":[{"db":"test_db","name":"student","obj_type":"TABLE"}],"query":"-- 7. 删除列\r\nALTER TABLE test_db.student DROP COLUMN gender"}
{"msg-type":"activity","date":"1744100793473","thread-id":"3","query-id":"17","user":"root","priv_user":"root","ip":"172.16.200.200","host":"172.16.200.200","_os":"Windows","_client_name":"libmariadb","_pid":"27656","_thread":"32420","_platform":"AMD64","_client_version":"3.2.3","_server_host":"172.22.33.207","rows":"1","status":"0","cmd":"update","objects":[{"db":"test_db","name":"student","obj_type":"TABLE"}],"query":"-- 8. 更新数据(剩余有效数据)\r\nUPDATE test_db.student SET age = 21 WHERE name = '张三'"}
{"msg-type":"activity","date":"1744100793474","thread-id":"3","query-id":"18","user":"root","priv_user":"root","ip":"172.16.200.200","host":"172.16.200.200","_os":"Windows","_client_name":"libmariadb","_pid":"27656","_thread":"32420","_platform":"AMD64","_client_version":"3.2.3","_server_host":"172.22.33.207","rows":"1","status":"0","cmd":"delete","objects":[{"db":"test_db","name":"student","obj_type":"TABLE"}],"query":"-- 9. 删除数据\r\nDELETE FROM test_db.student WHERE name = '王五'"}
{"msg-type":"activity","date":"1744100793477","thread-id":"3","query-id":"19","user":"root","priv_user":"root","ip":"172.16.200.200","host":"172.16.200.200","_os":"Windows","_client_name":"libmariadb","_pid":"27656","_thread":"32420","_platform":"AMD64","_client_version":"3.2.3","_server_host":"172.22.33.207","status":"0","cmd":"drop_table","objects":[{"db":"test_db","name":"student","obj_type":"TABLE"}],"query":"-- 10. 删除表\r\nDROP TABLE IF EXISTS test_db.student"}
{"msg-type":"activity","date":"1744100793478","thread-id":"3","query-id":"20","user":"root","priv_user":"root","ip":"172.16.200.200","host":"172.16.200.200","_os":"Windows","_client_name":"libmariadb","_pid":"27656","_thread":"32420","_platform":"AMD64","_client_version":"3.2.3","_server_host":"172.22.33.207","status":"0","cmd":"drop_db","query":"-- 11. 删除数据库\r\nDROP DATABASE IF EXISTS test_db"}
{"msg-type":"activity","date":"1744100793480","thread-id":"3","query-id":"21","user":"root","priv_user":"root","ip":"172.16.200.200","host":"172.16.200.200","_os":"Windows","_client_name":"libmariadb","_pid":"27656","_thread":"32420","_platform":"AMD64","_client_version":"3.2.3","_server_host":"172.22.33.207","rows":"359","status":"0","cmd":"show_status","objects":[{"db":"","obj_type":"TABLE"},{"db":"performance_schema","name":"session_status","obj_type":"TABLE"}],"query":"SHOW STATUS"}
{"msg-type":"activity","date":"1744100793485","thread-id":"3","query-id":"22","user":"root","priv_user":"root","ip":"172.16.200.200","host":"172.16.200.200","_os":"Windows","_client_name":"libmariadb","_pid":"27656","_thread":"32420","_platform":"AMD64","_client_version":"3.2.3","_server_host":"172.22.33.207","rows":"15","status":"0","cmd":"select","objects":[{"db":"information_schema","name":"/tmp/#sql_ef39_0","obj_type":"TABLE"}],"query":"SELECT QUERY_ID, SUM(DURATION) AS SUM_DURATION FROM INFORMATION_SCHEMA.PROFILING GROUP BY QUERY_ID"}
{"msg-type":"activity","date":"1744100793486","thread-id":"3","query-id":"23","user":"root","priv_user":"root","ip":"172.16.200.200","host":"172.16.200.200","_os":"Windows","_client_name":"libmariadb","_pid":"27656","_thread":"32420","_platform":"AMD64","_client_version":"3.2.3","_server_host":"172.22.33.207","rows":"11","status":"0","cmd":"select","objects":[{"db":"information_schema","name":"/tmp/#sql_ef39_0","obj_type":"TABLE"}],"query":"SELECT STATE AS `Status`, ROUND(SUM(DURATION),7) AS `Duration`, CONCAT(ROUND(SUM(DURATION)/0.007988*100,3), '') AS `Percentage` FROM INFORMATION_SCHEMA.PROFILING WHERE QUERY_ID=5 GROUP BY SEQ, STATE ORDER BY SEQ"}
Mysql-Audit 插件配置文件说明
默认情况下,安装后 AUDIT 插件不会记录活动。您必须显式启用所需的日志记录类型。通过使用 MySQL 系统变量完成配置。AUDIT 插件系统变量可以在服务器启动时使用命令行或 MySQL 选项文件([mysqld] 部分的 my.cnf)中的选项进行设置。此外,大多数 AUDIT Plugin 系统变量都可以在服务器运行时通过 SET 语句动态更改。
官方的参数写的很清楚,我这里就不搬运了😊
分割Mysql-Audit 插件日志
-
日志轮转使用logrotate工具定时来分割
cat > /etc/logrotate.d/audit << EOF
/home/application/mysql/logs/mysql-audit.json{
create 600 mysql mysql
missingok
daily
copytruncate
rotate 180
notifempty
compress
dateext
}
EOF -
模拟第一次日志分割
[root@localhost logs]# /usr/sbin/logrotate -f /etc/logrotate.d/audit
[root@localhost logs]# ll
-rw------- 1 mysql mysql 0 4月 8 17:09 mysql-audit.json
-rw------- 1 mysql mysql 187 4月 8 17:09 mysql-audit.json-20250408.gz -
模拟第二次日志分割,调整时间为后一天
#查看当前时间
[root@localhost logs]# date
2025年 04月 08日 星期三 17:13:19 CST#调整时间为后一天
[root@localhost logs]# date -s "2025-04-09 01:00:00"#再次手动分割日志
[root@localhost logs]# /usr/sbin/logrotate -f /etc/logrotate.d/audit[root@localhost logs]# ll
总用量 5988
-rw------- 1 mysql mysql 2520 4月 9 01:02 mysql-audit.json
-rw------- 1 mysql mysql 187 4月 8 17:09 mysql-audit.json-20250408.gz
-rw------- 1 mysql mysql 270 4月 8 17:12 mysql-audit.json-20250409.gz -
配置定时任务,每五分钟检查一次
[root@localhost logs]# crontab -l
*/5 * * * * /usr/sbin/logrotate -f /etc/logrotate.d/audit
Mysql-Audit 插件卸载
需要在 my.cnf 中 [mysqld] 下添加 audit_uninstall_plugin=1,重启mysql。重启完毕后执行两次 UNINSTALL PLUGIN AUDIT; 即可卸载。
> UNINSTALL PLUGIN AUDIT;
ERROR 1620 (HY000): Uninstall AUDIT plugin must be called again to complete
> UNINSTALL PLUGIN AUDIT;
Query OK, 0 rows affected, 1 warning (0.01 sec)
卸载完成后需要从 my.cnf 中删除 audit_uninstall_plugin=1 ,删除audit相关的配置文件
否则下次mysql启动会报错:[ERROR] /data/mysql/bin/mysqld: unknown variable 'audit_uninstall_plugin=1'
参考:
- Linux日志管理工具Logrotate:自动化轮转与最佳实践 https://srebro.cn/archives/1722926129042
- MySQL审计工具Audit Plugin安装使用 https://www.cnblogs.com/waynechou/p/mysql_audit.html#_label2