Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >技术分享 | MySQL 审计功能实现方案

技术分享 | MySQL 审计功能实现方案

作者头像
爱可生开源社区
发布于 2022-09-26 02:07:00
发布于 2022-09-26 02:07:00
2.7K00
代码可运行
举报
运行总次数:0
代码可运行

作者:刘聪

爱可生华东交付服务部 DBA 成员,专职 MySQL 故障处理及相关技术支持。座右铭:好好学习,天天向上。

本文来源:原创投稿

* 爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。


背景

鉴于目前MySQL审计需求不断深入扩张,以提高数据资产的安全,使得数据库愈来愈规范化管理,数据库实现审计功能成为必要安全环节。

众所周知,MySQL 社区版是不带审计插件的(Audit Plugin),那么该如何实现审计功能呢?我们自然会想到使用binlog日志做审计,因为binlog日志本就记录着数据库上的所有改变。但是无奈,binlog日志并不会记录用户的登录信息,所以无法做到真正意义上的审计。那使用general_log日志呢?

general_log日志可不仅记录着登录信息,甚至错误的登录信息、select等所有对数据库的操作都会记录着。也正是因为general_log日志记录得过于详细,不好做区分。且当并发访问量过大时,极大的占用空间,影响数据库的性能。所以也不会将之作为实现审计功能的工具。

本文将介绍如下三种方式,实现使用审计功能。

相关说明:本文所使用的工具版本

环境:MySQL - 5.7.25(社区版)

工具:

工具

获取源包名

MariaDB审计插件

mariadb-10.2.43-linux-systemd-x86_64

McAfee审计插件

audit-plugin-mysql-5.7-1.1.11-985-linux-x86_64.zip

init_connect 参数

相关说明

init_connect是社区版MySQL自带的参数。MySQL官方手册释义:“A string to be executed by the server for each client that connects. The string consists of one or more SQL statements, separated by semicolon characters.”

即:在连接客户端时刻,服务器要为每个连接,执行init_connect所定义的字符串。这个字符串可以由一个或多个 SQL 语句组成,以分号字符分隔。

那么该如何去利用这个参数呢?要实现审计功能,审计信息至少要包括登录MySQL的用户名、登录IP、登录时间等内容(谁在哪个时刻动了我的数据库啦!)。我们知道,init_connect参数所定义的字符串在登录连接时刻执行。如果我们提前创建一个表,并且把init_connect所定义的字符串写成insert语句(登录时刻,插入用户登录的信息)那么利用这个参数的特性,就可以实现简单的审计功能。

实现步骤

1、创建审计日志表

