數據庫高安全—審計追蹤:傳統審計統一審計

書接上文數據庫高安全—角色權限:權限管理&權限檢查,從權限管理和權限檢查方面解讀了高斯數據庫的角色權限,本篇將從傳統審計統一審計兩方面對高斯數據庫的審計追蹤技術進行解讀。

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審計日志執行完成。

                            以上內容從傳統審計和統一審計兩方面對高斯數據庫的審計追蹤技術進行解讀,下篇將從數據動態脫敏方面對高斯數據庫的數據保護技術進行解讀,敬請期待~

                            本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
                            如若轉載,請注明出處:http://www.pswp.cn/web/68206.shtml
                            繁體地址,請注明出處:http://hk.pswp.cn/web/68206.shtml
                            英文地址,請注明出處:http://en.pswp.cn/web/68206.shtml

                            如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

                            相關文章

                            第三個Qt開發實例:利用之前已經開發好的LED驅動在Qt生成的界面中控制LED2的亮和滅

                            前言 上一篇博文 https://blog.csdn.net/wenhao_ir/article/details/145459006 中,我們是直接利用GPIO子系統控制了LED2的亮和滅,這篇博文中我們利用之前寫好的LED驅動程序在Qt的生成的界面中控制LED2的亮和滅。 之前已經在下面兩篇博文中實現了LED驅動…

                            deepseek來講lua

                            Lua 是一種輕量級、高效、可嵌入的腳本語言,廣泛應用于游戲開發、嵌入式系統、Web 服務器等領域。以下是 Lua 的主要特點和一些基本概念: 1. 特點 輕量級:Lua 的核心非常小,適合嵌入到其他應用程序中。高效:Lua 的執…

                            (動態規劃 leetcode377)組合求和IV

                            確立狀態轉移方程需要深入理解問題,合理定義子問題,找到邊界條件(比如dp[0]),分析狀態之間的轉移關系(dp和dp之間的關系),并進行驗證。 遞歸是自頂向下,而dp是自下而上 這里是i作為目標值&…

                            解決aspose將Excel轉成PDF中文變成方框的亂碼問題

                            原文網址:解決aspose將Excel轉成PDF中文變成方框的亂碼問題_IT利刃出鞘的博客-CSDN博客 簡介 本文介紹如何解決aspose將Excel轉成PDF中文變成方框的亂碼問題。 問題描述 用aspose將word、excel等轉成PDF后,英文展示正常,但中文全部變成了…

                            Netty 核心原理與高并發場景實踐

                            在當今的網絡編程領域,隨著互聯網應用的不斷發展,對高并發、高性能網絡通信的需求日益增長。Netty 作為一款基于 Java 的異步事件驅動的網絡應用框架,憑借其卓越的性能和豐富的功能,成為了實現高并發網絡應用的首選工具。無論是在…

                            問題大集04-瀏覽器阻止從 本地 發起的跨域請求,因為服務器的響應頭 Access-Control-Allow-Origin 設置為通配符 *

                            1、問題 localhost/:1 Access to XMLHttpRequest at xxx(請求) from origin http://localhost:xxx(本地) has been blocked by CORS policy: The value of the Access-Control-Allow-Origin header in the response must not be t…

                            判斷192.168.1.0/24網絡中,當前在線的ip有哪些

                            需求:判斷192.168.1.0/24網絡中,當前在線的ip有哪些,并編寫腳本打印出來。 [rootopenEuler ~]# cat 1.sh #!/bin/bash for ip in $(seq 1 254); do ping -c 1 -W 1 "192.168.1.$ip" > /dev/null 2>&1 if [ $? …

                            vue-vite axios bug

                            axios-bug http proxy error Error: write ECONNABORTED 代碼寫法 一般baseURL不是單寫前綴就可以了嗎,為何要寫死就不會出現以上錯誤,求解。

                            【Spring】_SpringBoot配置文件

                            目錄 1.Spring Boot配置文件 1.1 Spring Boot 的配置文件類型及命名 1.2 properties和yml的優先級 2. properties配置文件 1.1 properties語法格式 1.2 自定義配置及配置文件的讀取 1.3 properties的缺點 3. yml配置文件 3.1 yml語法格式 3.2 自定義配置及配置文件的…

                            實操給觸摸一體機接入大模型語音交互

                            本文以CSK6 大模型開發板串口觸摸屏為例,實操講解觸摸一體機怎樣快速增加大模型語音交互功能,使用戶能夠通過語音在一體機上查詢信息、獲取智能回答及實現更多互動功能等。 在本文方案中通過CSK6大模型語音開發板采集用戶語音,將語音數據傳輸…

                            深入解析 FFmpeg 的 AAC 編解碼過程

                            深入解析 FFmpeg 的 AAC 編解碼過程 —— 技術詳解與代碼實現 AAC(Advanced Audio Coding) 是一種高效的有損音頻壓縮格式,因其高壓縮效率和良好的音質而被廣泛應用于流媒體、廣播和音頻存儲等領域。FFmpeg 是一個強大的多媒體處理工具,支持 AAC 的編碼和解碼。本文將詳細…

                            RabbitMQ 從入門到精通:從工作模式到集群部署實戰(一)

                            #作者:閆乾苓 文章目錄 RabbitMQ簡介RabbitMQ與VMware的關系架構工作流程RabbitMQ 隊列工作模式及適用場景簡單隊列模式(Simple Queue)工作隊列模式(Work Queue)發布/訂閱模式(Publish/Subscribe&#xff…

                            探索 Spring Cloud Alibaba:開啟微服務架構新時代

                            一、引言 在當今數字化浪潮中,軟件系統的規模和復雜度不斷攀升,傳統的單體架構逐漸難以滿足快速迭代、高并發處理以及靈活擴展的需求。微服務架構應運而生,它將一個大型的應用拆分成多個小型、自治的服務,每個服務專注于特定的業務…

                            Linux基礎命令之Nginx中的rewrite功能(重新)

                            一、什么是Rewrite Rewrite也稱URL Rewrite,即URL重寫,就是把傳入Web的請求重定向到其他URL的過程。 1. URL Rewrite最常見的應用是URL偽靜態化,是將動態頁面顯示為靜態頁面方式的一種技術。比如http://www.123.com/news/index.php?id123 使…

                            anaconda使用

                            anaconda配置鏡像源: 引用:https://zhuanlan.zhihu.com/p/17776864328 # 顯示所有的鏡像源 conda config --show channels # 設置鏡像源 conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/ conda config --add c…

                            DeepSeek 闡述 2025年前端發展趨勢

                            預測2025年前端的發展趨勢。首先,我需要考慮當前的前端 技術發展情況,以及近幾年的變化趨勢。比如,框架方面,React、Vue、Angular這些主流框架的更新方向和社區活躍度。可能用戶想知道未來哪些技術會更流行,或者需要學…

                            RK3568平臺開發系列講解(ConfigFS篇)ConfigFS核心數據結構

                            ??返回專欄總目錄 文章目錄 一、數據結構二、結構體關系三、案例3.1、configfs_subsystem 實例3.2、config_group 實例化四、屬性和方法五、config_item實例化沉淀、分享、成長,讓自己和他人都能有所收獲!?? 理解 ConfigFS 的核心數據結構對于深入使用和定制 ConfigFS 非…

                            【實戰篇】巧用 DeepSeek,讓 Excel 數據處理更高效

                            一、為何選擇用 DeepSeek 處理 Excel 在日常工作與生活里,Excel 是我們頻繁使用的工具。不管是統計公司銷售數據、分析學生成績,還是梳理個人財務狀況,Excel 憑借其強大的功能,如數據排序、篩選和簡單公式計算,為我們提供了諸多便利。但當面對復雜的數據處理任務,比如從…

                            微信小程序案例1——制作貓眼電影底部標簽導航欄

                            文章目錄 一、項目步驟1 新建一個無AppID的movie項目2將準備好的底部標簽導航圖標拷貝到movie項目下面(將圖標文件夾image放到項目文件夾里)3 打開App.json配置文件,在pages數組里添加4個頁面路徑:電影“pages/movie/movie”、影院“pages/cinema/cinema…

                            CSS 偽類(Pseudo-classes)的詳細介紹

                            CSS 偽類詳解與示例 在日常的前端開發中,CSS 偽類可以幫助我們非常精準地選擇元素或其特定狀態,從而達到豐富頁面表現的目的。本文將詳細介紹以下偽類的使用: 表單相關偽類 :checked、:disabled、:enabled、:in-range、:invalid、:optional、…