本文分享自华为云社区《【华为云MySQL技术专栏】RDS for MySQL 审计日志功能介绍》,作者:GaussDB数据库。

1. 背景

在生产环境中,当数据库出现故障或问题时,运维人员需要快速定位出异常或者高危的SQL语句。这时,审计日志能够提供详细的记录,帮助追踪每个数据库操作的执行者、执行时间以及受影响的数据对象,从而大大加速故障排查和恢复流程。

MySQL企业版提供了审计日志插件,可以对数据库操作进行细粒度的审计。该插件支持记录用户登录、查询执行、数据修改等重要操作。然而,在MySQL社区版中,只是提供了审计日志的相关插件接口定义和功能描述,并不支持原生的审计日志功能。

为了弥补这一功能的缺失,华为云RDS for MySQL通过集成Percona公司开源的审计日志插件,实现了MySQL审计日志功能。该功能已在RDS for MySQL 5.7和RDS for MySQL 8.0版本中开放,满足了用户对数据库安全审计的需求,同时增强了数据库的合规性和可用性。

本文将以RDS for MySQL为研究对象,对于审计日志进行功能介绍和原理解析。

2. 功能参数介绍

当在RDS for MySQL上开启审计日志功能,用户可以通过SHOW variables LIKE 'audit%';语句查看与审计日志功能相关的变量名和参数值。

mysql> SHOW variables LIKE 'audit%';
+-------------------------------------+---------------+
| Variable_name | Value |
+-------------------------------------+---------------+
| audit_log_anonymized_ip | |
| audit_log_buffer_size | 1048576 |
| audit_log_csv2_escape | OFF |
| audit_log_csv2_old_separated_format | OFF |
| audit_log_csv2_truncation | ON |
| audit_log_exclude_accounts | |
| audit_log_exclude_commands | |
| audit_log_exclude_databases | |
| audit_log_file | audit.log |
| audit_log_flush | OFF |
| audit_log_force_rotate | OFF |
| audit_log_format | CSV2 |
| audit_log_handler | FILE |
| audit_log_include_accounts | |
| audit_log_include_commands | |
| audit_log_include_databases | |
| audit_log_policy | ALL |
| audit_log_rotate_on_size | 104857600 |
| audit_log_rotations | 50 |
| audit_log_strategy | ASYNCHRONOUS |
| audit_log_syslog_facility | LOG_USER |
| audit_log_syslog_ident | percona-audit |
| audit_log_syslog_priority | LOG_INFO |
+-------------------------------------+---------------+
23 rows in set (0.01 sec)

这些参数控制着审计日志插件的整体功能,允许用户灵活调节审计日志的各个方面。通过合理设置和调整这些参数,用户可以精确确定日志的记录范围、记录级别、存储方式等。例如,用户可以通过audit_log_policy 决定审计日志的记录级别,也可以通过改变audit_log_strategy 调整审计日志的刷新策略。

在 RDS for MySQL中,部分变量因安全合规考虑未开放修改。下表对审计日志功能中相关变量的作用和默认值进行介绍。

表格 1 审计日志变量介绍

3. 日志内容解析

在RDS for MySQL上,audit_log_policy的默认值为ALL。在该级别下,审计日志会记录包括DML(数据操作语言)、DDL(数据定义语言)、DCL(数据控制语言)操作以及连接或断开连接等数据库活动。需要注意的是,不同类型的活动包含的日志字段有所不同。下面将从常见DDL、DML、DCL操作以及数据库连接与断开连接产生的审计日志进行内容解析。

DDL、DML和DCL

对于DDL、DML和DCL操作,所生成的审计日志格式是相同的。对于日志字段的具体含义详见如下。

  • RECORD ID:审计日志唯一ID,用来标识每条审计日志。

  • STATUS:状态码,非0表示ERROR。

  • NAME:操作命令分类,QUERY、EXECUTE、QUIT、CONNECT等。

  • TIMESTAMP:记录日志发生的时间戳。

  • COMMAND_CLASS:记录DDL、DML和DCL操作的类型,SELECT、INSERT、DELETE等。

  • SQLTEXT:执行SQL语句的内容。

  • USER:连接数据库的用户名。

  • HOST:连接数据库的主机名。

  • IP:连接数据库的客户端IP地址。

  • DATABASE:连接指定的数据库名。

Connect和Disconnect

