当前位置: 首页 > news >正文

数据库高安全—审计追踪:传统审计统一审计

书接上文数据库高安全—角色权限:权限管理&权限检查,从权限管理和权限检查方面解读了高斯数据库的角色权限,本篇将从传统审计统一审计两方面对高斯数据库的审计追踪技术进行解读。

4  审计追踪   

4.1 传统审计

审计内容的记录方式通常有两种:记录到数据库的表中、记录到OS文件中。openGauss采用记录到OS文件中(即审计日志)的方式来保存审计结果,审计日志文件夹受操作系统权限保护,默认只有初始化用户可以读写,从数据库安全角度出发,保证了审计结果的可靠性。日志文件的存储目录由audit_directory参数指定。

openGauss审计日志每条记录包括time、type、result、userid、username、database、client_conninfo、object_name、detail_info、node_name、thread_id、local_port、remote_port共13个字段。图1为审计日志的单条记录示例。

图片

图1  审计记录示例

对审计日志文件进行读写的函数主要位于pgaudit.cpp文件中,其中主要包括两类函数:审计文件的读、写、更新函数;审计记录的增、删、查接口。

首先我们介绍审计文件的数据结构。

openGauss的审计日志采用文件的方式存储在指定目录中。通过查看目录,我们发现日志主要包括两类文件:形如0_adt的审计文件以及名为index_table索引文件。    

图片

图2 审计文件结构

以adt结尾的审计文件中,每一条审计记录对应一个AuditData结构体。

