《MySQL 5.7.44审计合规实践:插件集成与日志分割自动化方案》

背景需求

很多时候项目上,需要过等保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'

参考:

相关推荐
红云梦39 分钟前
互联网三高-数据库高并发之分库分表
数据库·高并发·三高架构
王军新1 小时前
MySQL索引介绍
数据库·mysql
努力奋斗的小杨1 小时前
学习MySQL的第八天
数据库·笔记·学习·mysql·navicat
橘猫云计算机设计1 小时前
基于Python电影数据的实时分析可视化系统(源码+lw+部署文档+讲解),源码可白嫖!
数据库·后端·python·信息可视化·小程序·毕业设计
Another Iso1 小时前
MySQL 事务的优先级
数据库·mysql
爱的叹息2 小时前
JDK(Java Development Kit)从发布至今所有主要版本 的详细差异、新增特性及关键更新的总结,按时间顺序排列
java·数据库·python
永恒_顺其自然2 小时前
Oracle 复制表结构(含索引、主键)操作指南
数据库·oracle
lilye663 小时前
程序化广告行业(78/89):多因素交织下的行业剖析与展望
数据库·zookeeper·nosql
文牧之3 小时前
PostgreSQL 的统计信息
运维·数据库·postgresql
老李不敲代码3 小时前
榕壹云门店管理系统:基于Spring Boot+Mysql+UniApp的智慧解决方案
spring boot·后端·mysql·微信小程序·小程序·uni-app·软件需求