审计日志表记录内容包括:登录数据库的用户、IP、本次登录时间(审计必要信息);

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
CREATE TABLE `test_db`.`audit` (
  `ID` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增ID',
  `USER` varchar(64) COLLATE utf8mb4_bin NOT NULL COMMENT '登录用户名',
  `ADRESS` varchar(64) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '登录IP',
  `LOGIN_TIME` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '登录时间',
  PRIMARY KEY (`ID`),
  KEY `IDX_USER` (`USER`),
  KEY `IDX_HOST` (`ADRESS`),
  KEY `IDX_LOGIN_TIME` (`LOGIN_TIME`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='普通用户审计日志表';

2、对数据库中所有用户都授予审计日志表的权限

审计原理其实就是用户在登录时刻执行init_connect所指定的内容(对审计日志表进行insert操作),那么必须要求所有的用户都要有此表的insert权限才行。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
##为了文章的继续发展,注意这里并没有给普通用户'user_3'@'%'授权哦
mysql> select user,host from mysql.user;
+---------------+--------------+
| user          | host         |
+---------------+--------------+
| user_1        | %            |
| user_3        | %            |
| user_2        | 10.186.61.17 |
| mysql.session | localhost    |
| mysql.sys     | localhost    |
| root          | localhost    |
+---------------+--------------+
6 rows in set (0.00 sec)


mysql> grant insert on test_db.audit to 'user_1'@'%';
Query OK, 0 rows affected (0.01 sec)

mysql> grant insert on test_db.audit to 'user_2'@'10.186.61.17';
Query OK, 0 rows affected (0.01 sec)

3、动态设置,开启审计日志表

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
##动态设置init_connect参数
mysql> set global init_connect="insert into test_db.audit(USER,ADRESS) values(current_user(),substring_index(user(),'@',-1));";
Query OK, 0 rows affected (0.00 sec)

##补充说明current_user()可以查到当前登录的用户信息,substring_index()是一个截取函数,例如使用普通用户'user_2'@'10.186.61.17'
mysql> select current_user();
+---------------------+
| current_user()      |
+---------------------+
| user_2@10.186.61.17 |
+---------------------+
1 row in set (0.00 sec)
mysql> select substring_index(user(),'@',-1);
+--------------------------------+
| substring_index(user(),'@',-1) |
+--------------------------------+
| 10.186.61.17                   |
+--------------------------------+
1 row in set (0.00 sec)

为了永久生效,必须还要在配置文件中添加如下内容:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[mysqld]
init_connect="insert into test_db.audit(USER,ADRESS) values(current_user(),substring_index(user(),'@',-1));";

4、审计日志表结果说明

  1. 对于普通用户,需要提前被授予一定权限,否则不会被记录到审计日志表中,并且会导致连接失败('user_3'@'%'用户因为没有审计表的insert权限,所以没有被记录)。
  2. 对于普通用户,如果init_connect的内容有语法错误,依然会直接导致连接失败(无法执行init_connect的内容)。
  3. 对于具有super权限的用户,在登录时并不会执行init_connec的内容(所以审计日志表里也没有super用户的记录)。
  4. 对于密码过期的普通用户,登录数据库会直接连接失败,且不会记录也不会报错(无法执行init_connect的内容)。
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
##模拟对审计表有insert权限的普通用户登录数据库
[root@10-186-61-17 ~]# /data/mysql/3306/base/bin/mysql -uuser_2 -p -P6666 -h10.186.61.17
[root@10-186-61-17 ~]# /data/mysql/3306/base/bin/mysql -uuser_1 -p -P6666 -h10.186.61.17
[root@10-186-61-55 ~]# /data/mysql/3306/base/bin/mysql -uuser_1 -p -P6666 -h10.186.61.17

##模拟对审计表无insert权限的普通用户登录数据库
[root@10-186-61-17 ~]# /data/mysql/3306/base/bin/mysql -uuser_3 -p -P6666 -h10.186.61.17
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 10
Server version: 5.7.25-log

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show databases;
ERROR 2013 (HY000): Lost connection to MySQL server during query


##使用root用户登录查看审计日志表记录结果展示
[root@10-186-61-17 ~]# /data/mysql/3306/base/bin/mysql -uroot -p -S /data/mysql/6666/data/mysqld.sock
Enter password:
……
mysql> select * from test_db.audit;
+----+---------------------+--------------+---------------------+
| ID | USER                | ADRESS       | LOGIN_TIME          |
+----+---------------------+--------------+---------------------+
|  1 | user_2@10.186.61.17 | 10.186.61.17 | 2022-05-26 14:17:35 |
|  2 | user_1@%            | 10.186.61.17 | 2022-05-26 14:18:12 |
|  3 | user_1@%            | 10.186.61.55 | 2022-05-26 14:19:34 |
+----+---------------------+--------------+---------------------+
3 rows in set (0.02 sec)
小结

优点

  1. 实现原理和操作步骤简单;
  2. 几乎不影响MySQL性能。

缺点

  1. 记录的内容简略(仅记录登录时刻执行init_connect所定义插入的值);
  2. 只记录登入行为,不记录登录数据库后的行为;
  3. 不会记录有super权限的用户的登录行为;
  4. 密码过期的用户登录数据库,会直接连接失败,且不会记录也不会报错。

MariaDB审计插件

相关说明

MariaDB 开发的 MariaDB 审计插件,虽然具有一些仅适用于MariaDB的独特功能,但它也可以与 MySQL一起使用。MariaDB 审计插件所生成的审计日志记录内容包括:用户名和主机、执行了哪些查询、访问了哪些表以及更改了服务器变量等详情信息,下面一起来看看吧。

实现步骤

1、获取MariaDB的审计插件—— server_audit.so

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
##下载MariaDB Server安装包
##下载地址:https://mariadb.org/download/?t=mariadb&p=mariadb&r=10.2.43&os=Linux&cpu=x86_64&i=systemd&m=bkns
##本地解压后,在解压目录下找到审计插件`server_audit.so`
./mariadb/mariadb-10.2.43-linux-systemd-x86_64/lib/plugin/server_audit.so

2、将审计插件 server_audit.so复制到MySQL的plugin目录下,并授权

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
cp ./mariadb/mariadb-10.2.43-linux-systemd-x86_64/lib/plugin/server_audit.so /data/mysql/3306/base/lib/plugin/
chown -R mysql:mysql server_audit.so
chmod 755 server_audit.so

3、进入MySQL客户端,安装插件

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
##install审计插件
mysql> install plugin server_audit soname 'server_audit.so';
Query OK, 0 rows affected (0.07 sec)

##查看当前的插件信息
mysql> show plugins;
+----------------------------+----------+--------------------+--------------------+---------+
| Name                       | Status   | Type               | Library            | License |
+----------------------------+----------+--------------------+--------------------+---------+
 ……
| ngram                      | ACTIVE   | FTPARSER           | NULL               | GPL     |
| rpl_semi_sync_master       | ACTIVE   | REPLICATION        | semisync_master.so | GPL     |
| rpl_semi_sync_slave        | ACTIVE   | REPLICATION        | semisync_slave.so  | GPL     |
| SERVER_AUDIT               | ACTIVE   | AUDIT              | server_audit.so    | GPL     |
+----------------------------+----------+--------------------+--------------------+---------+
47 rows in set (0.00 sec)

4、配置说明

当安装完审计插件之后,MySQL中将有一些新的全局变量出现。这些变量就是用于配置审计日志的,例如配置审计日志的位置、日志大小、记录的信息格式等。查看相关变量:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mysql> show variables like '%server_audit%';
+-------------------------------+-----------------------+
| Variable_name                 | Value                 |
+-------------------------------+-----------------------+
| server_audit_events           |                       |
| server_audit_excl_users       |                       |
| server_audit_file_path        | server_audit.log      |
| server_audit_file_rotate_now  | OFF                   |
| server_audit_file_rotate_size | 1000000               |
| server_audit_file_rotations   | 9                     |
| server_audit_incl_users       |                       |
| server_audit_loc_info         |                       |
| server_audit_logging          | OFF                   |
| server_audit_mode             | 1                     |
| server_audit_output_type      | file                  |
| server_audit_query_log_limit  | 1024                  |
| server_audit_syslog_facility  | LOG_USER              |
| server_audit_syslog_ident     | mysql-server_auditing |
| server_audit_syslog_info      |                       |
| server_audit_syslog_priority  | LOG_INFO              |
+-------------------------------+-----------------------+
16 rows in set (0.01 sec)

部分变量说明:

变量名

获取源包名

server_audit_logging

控制审计功能的开关;

server_audit_events

指定记录的事件类型;如果设置指定值,则审核日志只记录在设定值范围内的事件类型; 如果未设置,则每个事件类型都会记录到审核日志中(默认值选项)。

server_audit_file_path

当server_audit_output_type=file时,设置日志文件的路径和文件名;默认文件路径为datadir,默认文件名为server_audit.log 。

server_audit_file_rotate_now

手工触发审计日志轮换;即:设置为 ON 或 1 来强制日志文件轮换。

server_audit_file_rotate_size

日志大小限制,达到了阈值,审计日志会自动轮换。

server_audit_file_rotations

指定轮换后所保留的日志文件个数;如果设置为 0,则日志永远不会轮换;默认值为 9,即保存最多9个审计日志。

server_audit_incl_users

指定用户列表,在内的用户,将被记录;注:CONNECT 记录不受此变量的影响。

server_audit_excl_users

指定用户列表,在内的用户,不会被记录;如果用户在server_audit_incl_users中也指定了,用户活动仍会被记录;注:CONNECT 记录不受此变量的影响。

server_audit_query_log_limit

限制记录中查询字符串的长度。

配置示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
##开启审计功能
mysql> SET GLOBAL server_audit_logging=ON;

##指定记录内容‘connect,query’,记录用户的连接和查询语句
SET global server_audit_events='connect,query';
##重命名审计日志
mysql> set global server_audit_file_path='mysql_3306_audit.log';

为了永久生效,必须还要在配置文件中添加如下内容:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
##这里仅定义了两项变量值供参考
[server]
server_audit_logging=ON
server_audit_events=connect,query
…

5、审计日志结果说明

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
##模拟相关操作(查询结果篇幅过长,省略部分内容)
mysql> show databases;
mysql> use test;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> show tables;
mysql> select count(*) from sbtest1;
mysql> select * from sbtest1 limit 3;
+----+--------+-------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------+
| id | k      | c                                                                                                                       | pad                                                         |
+----+--------+-------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------+
|  1 | 498670 | 31451373586-15688153734-79729593694-96509299839-83724898275-86711833539-78981337422-35049690573-51724173961-87474696253 | 98996621624-36689827414-04092488557-09587706818-65008859162 |
|  2 | 497778 | 21472970079-70972780322-70018558993-71769650003-09270326047-32417012031-10768856803-14235120402-93989080412-18690312264 | 04776826683-45880822084-77922711547-29057964468-76514263618 |
|  3 | 498956 | 49376827441-24903985029-56844662308-79012577859-40518387141-60588419212-24399130405-42612257832-29494881732-71506024440 | 26843035807-96849339132-53943793991-69741192222-48634174017 |
+----+--------+-------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------+
3 rows in set (0.00 sec)
mysql> exit
Bye

[root@10-186-65-155 plugin]# /data/mysql/3306/base/bin/mysql -utest -p -S /data/mysql/3306/data/mysqld.sock
Enter password:
mysql> show databases;
mysql> use occdb
mysql> show tables;
mysql> create table abc like occ_application_config;
Query OK, 0 rows affected (10.09 sec)
mysql> exit
Bye

##查看datadir下审计日志文件
[root@10-186-65-155 data]# cd /data/mysql/3306/data/ && ll -h | grep 'audit.log'
-rw-r----- 1 mysql mysql  711 Apr 19 15:30 mysql_3306_audit.log
-rw-r----- 1 mysql mysql  329 Apr 19 15:26 server_audit.log

##查看审计日志`mysql_3306_audit.log`记录的内容
20220419 15:26:04,10-186-65-155,root,localhost,6,6,QUERY,,'set global server_audit_file_path=\'mysql_3306_audit.log\'',0
20220419 15:29:30,10-186-65-155,root,localhost,6,7,QUERY,,'show databases',0
20220419 15:29:38,10-186-65-155,root,localhost,6,8,QUERY,,'SELECT DATABASE()',0
20220419 15:29:38,10-186-65-155,root,localhost,6,10,QUERY,test,'show databases',0
20220419 15:29:38,10-186-65-155,root,localhost,6,11,QUERY,test,'show tables',0
20220419 15:29:43,10-186-65-155,root,localhost,6,17,QUERY,test,'show tables',0
20220419 15:30:04,10-186-65-155,root,localhost,6,18,QUERY,test,'select count(*) from sbtest1',0
20220419 15:30:25,10-186-65-155,root,localhost,6,19,QUERY,test,'select * from sbtest1 limit 3',0
20220419 15:36:14,10-186-65-155,root,localhost,6,0,DISCONNECT,test,,0
20220419 15:36:24,10-186-65-155,test,localhost,7,0,CONNECT,,,0
20220419 15:36:24,10-186-65-155,test,localhost,7,21,QUERY,,'select @@version_comment limit 1',0
20220419 15:36:28,10-186-65-155,test,localhost,7,22,QUERY,,'show databases',0
20220419 15:36:36,10-186-65-155,test,localhost,7,23,QUERY,,'SELECT DATABASE()',0
20220419 15:36:36,10-186-65-155,test,localhost,7,25,QUERY,occdb,'show databases',0
20220419 15:36:36,10-186-65-155,test,localhost,7,26,QUERY,occdb,'show tables',0
20220419 15:36:39,10-186-65-155,test,localhost,7,28,QUERY,occdb,'show tables',0
20220419 15:36:55,10-186-65-155,test,localhost,7,29,QUERY,occdb,'create table abc like occ_application_config',0
20220419 15:37:11,10-186-65-155,test,localhost,7,0,DISCONNECT,occdb,,0

补充:下发的错误语句,或者连接失败等语句,审计日志依然会记录在内。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
##模拟错误语句和连接失败情景
mysql> show creates table abc;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'creates table abc' at line 1
mysql> exit
Bye
[root@10-186-65-155 plugin]# /data/mysql/3306/base/bin/mysql -utest -p -S /data/mysql/3306/data/mysqld.sock
Enter password:
ERROR 1045 (28000): Access denied for user 'test'@'localhost' (using password: NO)

##查看审计日志记录的相关内容
……
20220419 15:42:16,10-186-65-155,test,localhost,9,45,QUERY,occdb,'show creates table abc',1064
20220419 15:42:34,10-186-65-155,test,localhost,9,0,DISCONNECT,occdb,,0
20220419 15:42:48,10-186-65-155,test,localhost,10,0,FAILED_CONNECT,,,1045

根据以上记录的内容可以总结审计日志的记录格式:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[timestamp],[serverhost],[username],[host],[connectionid],[queryid],[operation],[database],[object],[retcode]
小结

优点

  1. 使用xml格式和内容明确且详细;
  2. 审计粒度细:例如可通过server_audit_events和server_audit_incl_users等参数指定需要审计的内容;
  3. 审计日志维护管理方便:自带审计日志切割轮换参数;
  4. 审计日志会记录下发的错误语句、连接失败信息等。

缺点

  1. 对MySQL性能有一定影响。

McAfee审计插件

相关说明

所属McAfee公司McAfee审计插件,专门为 MySQL 提供审计功能。其设计重点是安全和审计要求。可以独立的作为审计插件,实现MySQL的审计功能,实现步骤与MariaDB 审计插件类似。

实现步骤

1、获取审计插件——libaudit_plugin.so

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
##下载插件
##下载地址:https://github.com/mcafee/mysql-audit/releases
##本地解压后,在解压目录下找到审计插件libaudit_plugin.so
./audit-plugin-mysql-5.7-1.1.11-985/lib/libaudit_plugin.so

2、将审计插件server_audit.so复制到MySQL的plugin目录下,并授权

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
cp ./audit-plugin-mysql-5.7-1.1.11-985/lib/libaudit_plugin.so /data/mysql/6666/base/lib/plugin/
chown -R mysql:mysql libaudit_plugin.so
chmod 755 libaudit_plugin.so

3、进入MySQL客户端,安装插件

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mysql> INSTALL PLUGIN AUDIT SONAME 'libaudit_plugin.so';
Query OK, 0 rows affected (1.08 sec)
 
mysql> show plugins;
+----------------------------+----------+--------------------+--------------------+---------+
| Name                       | Status   | Type               | Library            | License |
+----------------------------+----------+--------------------+--------------------+---------+
……
| rpl_semi_sync_master       | ACTIVE   | REPLICATION        | semisync_master.so | GPL     |
| rpl_semi_sync_slave        | ACTIVE   | REPLICATION        | semisync_slave.so  | GPL     |
| AUDIT                      | ACTIVE   | AUDIT              | libaudit_plugin.so | GPL     |
+----------------------------+----------+--------------------+--------------------+---------+
47 rows in set (0.00 sec)

4、配置说明

同Mariadb的审计插件类似,当安装完审计插件之后,MySQL中将有一些新的全局变量,用于配置审计日志相关属性。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mysql> show variables like '%audit%';
+---------------------------------+-----------------------------------------------------------------------------------------------                  
| Variable_name                   | Value                                                                                                           
+---------------------------------+-----------------------------------------------------------------------------------------------                  
| audit_before_after              | after                                                                                                           
| audit_checksum                  |                                                                                                                 
| audit_client_capabilities       | OFF                                                                                                             
| audit_delay_cmds                |                                                                                                                 
| audit_delay_ms                  | 0                                                                                                               
| audit_force_record_logins       | OFF                                                                                                             
| audit_header_msg                | ON                                                                                                              
| audit_json_file                 | OFF                                                                                                             
| audit_json_file_bufsize         | 1                                                                                                               
| audit_json_file_flush           | OFF                                                                                                             
| audit_json_file_retry           | 60                                                                                                              
| audit_json_file_sync            | 0                                                                                                               
| audit_json_log_file             | mysql-audit.json                                                                                                
| audit_json_socket               | OFF                                                                                                             
| audit_json_socket_name          | /var/run/db-audit/mysql.audit__data_mysql_6666_data_6666                                                        
| audit_json_socket_retry         | 10                                                                                                              
| audit_json_socket_write_timeout | 1000                                                                                                            
| audit_offsets                   |                                                                                                                 
| audit_offsets_by_version        | ON                                                                                                              
| audit_password_masking_cmds     | CREATE_USER,GRANT,SET_OPTION,SLAVE_START,CREATE_SERVER,ALTER_SERVER,CHANGE_MASTER,UPDATE                        
| audit_password_masking_regex    | 
| audit_record_cmds               |                                                                                                                 
| audit_record_objs               |                                                                                                                 
| audit_sess_connect_attrs        | ON                                                                                                              
| audit_socket_creds              | ON                                                                                                              
| audit_uninstall_plugin          | OFF                                                                                                             
| audit_validate_checksum         | ON                                                                                                              
| audit_validate_offsets_extended | ON                                                                                                              
| audit_whitelist_cmds            | BEGIN,COMMIT,PING                                                                                               
| audit_whitelist_users           |                                                                                                                 
+---------------------------------+-----------------------------------------------------------------------------------------------                  
30 rows in set (0.01 sec)

部分变量说明:

变量名

获取源包名

audit_json_file

是否开启审计 ON/OFF;默认值:OFF。

audit_json_log_file

设置日志文件的路径和文件名;默认值:mysql-audit.json,默认路径:datadir。

audit_record_cmds

设置要记录的语句类型,例如:insert,update,delete ;默认记录所有的命令。

audit_record_objs

设置要记录到审计跟踪的对象(表),例如:database.table,可以使用通配符。

audit_whitelist_cmds

设置不需要记录的语句类型。

audit_whitelist_users

设置不需要记录的用户。

audit_before_after

控制是在执行当前 SQL 语句之前还是之后写入其日志记录,或两者兼而有之。可能的值为'before'、'after'或'both',默认为'after'。

audit_json_file_flush

手工进行轮换日志。

audit_json_file_sync

控制日志刷写周期json,如果此变量的值为N(N≠0),则审计日志将在每N次写入后同步到磁盘。默认值:0 。

配置示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mysql> set global audit_json_file=on;
Query OK, 0 rows affected (0.01 sec)

mysql> set global audit_json_log_file='mysql_6666_audit.log';
Query OK, 0 rows affected (0.00 sec)

为了永久生效,必须还要在配置文件中添加如下内容:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
##这里仅定义了两项变量值供参考
[mysqld]
audit_json_file=on
audit_record_cmds='query_type'  ##自定义需要记录的语句类型
……

5、审计日志结果说明

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
##模拟相关操作(查询结果篇幅过长,省略部分内容)
[root@10-186-65-155 plugin]# /data/mysql/6666/base/bin/mysql -uroot -p -S /data/mysql/6666/data/mysqld.sock
Enter password:
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show databases;
mysql> select count(*) from mysql.user;
mysql> create database test;
mysql> use test;
Database changed
mysql> create table aaa(id int,name varchar(20),primary key(id));
mysql> insert into aaa values (1,'zhangsan'),(2,'lisi');
mysql> exit
Bye
[root@10-186-65-155 plugin]# /data/mysql/6666/base/bin/mysql -utest -p -S /data/mysql/6666/data/mysqld.sock
Enter password:
mysql> use test;
mysql> select * from aaa;
+----+----------+
| id | name     |
+----+----------+
|  1 | zhangsan |
|  2 | lisi     |
+----+----------+

 ##查看datadir下的审计日志记录内容
 {"msg-type":"activity","date":"1650361253128","thread-id":"11","query-id":"0","user":"root","priv_user":"root","ip":"","host":"localhost","_os":"linux-glibc2.12","_client_name":"libmysql","_pid":"5151","_client_version":"5.7.25","_platform":"x86_64","program_name":"mysql","pid":"5151","os_user":"root","appname":"/data/mysql/6666/base/bin/mysql","cmd":"Connect","query":"Connect"}
{"msg-type":"activity","date":"1650361253129","thread-id":"11","query-id":"145","user":"root","priv_user":"root","ip":"","host":"localhost","_os":"linux-glibc2.12","_client_name":"libmysql","_pid":"5151","_client_version":"5.7.25","_platform":"x86_64","program_name":"mysql","pid":"5151","os_user":"root","appname":"/data/mysql/6666/base/bin/mysql","rows":"1","status":"0","cmd":"select","query":"select @@version_comment limit 1"}
{"msg-type":"activity","date":"1650361255866","thread-id":"11","query-id":"146","user":"root","priv_user":"root","ip":"","host":"localhost","_os":"linux-glibc2.12","_client_name":"libmysql","_pid":"5151","_client_version":"5.7.25","_platform":"x86_64","program_name":"mysql","pid":"5151","os_user":"root","appname":"/data/mysql/6666/base/bin/mysql","rows":"4","status":"0","cmd":"show_databases","objects":[{"db":"information_schema","name":"/data/mysql/6666/tmp/#sql_1b0f_0","obj_type":"TABLE"}],"query":"show databases"}
{"msg-type":"activity","date":"1650361283561","thread-id":"11","query-id":"147","user":"root","priv_user":"root","ip":"","host":"localhost","_os":"linux-glibc2.12","_client_name":"libmysql","_pid":"5151","_client_version":"5.7.25","_platform":"x86_64","program_name":"mysql","pid":"5151","os_user":"root","appname":"/data/mysql/6666/base/bin/mysql","rows":"1","status":"0","cmd":"select","objects":[{"db":"mysql","name":"user","obj_type":"TABLE"}],"query":"select count(*) from mysql.user"}
{"msg-type":"activity","date":"1650361313234","thread-id":"11","query-id":"148","user":"root","priv_user":"root","ip":"","host":"localhost","_os":"linux-glibc2.12","_client_name":"libmysql","_pid":"5151","_client_version":"5.7.25","_platform":"x86_64","program_name":"mysql","pid":"5151","os_user":"root","appname":"/data/mysql/6666/base/bin/mysql","status":"0","cmd":"create_db","query":"create database test"}
{"msg-type":"activity","date":"1650361318055","thread-id":"11","query-id":"149","user":"root","priv_user":"root","ip":"","host":"localhost","_os":"linux-glibc2.12","_client_name":"libmysql","_pid":"5151","_client_version":"5.7.25","_platform":"x86_64","program_name":"mysql","pid":"5151","os_user":"root","appname":"/data/mysql/6666/base/bin/mysql","rows":"1","status":"0","cmd":"select","query":"SELECT DATABASE()"}
{"msg-type":"activity","date":"1650361318055","thread-id":"11","query-id":"150","user":"root","priv_user":"root","ip":"","host":"localhost","_os":"linux-glibc2.12","_client_name":"libmysql","_pid":"5151","_client_version":"5.7.25","_platform":"x86_64","program_name":"mysql","pid":"5151","os_user":"root","appname":"/data/mysql/6666/base/bin/mysql","rows":"1","status":"0","cmd":"Init DB","objects":[{"db":"test","obj_type":"DATABASE"}],"query":"Init DB"}
{"msg-type":"activity","date":"1650361318057","thread-id":"11","query-id":"151","user":"root","priv_user":"root","ip":"","host":"localhost","_os":"linux-glibc2.12","_client_name":"libmysql","_pid":"5151","_client_version":"5.7.25","_platform":"x86_64","program_name":"mysql","pid":"5151","os_user":"root","appname":"/data/mysql/6666/base/bin/mysql","rows":"5","status":"0","cmd":"show_databases","objects":[{"db":"information_schema","name":"/data/mysql/6666/tmp/#sql_1b0f_0","obj_type":"TABLE"}],"query":"show databases"}
{"msg-type":"activity","date":"1650361318057","thread-id":"11","query-id":"152","user":"root","priv_user":"root","ip":"","host":"localhost","_os":"linux-glibc2.12","_client_name":"libmysql","_pid":"5151","_client_version":"5.7.25","_platform":"x86_64","program_name":"mysql","pid":"5151","os_user":"root","appname":"/data/mysql/6666/base/bin/mysql","status":"0","cmd":"show_tables","objects":[{"db":"information_schema","name":"/data/mysql/6666/tmp/#sql_1b0f_0","obj_type":"TABLE"}],"query":"show tables"}
{"msg-type":"activity","date":"1650361361491","thread-id":"11","query-id":"153","user":"root","priv_user":"root","ip":"","host":"localhost","_os":"linux-glibc2.12","_client_name":"libmysql","_pid":"5151","_client_version":"5.7.25","_platform":"x86_64","program_name":"mysql","pid":"5151","os_user":"root","appname":"/data/mysql/6666/base/bin/mysql","status":"0","cmd":"create_table","objects":[{"db":"test","name":"aaa","obj_type":"TABLE"}],"query":"create table aaa(id int,name varchar(20),primary key(id))"}
{"msg-type":"activity","date":"1650361424702","thread-id":"11","query-id":"154","user":"root","priv_user":"root","ip":"","host":"localhost","_os":"linux-glibc2.12","_client_name":"libmysql","_pid":"5151","_client_version":"5.7.25","_platform":"x86_64","program_name":"mysql","pid":"5151","os_user":"root","appname":"/data/mysql/6666/base/bin/mysql","rows":"2","status":"0","cmd":"insert","objects":[{"db":"test","name":"aaa","obj_type":"TABLE"}],"query":"insert into aaa values (1,'zhangsan'),(2,'lisi')"}
{"msg-type":"activity","date":"1650361432156","thread-id":"11","query-id":"155","user":"root","priv_user":"root","ip":"","host":"localhost","_os":"linux-glibc2.12","_client_name":"libmysql","_pid":"5151","_client_version":"5.7.25","_platform":"x86_64","program_name":"mysql","pid":"5151","os_user":"root","appname":"/data/mysql/6666/base/bin/mysql","cmd":"Quit","query":"Quit"}
{"msg-type":"activity","date":"1650361439497","thread-id":"12","query-id":"0","user":"test","priv_user":"test","ip":"","host":"localhost","_os":"linux-glibc2.12","_client_name":"libmysql","_pid":"5162","_client_version":"5.7.25","_platform":"x86_64","program_name":"mysql","pid":"5162","os_user":"root","appname":"/data/mysql/6666/base/bin/mysql","cmd":"Connect","query":"Connect"}
{"msg-type":"activity","date":"1650361439498","thread-id":"12","query-id":"156","user":"test","priv_user":"test","ip":"","host":"localhost","_os":"linux-glibc2.12","_client_name":"libmysql","_pid":"5162","_client_version":"5.7.25","_platform":"x86_64","program_name":"mysql","pid":"5162","os_user":"root","appname":"/data/mysql/6666/base/bin/mysql","rows":"1","status":"0","cmd":"select","query":"select @@version_comment limit 1"}
{"msg-type":"activity","date":"1650361443135","thread-id":"12","query-id":"157","user":"test","priv_user":"test","ip":"","host":"localhost","_os":"linux-glibc2.12","_client_name":"libmysql","_pid":"5162","_client_version":"5.7.25","_platform":"x86_64","program_name":"mysql","pid":"5162","os_user":"root","appname":"/data/mysql/6666/base/bin/mysql","rows":"1","status":"0","cmd":"select","query":"SELECT DATABASE()"}
{"msg-type":"activity","date":"1650361443136","thread-id":"12","query-id":"158","user":"test","priv_user":"test","ip":"","host":"localhost","_os":"linux-glibc2.12","_client_name":"libmysql","_pid":"5162","_client_version":"5.7.25","_platform":"x86_64","program_name":"mysql","pid":"5162","os_user":"root","appname":"/data/mysql/6666/base/bin/mysql","rows":"1","status":"0","cmd":"Init DB","objects":[{"db":"test","obj_type":"DATABASE"}],"query":"Init DB"}
{"msg-type":"activity","date":"1650361443138","thread-id":"12","query-id":"159","user":"test","priv_user":"test","ip":"","host":"localhost","_os":"linux-glibc2.12","_client_name":"libmysql","_pid":"5162","_client_version":"5.7.25","_platform":"x86_64","program_name":"mysql","pid":"5162","os_user":"root","appname":"/data/mysql/6666/base/bin/mysql","rows":"5","status":"0","cmd":"show_databases","objects":[{"db":"information_schema","name":"/data/mysql/6666/tmp/#sql_1b0f_0","obj_type":"TABLE"}],"query":"show databases"}
{"msg-type":"activity","date":"1650361443139","thread-id":"12","query-id":"160","user":"test","priv_user":"test","ip":"","host":"localhost","_os":"linux-glibc2.12","_client_name":"libmysql","_pid":"5162","_client_version":"5.7.25","_platform":"x86_64","program_name":"mysql","pid":"5162","os_user":"root","appname":"/data/mysql/6666/base/bin/mysql","rows":"1","status":"0","cmd":"show_tables","objects":[{"db":"information_schema","name":"/data/mysql/6666/tmp/#sql_1b0f_0","obj_type":"TABLE"}],"query":"show tables"}
{"msg-type":"activity","date":"1650361454500","thread-id":"12","query-id":"162","user":"test","priv_user":"test","ip":"","host":"localhost","_os":"linux-glibc2.12","_client_name":"libmysql","_pid":"5162","_client_version":"5.7.25","_platform":"x86_64","program_name":"mysql","pid":"5162","os_user":"root","appname":"/data/mysql/6666/base/bin/mysql","rows":"2","status":"0","cmd":"select","objects":[{"db":"test","name":"aaa","obj_type":"TABLE"}],"query":"select * from aaa"}

根据以上的记录内容可总结审计日志的记录格式:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
审计日志使用的是json格式记录,如下为一条记录内容
{
	"msg-type": "activity",
	"date": "1650361454500",
	"thread-id": "12",
	"query-id": "162",
	"user": "test",
	"priv_user": "test",
	"ip": "",
	"host": "localhost",
	"_os": "linux-glibc2.12",
	"_client_name": "libmysql",
	"_pid": "5162",
	"_client_version": "5.7.25",
	"_platform": "x86_64",
	"program_name": "mysql",
	"pid": "5162",
	"os_user": "root",
	"appname": "/data/mysql/6666/base/bin/mysql",
	"rows": "2",
	"status": "0",
	"cmd": "select",
	"objects": [{
		"db": "test",
		"name": "aaa",
		"obj_type": "TABLE"
	}],
	"query": "select * from aaa"
}
小结

优点:

  1. 使用json格式和内容明确且详细;
  2. 审计粒度细:例如可通过audit_record_cmds和audit_record_objs等指定需要审计的内容;
  3. 记录连接失败的语句(audit_force_record_logins参数值为on条件下);
  4. 审计日志刷写策略可控,可通过audit_json_file_sync参数控制。

缺点:

  1. 对MySQL性能有一定影响;
  2. 不记录下发错误的语句;
  3. 审计日志维护管理不便,无自带审计日志切割轮换参数。
补充说明:

Percona 公司开发的审计插件 audit_log.so(可以在Percona Server包中获取),目前无法直接install到社区版MySQL中使用。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mysql> INSTALL PLUGIN audit_log SONAME 'audit_log.so';
ERROR 1126 (HY000): Can't open shared library '/data/mysql/7777/base/lib/plugin/audit_log.so' (errno: 2 /data/mysql/7777/base/lib/plugin/audit_log.so: undefined symbol: plugin_thdvar_safe_update)

结束语

本文介绍了三种实现审计功能的方案,各个方案都有自己的优缺点。如果仅仅记录普通用户的登录信息就能够满足审计需求,那就选择第一种方案(init_connect参数)再好不过了。如果想要实现更全面的审计功能,那么第二种或者第三种方案会更加合适。总之,根据审计需求来选择自己认为最合适的方案吧。另外,在实际使用之前,请务必做好充分的测试工作!

本文关键字:#审计#

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-06-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 爱可生开源社区 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
利用开源审计插件对mysql进行审计
假设这么一个情况,你是某公司mysql DBA,某日突然公司数据库中的所有被人为删了。尽管有数据备份,但是因服务停止而造成的损失上千万,现在公司需要查出那个做删除操作的人。
SEian.G
2021/03/03
3.2K0
等保测评2.0:MySQL安全审计
虽然遇到这些插件的概率不高,我还是把这些插件的基本参数都列出来,到时候如果真遇到了,也不至于一头雾水。
FB客服
2020/03/24
6K0
等保测评2.0:MySQL安全审计
MySQL审计插件使用和对比
数据库审计是数据库安全中很重要的一个环节,说到审计,有些上市公司内部还会根据塞班斯法案,进行404审计等等。 而最基本的审计还是需要的,有些同学可能感觉审计会有些鸡肋,其实非也,开审计的功能势必会影响性能,如果不开又会有遗漏,这种防患于未然,把问题都扼杀在摇篮之中,通过这种规范和制度来做最后一道防线。 MySQL中也需要审计,不说大的方向,就说和我们工作更贴近的,比如某一个业务在某个时间点出现了异常,因为异常操作(比如DDL)导致系统出现了严重的问题,这个时候如果要查看这个问题的具体情
jeanron100
2018/03/22
4K0
MySQL审计插件使用和对比
MySQL监视——审计日志
MySQL的企业版中提供了审计日志功能。通过审计日志可以记录用户的登录、连接、执行的查询等行为,输出XML格式或者JSON格式的日志文件。
MySQLSE
2023/08/31
1K0
MySQL监视——审计日志
hhdb数据库介绍(9-21)
控制节点切换前是否先判断集群所有成员都能ping通,true开启false关闭。 例:A机房和B机房构成双活集群,A机房3个计算节点,B机房2个计算节点,primary节点在B机房。AB机房网络隔离后,A机房做为多数派会选出主,B机房无法形成多数派而cluster shutdown,但是在B机房primary未下线时,收到A机房主存储节点的心跳超时导致存储节点发生切换(开启此参数可避免此类情况)。
恒辉信达
2024/12/03
1170
hhdb数据库介绍(9-26)
启动时,主存储节点在首次初始化失败后,会一直重连;若存在备存储节点且超过主存储节点初始化超时时间,则会切换到可用的备存储节点,若该节点所有存储节点都初始化失败,则整个节点不可用。如果数据节点初始化失败且无可用逻辑库,或数据节点下无存储节点,则计算节点无法启动。
恒辉信达
2024/12/03
950
MySQL安全插件-数据库审计
数据库审计(简称DBAudit)能够实时记录网络上的数据库活动,对数据库操作进行细粒度审计的合规性管理,对数据库遭受到的风险行为进行告警,对攻击行为进行阻断。它通过对用户访问数据库行为的记录、分析和汇报,用来帮助用户事后生成合规报告、事故追根溯源,同时加强内外部数据库网络行为记录,提高数据资产安全。
Power
2025/03/01
6280
mysql审计开启–两种方法
这里使用的是macfee的mysql audit插件,虽然日志信息比较大,对性能影响大,但是如果想要开启审计,那也应该忍受了。介绍几个参考地址:
全栈程序员站长
2022/07/20
2.4K0
技术分享 | 细说 MySQL 用户安全加固策略
作者:官永强,爱可生 DBA 团队成员,擅长 MySQL 运维方面的技能。热爱学习新知识,亦是个爱打游戏的宅男。
爱可生开源社区
2023/12/20
4590
技术分享 | 细说 MySQL 用户安全加固策略
hhdb数据库介绍(9-22)
用于设置数据节点空闲检查的定时任务的时间。计算节点会定时检查后端存储节点连接情况,关闭多余的空闲连接或者补足连接池的可用连接,保持连接不被存储节点关闭,维护连接池的正常运作。
恒辉信达
2024/12/03
940
四十八、审计功能
审计是数据库安全中很重要的一个环节,它能够实时记录数据库的操作,帮助数据库管理员对数据库异常行为进行分析审计。审计会详细记录谁在什么时间执行了什么操作。MySQL 社区版没有自带的审计功能或插件,只有 MySQL 商业版中有审计功能。审计记录的日志如下:
喵叔
2021/07/14
4470
【MySQL】MySQL审计操作记录
简介: 数据库审计能够实时记录网络上的数据库活动,对数据库操作进行细粒度审计的合规性管理,对数据库受到的风险行为进行告警,对攻击行为进行阻断,它通过对用户访问数据库行为的记录、分析和汇报,用来帮助用户事后生成合规报告、事故追根溯源,同时加强内外部数据库网络行为记录,提高数据资产安全。
MySQL技术
2019/09/08
4.4K0
技术分享 | MySQL 使用 MariaDB 审计插件
专注于 Oracle、MySQL 数据库多年,Oracle 10G 和 12C OCM,MySQL 5.6 ,5.7,8.0 OCP。现在鼎甲科技任顾问,为同事和客户提供数据库培训和技术支持服务。
爱可生开源社区
2020/09/14
1.2K0
Oracle标准审计实战过程详解
最近很多人咨询我Oracle的审计功能,下面我用一个非常清晰的过程给大家讲解一个相关案例。
数据和云
2021/08/27
6610
技术分享 | 聊聊 MySQL 关机的故事
这两天看到一个 MySQL 群里在讨论一个有趣的话题,大家平时都是怎么关闭 MySQL 的,一个大佬还发起了一个投票。投票如下:
爱可生开源社区
2022/04/06
3460
技术分享 | MariaDB 10.1.9 迁移到 MySQL 5.7.25
爱可生 DBA 团队成员,负责项目日常问题处理及公司平台问题排查,对数据库有兴趣,对技术有想法。一入 IT 深似海,从此节操是路人。
爱可生开源社区
2020/06/12
2.1K0
技术分享 | MariaDB 10.1.9 迁移到 MySQL 5.7.25
MySQL审计插件介绍
数据库审计功能主要将用户对数据库的各类操作行为记录审计日志,以便日后进行跟踪、查询、分析,以实现对用户操作的监控和审计。审计是一项非常重要的工作,也是企业数据安全体系的重要组成部分,等保评测中也要求有审计日志。对于 DBA 而言,数据库审计也极其重要,特别是发生人为事故后,审计日志便于我们进行责任追溯,问题查找。
MySQL技术
2022/11/22
8590
MySQL审计插件介绍
MySQL审计数据归档演示
在此博客中,我将演示如何在许多mysql实例之间将审计日志进行合并归档。在后续文章中,我将展示如何通过在该归档文件上创建一个简单的哈希链来扩展此示例–这样您就可以证明是否可以通过任何方式对其进行了修改或污染,以及在何处进行了修改。
MySQLSE
2020/11/09
1.1K0
MySQL企业版之Audit(审计)初体验
MySQL企业版的优势在于有原厂技术支持,以及几个相当不错的功能插件,例如Transparent Data Encryption (TDE)(透明数据加密)、Audit(审计)、thread pool(线程池)、firewall(防火墙)、Data Masking(数据打码)等功能,还有企业级高可用、备份、监控等工具套件。
老叶茶馆
2020/06/24
2K0
【腾讯云CDB】MySQL审计功能大揭秘
腾讯云数据库 TencentDB
2017/12/28
5.3K0
【腾讯云CDB】MySQL审计功能大揭秘
相关推荐
利用开源审计插件对mysql进行审计
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验