pgAudit - 開源PostgreSQL審計日誌

翻譯自官方文檔:傳送門html

能力有限,若有錯誤請指正git

介紹

PostgreSQL審計擴展(pgAudit)經過標準的PostgreSQL日誌記錄工具提供詳細的會話和(或)對象審計日誌記錄。github

pgAudit的目標是爲PostgreSQL用戶提供生成審計日誌的能力,這些日誌一般須要符合政府、金融或ISO認證。sql

審計是對我的或組織帳戶的正式檢查,一般由獨立機構進行。pgAudit收集的信息被正確地稱爲審計跟蹤或審計日誌。本文檔中使用了審計日誌這一術語。數據庫

爲何使用 pgAudit?

基本語句日誌記錄能夠由 log_statement = all 的標準日誌記錄工具提供。這對於監視和其餘使用是能夠接受的,可是沒有提供審計所需的詳細程度。僅僅擁有對數據庫執行的全部操做的列表是不夠的。還必須可以找到審計人員感興趣的特定報表。標準的日誌記錄功能顯示了用戶的請求,而pgAudit關注的是數據庫知足請求時發生的事情的細節。編程

例如,審計人員可能想要驗證某個特定的表是在文檔化的維護窗口中建立的。對於grep來講,這彷佛是一項簡單的工做,可是若是您看到這樣一個(故意混淆的)例子:後端

BEGIN
    EXECUTE 'CREATE TABLE import' || 'ant_table (id INT)';
END $$;

標準日誌記錄會給您這樣的結果:併發

LOG:  statement: DO $$
BEGIN
    EXECUTE 'CREATE TABLE import' || 'ant_table (id INT)';
END $$;

在動態建立表的狀況下,查找感興趣的表可能須要一些代碼知識。這並不理想,由於只搜索表名更可取。這就是pgAudit的用武之地。對於相同的輸入,它將在日誌中產生如下輸出:函數

AUDIT: SESSION,33,1,FUNCTION,DO,,,"DO $$
BEGIN
    EXECUTE 'CREATE TABLE import' || 'ant_table (id INT)';
END $$;"
AUDIT: SESSION,33,2,DDL,CREATE TABLE,TABLE,public.important_table,CREATE TABLE important_table (id INT)

不只 DO 塊被記錄,子語句2還包含 CREATE TABLE 的全文,其中包含語句類型、對象類型和全限定名稱,以方便搜索。工具

當記錄 SELECT語句 和 DML語句 時,pgAudit能夠配置爲記錄語句中引用的每一個關係的單獨條目。查找涉及特定表的全部語句不須要解析。實際上,咱們的目標是,語句文本主要是爲深度取證提供的,不該該被要求進行審計。

使用注意事項

根據設置的不一樣,pgAudit能夠生成大量日誌記錄。當心地肯定在您的環境中須要審計哪些日誌,以免日誌記錄過多。

例如,在OLAP環境中工做時,審計大型事實表中的日誌插入可能不太明智。日誌文件的大小多是插入的實際數據大小的許多倍,由於日誌文件表示爲文本。因爲日誌一般與操做系統一塊兒存儲,這可能致使磁盤空間很快耗盡。在不可能將審計日誌記錄限制到某些表的狀況下,請確保在測試時評估性能影響,並在日誌捲上分配大量空間。對於OLTP環境也是如此。即便插入卷沒有那麼高,審計日誌記錄的性能影響仍然會顯著影響延遲。

爲了限制SELECT和DML語句記錄的關係審計的數量,考慮使用對象審計日誌記錄(請參閱對象審計)。對象審計日誌容許選擇要記錄的關係,從而減小整體日誌量。然而,當添加新關係時,它們必須顯式地添加到對象審計日誌記錄中。在這種狀況下,將指定的表排除在日誌以外幷包含全部其餘表的編程解決方案多是一個不錯的選擇。

PostgreSQL版本兼容性

pgAudit支持PostgreSQL 9.5或更高版本。

爲了支持在每一個PostgreSQL發行版中引入的新功能,pgAudit爲每一個PostgreSQL主版本(當前的PostgreSQL 9.5 - 11)維護一個獨立的分支,該分支將以相似於PostgreSQL項目的方式進行維護。

除了bug修復以外,尚未爲穩定的分支計劃進一步的開發。新的開發(若是有的話)將嚴格用於下一個未發佈的主要版本PostgreSQL。

與PostgreSQL主要版本相關的pgAudit版本以下:

  • pgAudit v1.3.X 用於支持 PostgreSQL 11.

  • pgAudit v1.2.X 用於支持 PostgreSQL 10.

  • pgAudit v1.1.X 用於支持 PostgreSQL 9.6.

  • pgAudit v1.0.X 用於支持 PostgreSQL 9.5.

編譯和安裝

獲取源代碼:

git clone https://github.com/postgres/postgres.git

切換分支:

git checkout REL_11_STABLE