数据结构AuditData:

    typedef struct AuditData {    AuditMsgHdr header;    // 记录文件头,存储记录的标识、大小等信息     AuditType type;        // 审计类型         AuditResult result;      // 执行结果     char varstr[1];         // 二进制格式存储的具体审计信息 } AuditData;

    其中AuditMsgHdr记录着审计记录的标识信息,其结构如下:

    数据结构 AuditMsgHdr:

      typedef struct AuditMsgHdr {    char signature[2];   // 审计记录标识,目前固定为AUDIT前两个字符’A’和’U’     uint16 version;      // 版本信息,目前固定为0     uint16 fields;       // 审计记录字段数,目前为13     uint16 flags;        // 记录有效性标识,如果被删除则标记为DEAD     pg_time_t time;     // 审计记录创建时间     uint32 size;         // 审计信息占字节长度 } AuditMsgHdr;

      AuditData的其他结构存储着审计记录的审计信息,AuditType为审计类型,目前有38种类型。AuditResult为执行的结果,有AUDIT_UNKNOWN、AUDIT_OK、AUDIT_FAILED三种结果。其余的各项信息,均通过二进制的方式写入到varstr中。

      审计日志有关的另一个文件为索引文件index_table,其中记录着审计文件的数量、审计日志文件编号、审计文件修改日期等信息。    

      数据结构 AuditIndexTable:

        typedef struct AuditIndexTable {    uint32 maxnum;             // 审计目录下审计文件个数的最大值     uint32 begidx;               // 审计文件开始编号     uint32 curidx;                // 当前使用的审计文件编号     uint32 count;                 // 当前审计文件的总数     pg_time_t last_audit_time;      // 最后一次写入审计记录的时间     AuditIndexItem data[1];        // 审计文件指针 } AuditIndexTable;

        索引文件中每一个AuditIndexItem对应一个审计文件,其结构如下:

        数据结构 AuditIndexTable:

          typedef struct AuditIndexItem {    pg_time_t ctime;             // 审计文件创建时间     uint32 filenum;              // 审计文件编号     uint32 filesize;               // 审计文件占空间大小 } AuditIndexItem;

          审计文件的读、写类函数如auditfile_open、auditfile_rotate等函数实现较简单,读者可以直接阅读源码。

          下面主要介绍日志文件的结构和日志记录的增、删、查接口。

          审计记录的写入接口为audit_report函数。该函数的原型为:

            void audit_report(AuditType type, AuditResult result, const char* object_name, const char* detail_info);

            其中入参type、result、object_name、detail_info分别对应审计日志记录中的相应字段,审计日志中的其余9个字段均为函数在执行时从全局变量中获取。

            audit_report函数的执行主要分为3个部分,首先会检查审计的各项开关,判断是否需要审计该操作。然后根据传入的参数、全局变量中的参数以及当前时间,生成审计日志所需的信息并拼接成字符串。最后调用审计日志文件读写接口,将审计日志写入文件中。

            审计记录查询接口为pg_query_audit函数,该函数为数据库内置函数,可供用户直接调用,调用形式为:

              SELECT * FROM pg_query_audit (timestamptz startime,timestamptz endtime, audit_log);

              入参为需要查询审计记录的起始时间和终止时间以及审计日志文件所在的物理路径。当不指定audit_log时,默认查看连接当前实例的审计日志信息。    

              审计记录的删除接口为pg_delete_audit函数,该函数为数据库内置函数,可供用户直接调用,调用形式为:

                SELECT * FROM pg_delete_audit (timestamptz startime,timestamptz endtime);

                入参为需要被删除审计记录的起始时间和终止时间。该函数通过调用pgaudit_delete_file来将审计日志文件中,startime与endtime之间的审计记录标记为AUDIT_TUPLE_DEAD,达到删除审计日志的效果,而不实际删除审计记录的物理数据。也即执行该函数,审计日志文件大小不会减小。

                4.2 统一审计

                1. 执行原理

                审计机制是openGauss的内置安全能力之一,openGauss提供对用户发起的SQL行为审计和追踪能力,支持针对DDL、DML语句和关键行为(登录、登出、系统启动、恢复)的审计。在每个工作线程初始化阶段把审计模块加载至线程中,其审计的执行原理是把审计函数赋给SQL生命周期不同阶段的Hook,当线程执行至SQL处理流程的特定阶段后会进行审计执行判定逻辑,审计模块加载关键代码如下:

                  void pgaudit_agent_init(void) {    // DDL、DML语句审计hook赋值, 赋值结束后标识审计模块已在此线程加载    prev_ExecutorEnd = ExecutorEnd_hook;    ExecutorEnd_hook = pgaudit_ExecutorEnd;    prev_ProcessUtility = ProcessUtility_hook;    ProcessUtility_hook = (ProcessUtility_hook_type)pgaudit_ProcessUtility;    u_sess->exec_cxt.g_pgaudit_agent_attached = true;}

                  SQL语句在执行到ProcessUtility_hook 和 ExecutorEnd_hook函数指针时,会分别进入到已预置好的审计流程中,这两个函数指针的位置在SQL进入执行器执行之前,具体关系如图3所示。    

                  图片

                  图3  审计执行关系图

                  如图3所示,在线程初始化阶段,审计模块已加载完毕,SQL经过优化器得到计划树,此时审计模块pgaudit_ExecutorEnd和pgaudit_ProcessUtility函数分别进行DML和DDL语句的分析,如果和已设置审计策略相匹配,则会调用审计日志接口,生成对应的审计日志,对于系统变更类的审计直接内置于相应行为的内核代码中。

                  2. 关键执行流程

                  1) 系统变更类审计执行:

                    pgaudit_system_recovery_okpgaudit_system_start_okpgaudit_system_stop_okpgaudit_user_loginpgaudit_user_logoutpgaudit_system_switchover_okpgaudit_user_no_privilegespgaudit_lock_or_unlock_user

                    以上为openGauss支持系统变更类的审计执行函数,对于此类审计函数均嵌入内核相应调用流程中,以审计用户登入登出pgaudit_user_login为例说明其主体流程。    

                    图片

                    图4 登入审计执行流程

                    图4为服务端校验客户端登入时的主要流程,以登录失败场景为例,首先根据配置文件和客户端IP和用户信息确认采用的认证方式(包括sha256和SSL认证等),然后根据不同的认证方式采用不同的认证流程和客户端进行交互完成认证身份流程,如果认证失败,则线程退出报错给客户端,pgaudit_user_login即在认证失败的时候调用,获取当前访问数据库名称和详细信息,调用审计日志接口记录于审计日志中供审计管理员查看,关键代码如下:

                      /* 拼装登入口失败时候的详细信息,包括数据库名称和用户名 */rc = snprintf_s(details,PGAUDIT_MAXLENGTH,    PGAUDIT_MAXLENGTH - 1,    "login db(%s)failed,authentication for user(%s)failed",    port->database_name,    port->user_name); securec_check_ss(rc, "\0", "\0");// 调用登入审计函数,记录审计日志pgaudit_user_login(FALSE, port->database_name, details);// 退出当前线程ereport(FATAL, (errcode(errcode_return), errmsg(errstr, port->user_name)))

                      登入审计日志接口pgaudit_user_login则主要完成审计日志记录接口需要参数的拼接:

                        void pgaudit_user_login(bool login_ok, const char* object_name, const char* detaisinfo){    AuditType audit_type;    AuditResult audit_result;    Assert(detaisinfo);    // 审计类型和审计结果拼装    if (login_ok) {        audit_type = AUDIT_LOGIN_SUCCESS;        audit_result = AUDIT_OK;    } else {            audit_type = AUDIT_LOGIN_FAILED;        audit_result = AUDIT_FAILED;    }    // 直接调用审计日志记录接口    audit_report(audit_type, audit_result, object_name, detaisinfo);}

                        2) DDL、DML语句审计执行

                        依据审计日志执行原理,DDL、DML语句的执行分别由于pgaudit_ProcessUtility、pgaudit_ExecutorEnd来承载,首先介绍函数pgaudit_ProcessUtility,其主体结构如下:

                        DDL审计执行函数关键入参parsetree用于识别审计日志类型(create/drop/alter等操作),入参queryString保存原始执行SQL语句,用于记录审计日志,略去非关键流程,此函数主要根据判断nodeTag所归属的DDL操作类型,进入不同的审计执行逻辑,以T_CreateStmt为例,识别当前语句create table则进入pgaudit_ddl_table逻辑进行审计日志执行并最终记录审计日志。

                        图片

                        图5  DDL审计执行流程

                        如图5所示,首先从当前SQL语句中获取执行对象类别校验其相应的审计开关是否开启,当前支持开启的全量对象如下,可以通过GUC参数audit_system_object控制:

                          typedef enum {    DDL_DATABASE = 0,DDL_SCHEMA, DDL_USER,DDL_TABLE,DDL_INDEX,DDL_VIEW,DDL_TRIGGER,DDL_FUNCTION,DDL_TABLESPACE,DDL_RESOURCEPOOL,DDL_WORKLOAD,DDL_SERVERFORHADOOP,DDL_DATASOURCE,DDL_NODEGROUP,DDL_ROWLEVELSECURITY,DDL_TYPE,DDL_TEXTSEARCH,DDL_DIRECTORY,DDL_SYNONYM} DDLType;

                          如果DDL操作的对象审计已开启则进行审计日志记录流程,在调用审计日志记录函数audit_report之前需要对包含密码的SQL语句进行脱敏处理,即将包含密码的语句中(create role/user)密码替换成‘********’用于隐藏敏感信息,至此针对create DDL语句的审计执行完成,其他类型DDL语句主体流程一致,不做赘述。

                          下面介绍针对DML语句审计执行逻辑pgaudit_ExecutorEnd,整体调用流程如下图6所示。

                          图片

                             

                          图6 DML审计执行流程

                          首先判断SQL查询语句所归属的查询类型,以CMD_SELECT类型为例,先获取查询对象的object_name用于审计日志记录中访问对象的记录,然后调用pgaudit_dml_table:

                            case CMD_SELECT:object_name = pgaudit_get_relation_name(queryDesc->estate->es_range_table);pgaudit_dml_table_select(object_name, queryDesc->sourceText);

                            和DDL的记录一样,同样会对敏感信息进行脱敏后调用审计日志记录接口audit_report,DML审计日志执行完成。

                            以上内容从传统审计和统一审计两方面对高斯数据库的审计追踪技术进行解读,下篇将从数据动态脱敏方面对高斯数据库的数据保护技术进行解读,敬请期待~

                            相关文章:

                            数据库高安全—审计追踪:传统审计统一审计

                            书接上文数据库高安全—角色权限:权限管理&权限检查,从权限管理和权限检查方面解读了高斯数据库的角色权限,本篇将从传统审计和统一审计两方面对高斯数据库的审计追踪技术进行解读。 4 审计追踪 4.1 传统审计 审计内容的记录方式通…...

                            机器学习 - 需要了解的条件概率、高斯分布、似然函数

                            似然函数是连接数据与参数的桥梁,通过“数据反推参数”的逆向思维,成为统计推断的核心工具。理解它的关键在于区分“参数固定时数据的概率”与“数据固定时参数的合理性”,这种视角转换是掌握现代统计学和机器学习的基础。 一、在学习似然函…...

                            Spring Boot Web 入门

                            目录 Spring Boot Web 是 Spring Boot 框架的一个重要模块,它简化了基于 Spring 的 Web 应用程序的开发过程。以下是一个 Spring Boot Web 项目的入门指南,涵盖了项目创建、代码编写、运行等关键步骤。 1. 项目创建 使用 Spring Initializr 使用 IDE …...

                            神经网络|(八)概率论基础知识-二项分布及python仿真

                            【1】引言 前序已经学习了古典概型、条件概率、全概率公式和贝叶斯公式,它们作为基础,解释了事件发生及其概率的对应关系,相关文章链接为: 神经网络|(四)概率论基础知识-古典概型-CSDN博客 神经网络|(五)概率论基础知识-条件概…...

                            【面试场景】MySQL分布式主键选取

                            文章目录 一. MySQL的自增主键二. UUID三. 雪花ID(推荐) 我的博客地址 一. MySQL的自增主键 适合单表的情况, 在分布式分库分表下可能会有一些问题 主键冲突问题 在分布式系统中,多个数据库节点独立生成自增主键,很容易出现重复的主键值。例如&#xff…...

                            执行git stash drop stash@{x} 时出现error: unknown switch `e‘ 的解决方式

                            原因: 在 PowerShell 或某些 Shell 中,{} 是特殊符号,stash{0} 会被解析成 stash 0,而 后的字符可能被误认为选项(如 -e),使 Git 收到意外的 -e 参数,导致报错 unknown switch ‘e’。 解决方…...

                            链表和 list

                            一、单链表的模拟实现 1.实现方式 链表的实现方式分为动态实现和静态实现两种。 动态实现是通过 new 申请结点,然后通过 delete 释放结点的形式构造链表。这种实现方式最能体 现链表的特性; 静态实现是利用两个数组配合来模拟链表。一个表示数据域&am…...

                            windows 蓝牙驱动开发-传输总线驱动程序常见问题

                            以下是驱动程序开发人员在开发总线驱动程序以支持蓝牙功能时可能会遇到的一些常见问题和方案。 我的串行总线驱动程序遇到了一些错误。 它意味着什么? 代码 10-49:设备管理器生成的错误代码。 代码 51:当串行总线驱动程序具有相关的控制器…...

                            Qt修仙之路2-1 炼丹初成

                            widget.cpp #include "widget.h" #include<QDebug> //实现槽函数 void Widget::login1() {QString userusername_input->text();QString passpassword_input->text();//如果不勾选无法登入if(!check->isChecked()){qDebug()<<"xxx"&…...

                            【含开题报告+文档+PPT+源码】基于SpringBoot+Vue宠物预约上门服务预约平台

                            开题报告 本研究论文旨在构建并阐述一个基于 SpringBoot 和 Vue 技术栈开发的宠物上门服务预约平台的设计与实现。该平台集成了丰富的功能模块&#xff0c;为用户提供一体化的便捷服务体验。首先&#xff0c;用户能够通过注册并登录系统&#xff0c;享受个性化的服务流程。在平…...

                            无线AP之详解(Detailed Explanation of Wireless AP)

                            无线AP是什么&#xff1f; 市场上的AP基本上分为两大类&#xff1a;单纯型AP和扩展型AP。扩展型AP除了基本的AP功能之外&#xff0c;还可能带有若干以太网交换口、路由、NAT、DHCP、打印服务器等功能。 无线AP也就是一个无线交换机 无线路由器就是一个带路由功能的无线AP&am…...

                            Spring Boot Actuator与JMX集成实战

                            在微服务架构中&#xff0c;监控和管理应用的运行状态是至关重要的。Spring Boot Actuator 提供了一种便捷的方式来监控和管理 Spring Boot 应用&#xff0c;而 JMX&#xff08;Java Management Extensions&#xff09;则是一种用于管理 Java 应用的标准技术。本文将通过一个实…...

                            mac环境下,ollama+deepseek+cherry studio+chatbox本地部署

                            春节期间&#xff0c;deepseek迅速火爆全网&#xff0c;然后回来上班&#xff0c;我就浅浅的学习一下&#xff0c;然后这里总结一下&#xff0c;我学习中&#xff0c;总结的一些知识点吧&#xff0c;分享给大家。具体的深度安装部署&#xff0c;这里不做赘述&#xff0c;因为网…...

                            camera光心检测算法

                            1.概要 光心检测算法&#xff0c;基于opencv c实现&#xff0c;便于模组厂快速集成到软件工具中&#xff0c;适用于camera模组厂算法评估组装制程镜头与sensor的偏心程度&#xff0c;便于工程师了解制程的问题找出改善方向。 2.技术介绍 下图为camera模组厂抓取的bayer-raw经过…...

                            【MySQL】向后兼容设计规范(无回滚场景)

                            MySQL 向后兼容设计规范&#xff08;无回滚场景&#xff09; 在 不支持数据库回滚 且需保证 长期向后兼容性 的系统中&#xff0c;需通过 架构设计 和 流程管控 规避风险。以下是关键设计规范&#xff1a; 一、变更流程规范 变更分类分级 变更类型风险评估等级审批流程测试要求…...

                            还搞不透stm32单片机启动过程?一篇文章几百字让你彻底看懂!

                            1.stm32启动 1.1 msp和pc的初始值&#xff0c;第一步&#xff1a; 2.boot的值就被锁定了 可以根据实际绑定的值变动&#xff0c; 这里补充一点boot1和0的原理&#xff1a; 1.2来点刺激的&#xff1a; 这里我插入一个链接&#xff1a; 【明解STM32】一文搞明白STM32芯片存储…...

                            无界构建微前端?NO!NO!NO!多系统融合思路!

                            文章目录 微前端理解1、微前端概念2、微前端特性3、微前端方案a、iframeb、qiankun --> 使用比较复杂 --> 自己写对vite的插件c、micro-app --> 京东开发 --> 对vite支持更拉跨d、EMP 方案--> 必须使用 webpack5 --> 很多人感觉不是微前端 --> 去中心化方…...

                            DeepSeek辅助段落扩写的能力怎么样?

                            DeepSeek-R1在学术写作的诸多细节层面展现出了显著的应用价值。接下来我们将通过一系列具体案例&#xff0c;深入探讨该工具如何在扩写、翻译、发表以及内容改进等关键环节为学术写作提供有力支持。在提问环节&#xff0c;DeepSeek-R1能够高效地简化提示词&#xff0c;并精准地…...

                            分形的魅力:数学与艺术的完美结合

                            分形的魅力&#xff1a;数学与艺术的完美结合 分形&#xff08;Fractal&#xff09;是一种神奇的数学结构&#xff0c;它以其无限的复杂性和自相似性吸引了无数科学家、艺术家和数学爱好者。分形不仅仅是数学中的一个概念&#xff0c;它还广泛应用于自然科学、计算机图形学和艺…...

                            如何通过工业智能网关进行数控机床数据采集?

                            数控机床数据采集过程是一个从物理连接到数据处理的完整链条&#xff0c;涉及设备连接、数据采集、预处理和传输的复杂过程&#xff0c;包含通信协议匹配、设备配置、数据采集设置、数据预处理和传输等多个环节。天拓四方自主研发的TDE工业智能网关作为这一过程中的核心设备&am…...

                            UE5 学习系列(二)用户操作界面及介绍

                            这篇博客是 UE5 学习系列博客的第二篇&#xff0c;在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下&#xff1a; 【Note】&#xff1a;如果你已经完成安装等操作&#xff0c;可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作&#xff0c;重…...

                            7.4.分块查找

                            一.分块查找的算法思想&#xff1a; 1.实例&#xff1a; 以上述图片的顺序表为例&#xff0c; 该顺序表的数据元素从整体来看是乱序的&#xff0c;但如果把这些数据元素分成一块一块的小区间&#xff0c; 第一个区间[0,1]索引上的数据元素都是小于等于10的&#xff0c; 第二…...

                            论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)

                            HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...

                            无法与IP建立连接,未能下载VSCode服务器

                            如题&#xff0c;在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈&#xff0c;发现是VSCode版本自动更新惹的祸&#xff01;&#xff01;&#xff01; 在VSCode的帮助->关于这里发现前几天VSCode自动更新了&#xff0c;我的版本号变成了1.100.3 才导致了远程连接出…...

                            多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验

                            一、多模态商品数据接口的技术架构 &#xff08;一&#xff09;多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如&#xff0c;当用户上传一张“蓝色连衣裙”的图片时&#xff0c;接口可自动提取图像中的颜色&#xff08;RGB值&…...

                            React19源码系列之 事件插件系统

                            事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...

                            SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现

                            摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序&#xff0c;以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务&#xff0c;提供稳定高效的数据处理与业务逻辑支持&#xff1b;利用 uniapp 实现跨平台前…...

                            【HTML-16】深入理解HTML中的块元素与行内元素

                            HTML元素根据其显示特性可以分为两大类&#xff1a;块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...

                            【python异步多线程】异步多线程爬虫代码示例

                            claude生成的python多线程、异步代码示例&#xff0c;模拟20个网页的爬取&#xff0c;每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程&#xff1a;允许程序同时执行多个任务&#xff0c;提高IO密集型任务&#xff08;如网络请求&#xff09;的效率…...

                            【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分

                            一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计&#xff0c;提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合&#xff1a;各模块职责清晰&#xff0c;便于独立开发…...