连接或断开连接事件,在用户登录成功或登录失败时均会有日志记录。与DDL和DDL操作产生的审计日志不同,连接事件产生审计日志增加了PRIV_USER、OS_LOGIN等字段,下面对于连接或断开连接产生的审计日志进行解析。

  • RECORD ID: 审计日志唯一ID,用来标识每条审计日志。

  • STATUS:状态码,非0表示ERROR。

  • NAME: 操作命令分类,QUERY、EXECUTE、QUIT、CONNECT等。

  • TIMESTAMP:记录日志发生的时间戳

  • USER:连接数据库的用户名。

  • PRIV_USER:经过身份验证的用户名。

  • OS_LOGIN:外部用户名。

  • PROXY_USER:代理用户名。

  • HOST:连接数据库的主机名。

  • IP:连接数据库的客户端IP地址。

  • DATABASE:连接指定的数据库名。

通过对审计日志内容的解析,用户不仅可以快速地查看任意时间段数据库的活动状态,还能够准确了解每条SQL语句的详情,包括执行的用户、时间戳、查询类型等关键信息。这样详细的记录为安全审查、问题排查以及性能优化提供了强有力的支撑。

4.RDS for MySQL审计日志原理浅析

RDS for MySQL审计功能的核心是通过不同类型的事件驱动审计日志插件完成对应类型日志的记录。在RDS for MySQL中一共支持两类事件,即一般事件和连接事件。一般事件可以理解为用户执行的DDL、DML和DCL语句。连接事件则是连接数据库(Connect)和断开连接(Disconnect)数据库。审计日志插件支持事件定义的相关代码如下。

static int is_event_class_allowed_by_policy(mysql_event_class_t event_class,num audit_log_policy_t policy) {
static unsigned int class_mask[] = {
/* ALL */
(1 << MYSQL_AUDIT_GENERAL_CLASS) | (1 << MYSQL_AUDIT_CONNECTION_CLASS),
0, /* NONE */
(1 << MYSQL_AUDIT_CONNECTION_CLASS), /* LOGINS */
(1 << MYSQL_AUDIT_GENERAL_CLASS), /* QUERIES */
}; return (class_mask[policy] & (1 << event_class)) != 0;
}

当发生可审计事件时,服务器会调用相关的审计接口,以便向已注册的审计日志插件传递该事件的信息,确保审计插件在必要时能够接收到并处理该事件。

审计日志功能在RDS for MySQL内核的入口函数是mysql_audit_notify。通过对应事件驱动审计日志插件的工作。主要工作流程调用栈如下所示。

  do_command
->dispatch_commnad
->mysql_audit_notify
->event_class_dispatch
// 检查当前插件是否需要处理此事件
->plugin_dispatch
// 按事件类别下发审计任务
->audit_log_notify

数据库内核在收到一条SQL的执行请求后,首先,会通过do_command函数处理该连接。处理完成后,由dispatch_command函数依据不同SQL类型进行命令分发。之后,审计入口函数mysql_audit_notify会完成审计日志记录前的准备和校验工作。如果校验通过,则后续工作会由已注册的审计日志插件中的其他函数完成。

通过函数调用栈可以看出,审计日志功能与数据库内核之间实现了高度解耦。二者通过预先注册的函数接口进行对接,这种设计提高了未来功能扩展的灵活性。

审计日志插件的校验和资源准备工作由mysql_audit_acquire_plugins函数完成,当该函数完成校验后,即审计日志插件已完成注册并且相关资源也已完成绑定,接下来将由audit_log_notify函数按照事件的类型和相关参数设定完成任务分发。audit_log_notify会调用audit_log_write函数完成审计日志的写入,audit_log_write会依据audit_log_handler变量的值来判断是写入审计日志文件还是系统日志。

若是写入日志文件中,此时还会判断日志的写入策略;如果audit_log_strategy是PERFORMANCE或ASYNCHRONOUS,则会调用audit_handle_file_write_buf函数,将日志内容写入审计日志插件的缓冲区中,否则会调用audit_handle_file_write_nobuf函数,将日志内容直接写入操作系统文件缓存。

若audit_log_handler值为SYSLOG,则意味着审计日志会直接写到系统日志中。那么则会通过调用audit_handler_syslog_write完成日志向系统日志的写入。审计日志内部函数调用流程如图所示。

图1 审计日志插件工作流程图

从图中可以看到,审计日志的落盘方式主要有两种,分别是通过文件系统完成日志落盘和利用审计日志刷盘线程不断地将缓冲区的日志写入磁盘中。审计日志的缓冲区是在审计日志插件初始化时完成相关资源的分配,其结构体如下:

struct audit_log_buffer {
// 缓冲区内容
char *buf;
// 缓冲区大小
size_t size;
// 写日志位置
size_t write_pos;
// 日志落盘位置
size_t flush_pos;
// 日志落盘工作线程
pthread_t flush_worker_thread;
// 缓冲区是否暂停
int stop;
// 缓冲区满是否丢弃该日志
int drop_if_full;
void *write_func_data;
audit_log_write_func write_func;
mysql_mutex_t mutex;
mysql_cond_t flushed_cond;
mysql_cond_t written_cond;
log_record_state_t state;
};

从审计日志缓冲区结构体可以看到,日志缓冲区主要通过日志写入函数和日志落盘线程完成其核心功能。

当日志需要写入缓冲区时,首先会比较日志的长度和缓冲区的大小。如果审计日志的长度大于日志缓冲区的大小,并且缓冲区满且选择不丢弃该日志时,审计日志的落盘线程暂停工作,并会绕过日志的缓冲区,直接写入文件缓冲区中。当审计日志长度小于日志缓冲区大小时,此时会将日志的内容拷贝到文件缓冲区中,并更新缓冲区write_pos等相关参数,等待日志落盘线程的工作。如果当前写入位置超过整个缓冲区大小的一半,则会立刻通知落盘线程,完成审计日志的落盘。

审计日志的落盘工作主要由日志落盘工作线程完成。如果日志缓冲区没有关闭并且缓冲区中还存在日志尚未落盘,则会循环调用日志落盘函数进行日志写入。

static void *audit_log_flush_worker(void *arg) {
audit_log_buffer_t *log = (audit_log_buffer_t *)arg;
// 线程初始化
my_thread_init();
// 如果日志缓冲区没有关闭并且当前还有日志未落盘
while (!(log->stop && log->flush_pos == log->write_pos)) {
// 进行日志的落盘工作
audit_log_flush(log);
}
// 关闭线程
my_thread_end(); return nullptr;
}

对于日志落盘函数,会通过循环判断write_pos和flush_pos是否相等,如果二者相等并且日志缓冲区没有停止工作,此时会等待1秒进入循环;如果二者不相等,说明缓冲区中有新的日志需要落盘。

此时,若write_pos大于缓冲区的大小,日志插件会把flush_pos后的所有日志进行落盘,并将当前日志的状态设为LOG_RECORD_INCOMPLETE。若write_pos在缓冲区大小范围内,则会将该条日志完整写入审计日志文件中并将该日志状态设为LOG_RECORD_COMPLETE。在完成日志落盘操作后,与缓冲区相关变量值会同步更新,并为下次日志落盘做好准备。

5.使用说明

1)数据库实例开启审计日志

登录管理控制台,在云数据库RDS for MySQL的“实例管理”页面,单击目标实例名称,进入基本信息页面。在左侧导航栏,点击“SQL审计”,在“SQL审计”右侧点击开启按钮,在弹框中点击“确定”,打开审计日志开关。

图2 设置审计日志功能

2)审计日志的下载

开启审计日志后,数据库的相关活动都会以日志的形式记录在OBS中,用户可以在控制台界面进行审计日志的下载。

图3 控制台界面下载审计日志

6.总结

RDS for MySQL的审计日志功能在用户活动监控、权限变更追踪和性能优化等方面有着重要的作用。它不仅帮助企业提升数据库的整体安全性,满足日益严格的合规性要求,还在故障排查中提供有价值的信息。这一功能能够精确的记录用户的数据库操作,有助于识别潜在的安全威胁,并为性能瓶颈分析和优化提供详实的数据支持。

华为开发者空间,汇聚鸿蒙、昇腾、鲲鹏、GaussDB、欧拉等各项根技术的开发资源及工具,致力于为每位开发者提供一台云主机、一套开发工具及云上存储空间,让开发者基于华为根生态创新。

点击链接,免费领取您的专属云主机~