編譯 PostgreSQL:

./configure
make
make install

切換到 contrib 目錄:

cd contrib

獲取 pgAudit 擴展源碼:

git clone https://github.com/pgaudit/pgaudit.git

切換到 pgAudit 目錄:

cd pgaudit

切換分支:

git checkout REL_11_STABLE

編譯、安裝、迴歸測試:

make
make install
make check

設置

設置只能由超級用戶修改。容許普通用戶更改他們的設置將會破壞審計日誌。

設置能夠全局指定(在 postgresql.conf 或使用 ALTER SYSTEM ... SET),在數據庫級別(使用 ALTER DATABASE ... SET),在角色級別(使用ALTER ROLE ... SET)。注意,設置不是經過普通角色繼承繼承的, SET ROLE 不會改變用戶的pgAudit設置。這是角色系統的限制,而不是pgAudit所固有的。

pgAudit擴展必須經過shared_preload_libraries載入。不然,將在加載時引起錯誤,而且不會發生審計日誌記錄。此外,在設置 pgaudit.log 以前必須調用 CREATE EXTENSION pgaudit 。若是刪除了pgaudit擴展並須要從新建立pgaudit擴展,那麼 pgaudit.log 必須先取消設置,不然會引起錯誤。

pgaudit.log

指定會話審計日誌記錄將記錄哪類語句。可能的值是:

  • READ: SELECTCOPY 當源是關係或查詢時。
  • WRITE: INSERT, UPDATE, DELETE, TRUNCATE, 和COPY 當目標是一個關係時。
  • FUNCTION: 函數調用和 DO 塊.
  • ROLE: 與角色和特權相關的語句: GRANT, REVOKE, CREATE/ALTER/DROP ROLE.
  • DDL: 不包含在 ROLE 類中的全部DDL.
  • MISC: 其餘的一些命令, 好比 DISCARD, FETCH, CHECKPOINT, VACUUM.

可使用逗號分隔的列表提供多個類,經過在類前面加 - 號能夠減去類(參閱 會話審計日誌記錄).

默認值爲 none.

pgaudit.log_catalog

指定若是語句中的全部關係都在pg_catalog中,則應該啓用會話日誌記錄。禁用此設置將減小psql和PgAdmin等工具在日誌中大量查詢catalog的噪音。

默認值爲 on.

pgaudit.log_level

指定將用於日誌條目的日誌級別 (詳見有效級別的消息嚴重級別),但注意不容許出現 ERROR, FATAL, 和PANIC 。此設置用於迴歸測試,對於測試或其餘目的的最終用戶也可能有用。

默認值爲 log.

pgaudit.log_parameter

指定審計日誌記錄應該包括與語句一塊兒傳遞的參數。當參數出現時,它們將包含在語句文本以後的CSV格式中。

默認值爲 off.

pgaudit.log_relation

指定會話審計日誌記錄是否應該爲SELECT或DML語句中引用的每一個關係(表、視圖等)建立單獨的日誌條目。對於不使用對象審計日誌記錄的詳盡日誌記錄,這是一個有用的快捷方式。

默認值爲 off.

pgaudit.log_statement_once

指定日誌記錄是包含帶有語句/子語句組合的第一個日誌條目的語句文本和參數,仍是包含每一個條目。禁用此設置將減小冗長的日誌記錄,但可能會使肯定生成日誌條目的語句變得更加困難,儘管語句/子語句對以及進程id應該足以識別與前一個條目一塊兒記錄的語句文本。

默認值 off.

pgaudit.role

指定用於對象審計日誌記錄的主角色。能夠經過將多個審計角色授予主角色來定義它們。這容許多個組負責審計日誌記錄的不一樣方面。

該項沒有默認值.

會話審計日誌記錄

會話審計日誌提供用戶在後端執行的全部語句的詳細日誌。

配置

使用pgaudit.log設置啓用會話日誌記錄。

啓用全部DML和DDL的會話日誌記錄,並記錄DML語句中的全部關係:

set pgaudit.log = 'write, ddl';
set pgaudit.log_relation = on;

啓用除MISC以外的全部命令的會話日誌記錄,併發出 NOTICE審計日誌消息:

set pgaudit.log = 'all, -misc';
set pgaudit.log_level = notice;

實例說明

在這個示例中,會話審計日誌記錄用於記錄DDL和SELECT語句。注意,因爲未啓用WRITE類,insert語句沒有記錄日誌

SQL語句:

set pgaudit.log = 'read, ddl';

create table account
(
    id int,
    name text,
    password text,
    description text
);

insert into account (id, name, password, description)
             values (1, 'user1', 'HASH1', 'blah, blah');

select *
    from account;

日誌輸出:

AUDIT: SESSION,1,1,DDL,CREATE TABLE,TABLE,public.account,create table account
(
    id int,
    name text,
    password text,
    description text
);
AUDIT: SESSION,2,1,READ,SELECT,,,select *
    from account

