在许多环境中,审计睡在使用数据库及其活动是至关重要的。此功能在 Percona 版 MySQL 中包含的免费开源审计插件中提供。
安装 Percona 的审计日志插件先决条件是首先安装 Percona 版 MySQL。Percona 版 MySQL 是 MySQL 的替代品。
审计日志插件本身很容易安装,只需要在 MySQL 客户端程序加载共享对象库中安装插件 audit_log SONAME ‘audit_log.so’。
stoker@testbox:~/Downloads$ mysql -u root -p mysql
Enter password:
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Welcome to the MySQL monitor. Commands end with ; or g.
Your MySQL connection id is 9
Server version: 8.0.30-22 Percona Server (GPL), Release '22', Revision '7e301439b65'
Copyright (c) 2009-2022 Percona LLC and/or its affiliates
Copyright (c) 2000, 2022, Oracle and/or its affiliates.
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> INSTALL PLUGIN audit_log SONAME 'audit_log.so';
Query OK, 0 rows affected (0.06 sec)
mysql>
如果您想二次检查安装,你需要查询 Information Schema
中的 Plugings
表。
mysql> SELECT * FROM information_schema.PLUGINS WHERE PLUGIN_NAME LIKE '%audit%'G
*************************** 1. row ***************************
PLUGIN_NAME: audit_log
PLUGIN_VERSION: 0.2
PLUGIN_STATUS: ACTIVE
PLUGIN_TYPE: AUDIT
PLUGIN_TYPE_VERSION: 4.1
PLUGIN_LIBRARY: audit_log.so
PLUGIN_LIBRARY_VERSION: 1.11
PLUGIN_AUTHOR: Percona LLC and/or its affiliates.
PLUGIN_DESCRIPTION: Audit log
PLUGIN_LICENSE: GPL
LOAD_OPTION: ON
1 row in set (0.01 sec)
mysql>
审计日志将以 JSON 、CSV 或者 XML 格式(您可以选择)收集有关连接、查询、关闭、删除和其他活动的消息。日志本身具有高度可配置性,可以设置为包括或排除特定用户、数据或命令。审计可以记录到文件中或者 SYSLOG 中。
如果您以前从未使用过审计日志,请注意,最初的输出似乎很冗长。您将在该日志中看到的第一条记录是加载审计日志共享对象。
stoker@testbox:$ sudo cat /var/lib/mysql/audit.log
<?xml version="1.0" encoding="UTF-8"?>
<AUDIT>
<AUDIT_RECORD
NAME="Audit"
RECORD="1_2022-11-21T18:39:45"
TIMESTAMP="2022-11-21T18:39:45Z"
MYSQL_VERSION="8.0.30-22"
STARTUP_OPTIONS=""
OS_VERSION="x86_64-Linux"
/>
<AUDIT_RECORD
NAME="Query"
RECORD="2_2022-11-21T18:39:45"
TIMESTAMP="2022-11-21T18:39:45Z"
COMMAND_CLASS="install_plugin"
CONNECTION_ID="9"
STATUS="0"
SQLTEXT="INSTALL PLUGIN audit_log SONAME 'audit_log.so'"
USER="root[root] @ localhost []"
HOST="localhost"
OS_USER=""
IP=""
DB=""
/>
示例
要演示审计插件的功能,先创建两个账户,然后将其添加到 audit_log_include_accounts
变量里。
mysql> CREATE USER 'test1'@'%' IDENTIFIED BY '1Test1';
Query OK, 0 rows affected (0.13 sec)
mysql> CREATE USER 'test2'@'%' IDENTIFIED BY '2Test2';
Query OK, 0 rows affected (0.14 sec)
mysql> SET GLOBAL audit_log_include_accounts ='test1@%,test2@%';
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT @@audit_log_include_accounts;
+------------------------------+
| @@audit_log_include_accounts |
+------------------------------+
| test1@%,test2@% |
+------------------------------+
1 row in set (0.00 sec)
mysql>
记录了什么?
记录的是服务器上的活动,可配置为包含或者不包含账户、schema 或操作。使用其中一个新账户连接到服务端会生成两条记录:连接和查询,如下所示。使用 MySQL Shell 会生成更多的条目,因为 shell 在连接时请求更多数据来填充变量。
<AUDIT_RECORD
NAME="Connect"
RECORD="11_2022-11-21T18:39:45"
TIMESTAMP="2022-11-21T18:51:48Z"
CONNECTION_ID="10"
STATUS="0"
USER="test1"
PRIV_USER="test1"
OS_LOGIN=""
PROXY_USER=""
HOST="localhost"
IP=""
DB=""
/>
<AUDIT_RECORD
NAME="Query"
RECORD="12_2022-11-21T18:39:45"
TIMESTAMP="2022-11-21T18:51:48Z"
COMMAND_CLASS="select"
CONNECTION_ID="10"
STATUS="0"
SQLTEXT="select @@version_comment limit 1"
USER="test1[test1] @ localhost []"
HOST="localhost"
OS_USER=""
IP=""
DB=""
/>
也许您有些命令不想审计。例如,当您非常关心表中数据被删除,不想审计表创建、查询或者数据库其他修改操作。您可以使用类似SET GLOBAL audit_log_include_commands= ‘set_option,create_db’;
的命令选择要审计的命令。那么,如何获得可审核的命令列表?
mysql> SELECT name FROM performance_schema.setup_instruments WHERE name LIKE "statement/sql/%" ORDER BY name;
您可以看到如下内容:
+------------------------------------------+
| name |
+------------------------------------------+
| statement/sql/alter_db |
| statement/sql/alter_db_upgrade |
| statement/sql/alter_event |
| statement/sql/alter_function |
| statement/sql/alter_procedure |
| statement/sql/alter_server |
| statement/sql/alter_table |
| statement/sql/alter_tablespace |
| statement/sql/alter_user |
| statement/sql/analyze |
| statement/sql/assign_to_keycache |
| statement/sql/begin |
| statement/sql/binlog |
| statement/sql/call_procedure |
| statement/sql/change_db |
| statement/sql/change_master |
...
| statement/sql/xa_rollback |
| statement/sql/xa_start |
+------------------------------------------+
145 rows in set (0.00 sec)
要查找的内容
学习阅读审计日志不会花费很多时间。以下是尝试登陆但失败的案例。登陆失败时,密码错误(故意输错),会生成一个稍微不同的 schema ,即生成退出,而不是连接。
<AUDIT_RECORD
NAME="Quit"
RECORD="43_2022-11-21T18:39:45"
TIMESTAMP="2022-11-21T18:57:48Z"
CONNECTION_ID="16"
STATUS="0"
USER="test1"
PRIV_USER="test1"
OS_LOGIN=""
PROXY_USER=""
HOST="localhost"
IP=""
DB="davetest"
/>
<AUDIT_RECORD
NAME="Connect"
RECORD="44_2022-11-21T18:39:45"
TIMESTAMP="2022-11-21T18:57:54Z"
CONNECTION_ID="17"
STATUS="1045"
USER="test1"
PRIV_USER="test1"
OS_LOGIN=""
PROXY_USER=""
HOST="localhost"
IP=""
DB=""
/>
使用 mysql -u test1 -p davetest
正确登陆生成了一个连接
<AUDIT_RECORD
NAME="Connect"
RECORD="45_2022-11-21T18:39:45"
TIMESTAMP="2022-11-21T18:58:34Z"
CONNECTION_ID="18"
STATUS="0"
USER="test1"
PRIV_USER="test1"
OS_LOGIN=""
PROXY_USER=""
HOST="localhost"
IP=""
DB="davetest"
/>
<AUDIT_RECORD
NAME="Query"
RECORD="46_2022-11-21T18:39:45"
TIMESTAMP="2022-11-21T18:58:34Z"
COMMAND_CLASS="show_databases"
CONNECTION_ID="18"
STATUS="0"
SQLTEXT="show databases"
USER="test1[test1] @ localhost []"
HOST="localhost"
OS_USER=""
IP=""
DB="davetest"
/>
<AUDIT_RECORD
NAME="Query"
RECORD="47_2022-11-21T18:39:45"
TIMESTAMP="2022-11-21T18:58:34Z"
COMMAND_CLASS="show_tables"
CONNECTION_ID="18"
STATUS="0"
SQLTEXT="show tables"
USER="test1[test1] @ localhost []"
HOST="localhost"
OS_USER=""
IP=""
DB="davetest"
/>
<AUDIT_RECORD
NAME="Query"
RECORD="48_2022-11-21T18:39:45"
TIMESTAMP="2022-11-21T18:58:34Z"
COMMAND_CLASS="select"
CONNECTION_ID="18"
STATUS="0"
SQLTEXT="select @@version_comment limit 1"
USER="test1[test1] @ localhost []"
HOST="localhost"
OS_USER=""
IP=""
DB="davetest"
/>
我建议从一种类型的操作开始,查看日志中的所有事件。可能您的实例有大量表变更或者登陆失败。寻找您需要注意的部分。
示例
创建一个简单表并插入一条记录同样会生成审计日志条目。
mysql> create table t1 (id int unsigned not null auto_increment primary key, c1 int, extra JSON);
Query OK, 0 rows affected (0.63 sec)
mysql> insert into t1 (c1,extra) values (101,'{ "Name": "Dave"}');
Query OK, 1 row affected (0.10 sec)
mysql>
这里我们可以看到执行的确切查询、时间戳数据、连接信息和命令状态。
<AUDIT_RECORD
NAME="Query"
RECORD="50_2022-11-21T18:39:45"
TIMESTAMP="2022-11-21T19:04:09Z"
COMMAND_CLASS="create_table"
CONNECTION_ID="18"
STATUS="0"
SQLTEXT="create table t1 (id int unsigned not null auto_increment primary key, c1 int, extra JSON)"
USER="test1[test1] @ localhost []"
HOST="localhost"
OS_USER=""
IP=""
DB="davetest"
/>
<AUDIT_RECORD
NAME="Query"
RECORD="51_2022-11-21T18:39:45"
TIMESTAMP="2022-11-21T19:05:20Z"
COMMAND_CLASS="insert"
CONNECTION_ID="18"
STATUS="0"
SQLTEXT="insert into t1 (c1,extra) values (101,'{ "Name": "Dave"}')"
USER="test1[test1] @ localhost []"
HOST="localhost"
OS_USER=""
IP=""
DB="davetest"
/>
Percona 审计插件是高度可配置的。您可以使用SET GLOBAL audit_log_include_accounts = ‘user1@host,root@host’
包含某些用户,或者使用SET GLOBAL audit_log_exclude_accounts = ‘user1@host,root@host’
排除某些用户,同样您可以使用SET GLOBAL audit_log_include_databases = ‘test,mysql,db1’;
包含或者排除某些数据库。
您还可以设置整个 audit_log_policy
。此参数用于指定应记录哪些事件,例如 ALL
——将记录所有事件,LOGINS
——仅记录登陆事件,QUERIES
——仅记录查询事件,NONE
——没有事件将被记录。结合上文列出的包含或者排除选项,应该很容易将注意力集中到需要监控的最关键事件和资源上。
为了避免磁盘空间不足,您还可以控制何时在文件达到您认为合适的大小时候对审计日志进行切割。
总结
审计日志插件是企业级功能,免费开源的 Percona 版 MySQL 也有这个功能。如果您希望在Oracle 版 MySQL 使用此功能,需要购买企业许可。Percona 审计插件的设置可以根据您的需要进行调整。
原文始发于微信公众号(Mwkk):Percona 版 MySQL 中审计日志插件——以社区版价格提供企业版功能
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/100513.html