深度解读RDS for MySQL 审计日志功能和原理的更多相关文章

  1. Ubuntu下rsyslog集中收集mysql审计日志

    服务端 1.安装最新版本rsyslog sudo apt-get install software-properties-common python-software-properties sudo ...

  2. MySQL二进制日志功能介绍

    二进制日志记录所有更新数据的SQL语句,其中也包含可能更新数据的SQL语句,例如DELETE语句执行过程中无匹配的行.二进制日志中还包含了与执行SQL语句相关的内容,例如SQL语句执行的时间.错误代码 ...

  3. rsyslog服务器同步其他服务器上面应用日志(如mysql审计日志 、nginx日志)

    **环境说明**系统:ubuntu 14.04 (CentOS可以参考http://www.cnblogs.com/hanyifeng/p/5463338.html) rsyslog版本 :8.16. ...

  4. abp审计日志功能的关闭

    参考官网介绍:https://aspnetboilerplate.com/Pages/Documents/Audit-Logging

  5. MySQL慢日志功能分析及优化增强

    本文由  网易云发布. MySQL慢日志(slow log)是MySQL DBA及其他开发.运维人员需经常关注的一类信息.使用慢日志可找出执行时间较长或未走索引等SQL语句,为进行系统调优提供依据.本 ...

  6. MySQL慢日志线上问题分析及功能优化

    本文来源于数据库内核专栏. MySQL慢日志(slow log)是MySQL DBA及其他开发.运维人员需经常关注的一类信息.使用慢日志可找出执行时间较长或未走索引等SQL语句,为进行系统调优提供依据 ...

  7. Kubernetes审计日志方案

    前言 当前Kubernetes(K8S)已经成为事实上的容器编排标准,大家关注的重点也不再是最新发布的功能.稳定性提升等,正如Kubernetes项目创始人和维护者谈到,Kubernetes已经不再是 ...

  8. Abp + MongoDb 改造默认的审计日志存储位置

    一.背景 在实际项目的开发当中,使用 Abp Zero 自带的审计日志功能写入效率比较低.其次审计日志数据量中后期十分庞大,不适合与业务数据存放在一起.所以我们可以重新实现 Abp 的 IAuditi ...

  9. 配置Mysql审计

    mysql-audit.json:Mysql审计日志 插件下载地址: https://bintray.com/mcafee/mysql-audit-plugin/release/1.1.4-725#f ...

  10. 最全Kubernetes审计日志方案

    前言 当前Kubernetes(K8S)已经成为事实上的容器编排标准,大家关注的重点也不再是最新发布的功能.稳定性提升等,正如Kubernetes项目创始人和维护者谈到,Kubernetes已经不再是 ...

随机推荐

  1. 颗粒流 + Janssen 定律 + Bagnold 数

    对于 \(n\) 个球,易得有 \[\begin{array}{c} \displaystyle\frac\pi2>\theta_i>-\frac\pi2,\theta_1>\cdo ...

  2. Win32 自绘控件按钮类

    今天学了控件的自绘,初步偿试了下,蹂躏的不行不行的,查了好多的资料,头都弄大了, 有好多还是没弄明白,只是初步实现一个按钮的基本功能,好难呀, 先看下效果: 按下状态 弹起状态 按钮2按下状态 按钮2 ...

  3. “从零到一:如何在鸿蒙OS上启动你的第一个项目”

    背景与引言 全球操作系统市场现状如何? 长期以来,Android.iOS.Windows等巨头几乎垄断了整个市场,成为人们日常生活中不可或缺的工具.然而,尽管它们在各自领域有着不可否认的成功,却也逐渐 ...

  4. 2024DASCTF

    DASCTF prese 一眼控制了平坦化,可以用d810梭一下 跟进一下main_crypto这个函数 主要是两部分,第一部分是生成一个256大小的数组,通过输入的长度和遍历生成的一个数组 第二部分 ...

  5. 省钱的开源项目「GitHub 热点速览」

    本期,我从上周的热门开源项目中挑选了 5 个既省钱又省事,还好玩的开源项目. 首先,推荐的是省钱的电动汽车智能充电管理平台 evcc,它可以根据分时电价智能安排电动车充电时间,从而降低电费,如果你家还 ...

  6. 【YashanDB数据库】Ubuntu系统加载Yashan C驱动后无法使用PHP

    [问题分类]驱动使用 [关键字]驱动使用.PHP.Ubuntu.C驱动 [问题描述] 客户将YashanDB的C驱动lib加载到环境变量LD_LIBRARY_PATH后,PHP报错:PHP Fatal ...

  7. Ansible 知识

    Ref: guru99.com/ansible-tutorial.html https://www.digitalocean.com/community/tutorials/how-to-use-an ...

  8. Asp.net core 学习笔记之 authentication + authorization + identity + identity server 4 + angular 第六篇 (authorization 之 simple authorization, role based, claim based, policy based)

    authorization 授权是什么 ? 就是某个人必须符合某些条件才能做某些事儿 某个人指的是登入的 user 某些条件指的是 policy requirements 事儿指的是访问 contro ...

  9. 蓝桥杯-全球变暖 (DFS)

    你有一张某海域NxN像素的照片,"."表示海洋."#"表示陆地,如下所示: ....... .##.... .##.... ....##. ..####. .. ...

  10. Go runtime 调度器精讲(九):系统调用引起的抢占

    原创文章,欢迎转载,转载请注明出处,谢谢. 0. 前言 第八讲介绍了当 goroutine 运行时间过长会被抢占的情况.这一讲继续看 goroutine 执行系统调用时间过长的抢占. 1. 系统调用时 ...