對象審計日誌記錄

影響特定關係的對象審計日誌記錄語句。只支持 SELECT, INSERT, UPDATEDELETE 命令。對象審計日誌中不包括 TRUNCATE

對象審計日誌記錄旨在成爲pgaudit.log = 'read, write'的細粒度替代。所以,將它們結合使用可能沒有任何意義,可是一種可能的場景是使用會話日誌記錄來捕獲每一個語句,而後用對象日誌記錄來補充這些語句,以得到關於特定關係的更多細節。

配置

對象級審計日誌是經過角色系統實現的。pgaudit.role 設置定義用於審計日誌記錄的角色。當審計角色對執行的命令具備權限或從另外一個角色繼承權限時,將記錄一個關係(表、視圖等)。這容許您有效地擁有多個審計角色,即便在任何上下文中只有一個主角色。

設置pgaudit.role爲auditor,並授予account表的SELECT和DELETE權限。account表上的任何SELECT或DELETE語句都將被記錄:

set pgaudit.role = 'auditor';

grant select, delete
   on public.account
   to auditor;

實例說明

在這個示例中,使用對象審計日誌記錄來講明如何使用粒度方法來記錄SELECT和DML語句。注意,account表上的日誌記錄由列級權限控制,而account_role_map表上的日誌記錄是表級的。

SQL語句:

set pgaudit.role = 'auditor';

create table account
(
    id int,
    name text,
    password text,
    description text
);

grant select (password)
   on public.account
   to auditor;

select id, name
  from account;

select password
  from account;

grant update (name, password)
   on public.account
   to auditor;

update account
   set description = 'yada, yada';

update account
   set password = 'HASH2';

create table account_role_map
(
    account_id int,
    role_id int
);

grant select
   on public.account_role_map
   to auditor;

select account.password,
       account_role_map.role_id
  from account
       inner join account_role_map
            on account.id = account_role_map.account_id

日誌輸出:

AUDIT: OBJECT,1,1,READ,SELECT,TABLE,public.account,select password
  from account
AUDIT: OBJECT,2,1,WRITE,UPDATE,TABLE,public.account,update account
   set password = 'HASH2'
AUDIT: OBJECT,3,1,READ,SELECT,TABLE,public.account,select account.password,
       account_role_map.role_id
  from account
       inner join account_role_map
            on account.id = account_role_map.account_id
AUDIT: OBJECT,3,1,READ,SELECT,TABLE,public.account_role_map,select account.password,
       account_role_map.role_id
  from account
       inner join account_role_map
            on account.id = account_role_map.account_id

格式

審計條目被寫入標準日誌記錄工具,並以逗號分隔的格式包含如下列。只有在刪除每一個日誌條目的日誌行前綴部分時,輸出才符合CSV格式。

  • AUDIT_TYPE - 會話或對象.

  • STATEMENT_ID - 此會話的惟一語句ID。每一個語句ID表示後端調用。即便沒有記錄某些語句,語句id也是連續的。當記錄多個關係時,語句ID可能有多個條目。

  • SUBSTATEMENT_ID - 主語句中每一個子語句的順序ID。例如,從一個查詢中調用函數。即便沒有記錄一些子語句,子語句id也是連續的。當記錄多個關係時,子語句ID可能有多個條目。

  • CLASS - 例如 READ, ROLE (詳見 pgaudit.log).

  • COMMAND - 例如 ALTER TABLE, SELECT

  • OBJECT_TYPE - TABLE, INDEX, VIEW等. 可用於SELECT、DML和大多數DDL語句。

  • OBJECT_NAME - 徹底限定對象名(例如public.account)。可用於SELECT、DML和大多數DDL語句。

  • STATEMENT - 在後端執行的語句。

  • PARAMETER - 若是設置了pgaudit.log_parameter 後,該字段將包含引用CSV的語句參數。

使用log_line_prefix添加知足審計日誌需求所需的任何其餘字段。典型的日誌行前綴多是 '\%m \%u \%d: ' ,它將爲每一個審計日誌提供日期/時間、用戶名和數據庫名。

警告

對象重命名被記錄在它們重命名的名稱下。例如,從新命名錶將產生如下結果:

ALTER TABLE test RENAME TO test2;

AUDIT: SESSION,36,1,DDL,ALTER TABLE,TABLE,public.test2,ALTER TABLE test RENAME TO test2

能夠將命令記錄屢次。例如,當在建立時使用指定的主鍵建立表時,主鍵的索引將被獨立記錄,而對於create條目下的索引將建立另外一個審計日誌。可是,多個條目將包含在一個語句ID中。

Autovacuum 和 Autoanalyze 不會被記錄。

事務進入停止狀態後執行的語句將不會被審計記錄。可是,致使錯誤的語句和在停止的事務中執行的任何後續語句將被標準日誌記錄工具做爲錯誤記錄。

相關文章
相關標籤/搜索