了解如何使用 Oracle 數(shù)據(jù)庫的細粒度審計特性來跟蹤對表中特定行的只讀訪問 — 以及更多信息
傳統(tǒng)的 Oracle 數(shù)據(jù)庫審計選件允許您在宏觀級別上跟蹤用戶在對象上所執(zhí)行的操作 — 例如,如果您審計對某個表的 SELECT 語句,則可以跟蹤是誰從表中選擇了數(shù)據(jù)。但是,您不知道他們選擇了什么。利用數(shù)據(jù)操縱語句 — 如 INSERT、UPDATE 或 DELETE — 您可以通過使用觸發(fā)器或使用 Oracle LogMiner 實用程序來分析歸檔日志,從而捕獲任何的更改。因為簡單的 SELECT 語句是不操縱數(shù)據(jù)的,它們既不啟動觸發(fā)器,也不記入到那些以后可以進行挖掘的歸檔日志中,所以這兩種技術(shù)在涉及到 SELECT 語句的地方無法滿足要求。
Oracle9i Database 推出了一種稱為細粒度審計 (FGA) 的新特性,它改變了這種局面。該特性允許您將單個的 SELECT 語句聯(lián)同用戶提交的確切語句一起進行審計。除了簡單地跟蹤語句之外,F(xiàn)GA 還通過在每次用戶選擇特定的數(shù)據(jù)集時執(zhí)行一段代碼,提供了一種方法來模擬用于 SELECT 語句的觸發(fā)器。在分為三部分的這一系列文章中,我將說明如何使用 FGA 解決實際問題。這第一部分的主要內(nèi)容是構(gòu)建基本的 FGA 系統(tǒng)。
示例安裝
我們的示例基于一個銀行系統(tǒng),已經(jīng)通過應(yīng)用程序級的審計按照傳統(tǒng)提供了用戶訪問特定數(shù)據(jù)的審計線索。但是,只要用戶使用諸如 SQL*Plus 等工具從應(yīng)用程序以外的地方訪問數(shù)據(jù),該系統(tǒng)就不能滿足要求。在本文中,我將說明作為 DBA 的您能夠如何使用 FGA 來完成捕獲用戶對特定行的 SELECT 訪問的任務(wù),無論訪問的工具或機制是什么。
在我們的示例中,數(shù)據(jù)庫有一個名為 ACCOUNTS 的表,由模式 BANK 擁有,其結(jié)構(gòu)如下:
Name Null? Type ---------------- -------- ------------ ACCT_NO NOT NULL NUMBER CUST_ID NOT NULL NUMBER BALANCE NUMBER(15,2)
為了構(gòu)造一個能夠?qū)θ魏卧诖吮碇羞x擇的用戶進行審計的系統(tǒng),您需要定義對該表的 FGA 策略如下:
begin dbms_fga.add_policy ( object_schema=>'BANK', object_name=>'ACCOUNTS', policy_name=>'ACCOUNTS_ACCESS' ); end;
這段代碼必須由具有執(zhí)行程序包 dbms_fga 權(quán)限的用戶來執(zhí)行。但是,為了提高安全性,建議不要對用戶 BANK(將要被審計的表的所有者)授予執(zhí)行權(quán)限;而應(yīng)該將權(quán)限授予一個安全的用戶(比如 SECMAN),此用戶應(yīng)該執(zhí)行添加策略的過程。
在定義了策略以后,當用戶以通常的方式對表進行查詢時,如下所示:
select * from bank.accounts;
審計線索記錄此操作。您可以使用以下語句查看線索:
select timestamp, db_user, os_user, object_schema, object_name, sql_text from dba_fga_audit_trail; TIMESTAMP DB_USER OS_USER OBJECT_ OBJECT_N SQL_TEXT --------- ------- ------- ------- -------- ---------------------- 22-SEP-03 BANK ananda BANK ACCOUNTS select * from accounts
注意名為 DBA_FGA_AUDIT_TRAIL 的新視圖,它記錄細粒度的訪問信息。其中顯示了審計事件的時間標記、查詢者的數(shù)據(jù)庫用戶 ID、操作系統(tǒng)用戶 ID、查詢中所使用表的名稱和所有者,最后還有確切的查詢語句。在 Oracle9i Database 之前不可能得到這種信息,但隨著 FGA 的推出,獲得此信息變得輕而易舉。
在 Oracle9i Database 中,F(xiàn)GA 只能捕獲 SELECT 語句。利用 Oracle Database 10g,F(xiàn)GA 還可以處理 DML 語句 — INSERT、UPDATE 和 DELETE — 使其成為完整的審計特性。在本系列的第 3 部分,我將詳細說明這些新的功能。
審計列和審計條件
讓我們更詳細地檢查前面的示例。我們要求審計對該表所使用的任何 SELECT 語句。但是在現(xiàn)實中,可能不必要這樣做,并且這樣可能會使存儲線索的審計表承受不起。當用戶選擇含有敏感信息的余額列時,銀行可能需要進行審計,但當用戶選擇特定客戶的賬號時,可能不需要進行審計。列 BALANCE(選擇它可觸發(fā)審計)稱為審計列,在此情況下,dbms_fga.add_policy 過程的參數(shù)指定該列如下:
audit_column => 'BALANCE'
如果每次用戶從表中選擇時都記錄審計線索,則線索的大小將增長,導(dǎo)致空間和管理問題,因此您可能希望只有在滿足特定條件時進行審計,而不是每次都進行審計。也許只有當用戶訪問極為富有的戶主賬號時,銀行需要審計 — 例如,只有當用戶選擇了余額為 11,000 美元或更多的賬號時需要審計。這種類型的條件稱為審計條件,并作為一項參數(shù)傳遞到 dbms_fga.add_policy 過程,如下所示:
audit_condition => 'BALANCE >= 11000'
讓我們來看這兩個參數(shù)如何起作用?,F(xiàn)在策略定義的形式類似于:
begin dbms_fga.add_policy ( object_schema=>'BANK', object_name=>'ACCOUNTS', policy_name=>'ACCOUNTS_ACCESS', audit_column => 'BALANCE', audit_condition => 'BALANCE >= 11000' ); end;
在此情況下,只有當用戶選擇列 BALANCE 并且檢索的行包含大于或等于 $11,000 的余額時,才會審計該操作。如果這兩個條件中有一個不為真,則該操作不會被寫入到審計線索中。表 1 中的示例演示了何時審計操作和何時不審計操作的各種情況。
優(yōu)化器模式
FGA 需要基于開銷的優(yōu)化 (CBO),以便正確地工作。在基于規(guī)則的優(yōu)化時,只要用戶從表中進行選擇,無論是否選擇了相關(guān)的列,都始終生成審計線索,增加了誤導(dǎo)項目出現(xiàn)的可能性。為使 FGA 正確地工作,除了在實例級啟用 CBO 之外,在 SQL 語句中應(yīng)該沒有規(guī)則暗示,并且必須至少使用評估選項對查詢中的所有表進行分析。
管理 FGA 策略
在前文中您看到了如何添加 FGA 策略。要刪除策略,您可以使用以下語句:
begin dbms_fga.drop_policy ( object_schema => 'BANK', object_name => 'ACCOUNTS', policy_name => 'ACCOUNTS_ACCESS' ); end;
對于更改策略而言,沒有隨取隨用的解決方案。要更改策略中的任何參數(shù),必須刪除策略,再使用更改后的參數(shù)添加策略。
有時您可能需要臨時禁用審計收集 — 例如,如果您希望將線索表移動到不同的表空間或者要刪除線索表。您可以按如下方法禁用 FGA 策略:
begin dbms_fga.enable_policy ( object_schema => 'BANK', object_name => 'ACCOUNTS', policy_name => 'ACCOUNTS_ACCESS', enable => FALSE ); end;
要重新啟用它,可使用同一函數(shù),但是將參數(shù) enable 設(shè)置為 TRUE。
處理器模塊
FGA 的功能不只是記錄審計線索中的事件;FGA 還可以任意執(zhí)行過程。過程可以執(zhí)行一項操作,比如當用戶從表中選擇特定行時向?qū)徲嬚甙l(fā)送電子郵件警告,或者可以寫到不同的審計線索中。這種存儲代碼段可以是獨立的過程或者是程序包中的過程,稱為策略的處理器模塊。實際上由于安全性原因,它不必與基表本身處于同一模式中,您可能希望特意將它放置在不同的模式中。由于只要 SELECT 出現(xiàn)時過程就會執(zhí)行,非常類似于 DML 語句啟動的觸發(fā)器,您還可以將其看作 SELECT 語句觸發(fā)器。以下參數(shù)指定將一個處理器模塊指定給策略:
handler_schema 擁有數(shù)據(jù)過程的模式
handler_module 過程名稱
處理器模塊還可以采用程序包的名稱來代替過程名稱。在這種情況下,參數(shù) handler_module 在 package.procedure 的格式中指定。
FGA 數(shù)據(jù)字典視圖
FGA 策略的定義位于數(shù)據(jù)字典視圖 DBA_AUDIT_POLICIES 中。表 2 包含該視圖中一些重要列的簡短描述。
審計線索收集在 SYS 擁有的表 FGA_LOG$ 中。對于 SYS 擁有的任何原始表,此表上的某些視圖以對用戶友好的方式顯示信息。DBA_FGA_AUDIT_TRAIL 是該表上的一個視圖。表 3 包含該視圖中重要列的簡短描述。
一個重要的列是 SQL_BIND,它指定查詢中使用的綁定變量的值 — 這是顯著增強該工具功能的一項信息。
另一個重要的列是 SCN,當發(fā)生特定的查詢時,它記錄系統(tǒng)更改號。此信息用于識別用戶在特定時間看到了什么,而不是現(xiàn)在的值,它使用了閃回查詢,這種查詢能夠顯示在指定的 SCN 值時的數(shù)據(jù)。我將在本系列的第 2 部分中詳細說明這種功能強大的特性。
視圖和 FGA
到目前為止我已經(jīng)討論了在表上應(yīng)用 FGA;現(xiàn)在讓我們來看如何在視圖上使用 FGA。假定在 ACCOUNTS 表上定義視圖 VW_ACCOUNTS 如下:
create view vw_accounts as select * from accounts;
現(xiàn)在,如果用戶從視圖中而不是從表中進行選擇:
select * from vw_accounts;
您將看到以下審計線索:
select object_name, sql_text from dba_fga_audit_trail; OBJECT_NAME SQL_TEXT ----------- ------------------------------------------------- ACCOUNTS select * from vw_accounts
注意,是基表名稱而不是視圖名稱出現(xiàn)在 OBJECT_NAME 列中,因為視圖中的選擇是從基表中進行選擇。但是,SQL_TEXT 列記錄了用戶提交的實際語句,而這正是您希望了解的。
|
如果您只希望審計對視圖的查詢而不是對表的查詢,可以對視圖本身建立策略。通過將視圖名稱而不是表的名稱傳遞給打包的過程 dbms_fga.add_policy 中的參數(shù) object_name,可以完成這項工作。隨后 DBA_FGA_AUDIT_TRAIL 中的 OBJECT_NAME 列將顯示視圖的名稱,并且不會出現(xiàn)有關(guān)表訪問的附加記錄。
其它用途
除了記錄對表的選擇訪問,F(xiàn)GA 還可用于某些其它情況:
結(jié)論
FGA 使您在 Oracle 數(shù)據(jù)庫中支持隱私和職能策略。因為審計發(fā)生在數(shù)據(jù)庫內(nèi)部而不是應(yīng)用程序中,所以無論用戶使用的訪問方法是什么(通過諸如 SQL*Plus 等工具或者應(yīng)用程序),都對操作進行審計,允許進行非常簡單的設(shè)置。
下一次我將討論高級 FGA 技術(shù)以及 Oracle Database 10g 中的新特性,這些特性使 FGA 的功能極為強大,適用于所有類型的審計情況。
Arup Nanda (arup@proligence.com) 是 IntelliClaim 的首席數(shù)據(jù)庫設(shè)計人員,該公司位于 Connecticut 的 Norwalk,提供對衛(wèi)生保健保險索賠管理高度安全和基于規(guī)則的優(yōu)化。他是 2003 年度 Oracle DBA 獎的獲得者,并與他人合作編著了即將出版的 Oracle 隱私安全性審計(Rampant TechPress 出版,2003)。
表 1:演示何時審計操作以及何時不審計操作的各種情況
SQL 語句 | 審計狀態(tài) |
select balance from accounts; | 進行審計。用戶選擇了在添加策略時所指定的審計列 BALANCE。 |
select * from accounts; | 進行審計。即使用戶沒有明確指定列 BALANCE,* 也隱含地選擇了它。 |
select cust_id from accounts where balance < 10000; | 進行審計。即使用戶沒有明確指定列 BALANCE,where 子句也隱含地選擇了它。 |
select cust_id from accounts; | 不進行審計。用戶沒有選擇列 BALANCE。 |
select count(*) from accounts; | 不進行審計。用戶沒有明確或隱含地選擇列 BALANCE。 |
表 2:數(shù)據(jù)字典視圖 DBA_AUDIT_POLICIES 中重要的列
OBJECT_SCHEMA | 對其定義了 FGA 策略的表或視圖的所有者 |
OBJECT_NAME | 表或視圖的名稱 |
POLICY_NAME | 策略的名稱 — 例如,ACCOUNTS_ACCESS |
POLICY_TEXT | 在添加策略時指定的審計條件 — 例如,BALANCE >= 11000 |
POLICY_COLUMN | 審計列 — 例如,BALANCE |
ENABLED | 如果啟用則為 YES,否則為 NO |
PF_SCHEMA | 擁有策略處理器模塊的模式(如果存在) |
PF_PACKAGE | 處理器模塊的程序包名稱(如果存在) |
PF_FUNCTION | 處理器模塊的過程名稱(如果存在) |
表 3:DBA_FGA_AUDIT_TRAIL 視圖中重要的列
SESSION_ID | 審計會話標識符;與 V$SESSION 視圖中的會話標識符不同 |
TIMESTAMP | 審計記錄生成時的時間標記 |
DB_USER | 發(fā)出查詢的數(shù)據(jù)庫用戶 |
OS_USER | 操作系統(tǒng)用戶 |
USERHOST | 用戶連接的機器的主機名 |
CLIENT_ID | 客戶標識符(如果由對打包過程 dbms_session.set_identifier 的調(diào)用所設(shè)置) |
EXT_NAME | 外部認證的客戶名稱,如 LDAP 用戶 |
OBJECT_SCHEMA | 對該表的訪問觸發(fā)了審計的表所有者 |
OBJECT_NAME | 對該表的 SELECT 操作觸發(fā)了審計的表名稱 |
POLICY_NAME | 觸發(fā)審計的策略名稱(如果對表定義了多個策略,則每個策略將插入一條記錄。在此情況下,該列顯示哪些行是由哪個策略插入的。) |
SCN | 記錄了審計的 Oracle 系統(tǒng)更改號 |
SQL_TEXT | 由用戶提交的 SQL 語句 |
SQL_BIND | 由 SQL 語句使用的綁定變量(如果存在) |