熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Oracle >> 正文

現實問題的細粒度審計,第 3 部分

2013-11-13 15:33:10  來源: Oracle 

  在本系列的前兩個部分中我向您介紹了細粒度審計 (FGA) 的概念它用來在 Oraclei Database 和更高版本中跟蹤選定的語句我還說明了如何在復雜的環境中(比如說在一個 Web 應用程序內部)通過應用程序上下文和客戶端標識符來使用這個特性這兩篇文章為您提供了足夠的信息使您可以為幾乎所有類型的數據庫系統(無論它有多復雜)構建一個 FGA 設置程序在這個第三部分同時也是最後一部分中我將說明 Oracle Database g 為表帶來的 FGA 增強
  
  Oraclei Database 中的 FGA
  讓我們簡要地重述一下 FGA 的好處關於完整的討論請參考本系列的第 部分和第 部分
  
  正規審計(通過 AUDIT 語句)記錄使用的語句 — 如 SELECT 或 INSERT — 以及誰發出它從哪一個終端什麼時候等等然而信息最重要的部分 — 哪條特定記錄被修改了以及數據本身的變化 — 沒有捕獲到相反許多用戶編寫觸發器來捕獲變化前後的數據值並把它們記錄在用戶自定義的表中但因為觸發器只可能在 DML 語句(如 insertupdate 和 delete)上使用所以訪問的一個主要的方面 — SELECT 語句 — 不能通過這種途徑來審計
  
  因此 FGA 的價值在於它只捕獲 SELECT 語句與觸發器和 Log Miner 工具一起FGA 提供了一種機制來審計各種類型的值修改和不涉及到修改的數據訪問
  
  FGA 不僅填補了審計 SELECT 語句的空白而且還提供了其它的一些引人注目的額外好處這些好處使得數據庫管理員的工作變得更加輕松例如FGA 允許一個用戶自定義的過程在指定的審計條件出現的時候執行因此您可以認為它是 SELECT 語句上的一個觸發器 — 這是一個在其它方式下沒有提供的功能這個技巧可能非常有用 — 例如任何時候當有人選擇了收入超過 百萬美元的員工的工資記錄時發送一封郵件給一個安全審計員以在用戶自定義的表中生成審計記錄這些表可以不受限制地進行處理(這與 SYS 擁有的 FGA_LOG$ 表不同)利用審計線索識別數據訪問類型以找出最可能的索引機制等等
  
  由於這些及其它的原因FGA 成為數據庫管理員工具箱中最重要的工具之一不過在 Oraclei Database 中它缺少一個重要的特性在 SELECT 語句之外的語句上使用
  
  所有類型的 DML
  在 Oracle Database g 中FGA 已變得很完善 — 它可以審計所有類型的 DML 語句而不只是 SELECT
  
  讓我們看一個例子在本系列的第 部分中我介紹了一個名稱為 ACCOUNTS 的表在那個表上定義的 FGA 策略為
  
  begin
    dbms_fgaadd_policy (
     object_schema  => BANK
     object_name   => ACCOUNTS
     policy_name   => ACCOUNTS_ACCESS
     audit_column  => BALANCE
     audit_condition => BALANCE >=
   );
  end;
  
  在 Oracle i Database 下這個策略只能審計 SELECT 語句然而在 Oracle Database g 中您可以擴展它使它包含 INSERTUPDATE 和 DELETE您可以通過指定一個新的參數來實現這個目的
  
  statement_types => INSERT UPDATE DELETE SELECT
  
  這個參數將在所有包括的語句類型上啟用審計您甚至可能考慮為每種語句類型創建單獨的策略這將允許您隨意地啟用和禁用策略 — 尤其是控制審計線索的創建以管理它們占用的空間不過statement_type 參數默認情況下只審計 SELECT 語句
  
  在策略中添加新的參數之後發出以下語句
  
  update accounts set balance = where balance >= ;
  
  這將使一條記錄插入到 FGA_LOG$ 表中注意這條記錄是由一個自動事務插入的即使您回滾 update 語句這條記錄也將存在您可以從另一個會話來檢查線索是否存在
  
  select lsqltext from fga_log$;
  
  LSQLTEXT
  
  update accounts set balance = where balance >=
  
  該行還包括其它所有的相關詳細信息(如表名稱策略名稱和事務 ID)
  
  與觸發器方法相比較
  那麼 FGA 能做什麼原來的基於觸發器的方法不能做的事情?
  
  在 Oracle Database g 之前DML 語句審計是在一個觸發器中進行的類似於以下方式(注意這不是真實的代碼只是一個代表性的示例)
  
  CREATE TRIGGER XXXXX
  ON Table
  AFTER INSERT OR UPDATE OR DELETE
  FOR EACH ROW
  BEGIN
    INSERT INTO AUDIT_LOG
    Old Value New Value Time
  END
  
  觸發器捕獲舊的值和新的值並填充 AUDIT_LOG 表如果需要還可以將它變為自動事務最大的問題是觸發器是對每行觸發的而不是每條語句一次例如以下語句
  
  update accounts set balance = where balance >= ;
  
  對全部 條記錄觸發在審計表中插入 這種方法可能嚴重地損害 update 語句的性能甚至可能因審計線索中的空間問題而導致失敗使用語句觸發器也無濟於事因為它不能捕獲個別記錄的任何新的或舊的值比較而言在 FGA 方法中只創建一條記錄並且插入只在每條語句上執行一次而不是每行一次 — 即使有的話對性能的影響也很小
  
  在 FGA 中您可以指定相關的列來限定審計線索僅在這些列被訪問時才創建在觸發器中通過使用觸發器定義的 WHERE這種功能也可以實現不過其中存在一個非常重要的差異 — 在觸發器中只有當列被修改時(而不是被訪問時)才檢查它們在 FGA 中無論何時列被訪問(無論它們被修改與否)審計就開始這個特性使得 FGA 比觸發器具有更多的功能
  
  另一個優點是 FGA 工具的適用性有時在一個視圖上定義的 INSTEAD OF 觸發器在基表上更新視圖另一個 INSTEAD OF 觸發器不能捕獲由其它的觸發器所作的修改因此這些修改不能被記錄然而FGA 是建立在視圖或表的基礎上的它能夠捕獲變化而不論變化來自哪裡 — 用戶語句或觸發器
  
  那麼是否存在觸發器比 FGA 更好的情況呢?可能有兩種情況
  
  記住FGA 通過一個自動事務來插入審計線索這種事務在它自己的上下文中提交當 DML 語句失敗或被回滾時插入的線索記錄不被回滾如果用戶更新了一些東西但沒有提交則不執行修改但不管怎樣將創建審計線索這可能導致在審計線索中產生幾個虛假的實際項目 — 一種不希望出現的潛在情況隨後使用通過閃回查詢捕獲的 SCN 號碼對表進行分析將可能揭露這個問題但這個過程可能非常復雜但如果這種風險是不可接受的那麼基於觸發器的方法將優於 FGA 成為首選
  
  FGA 記錄用戶發出的 SQL 語句和 SCN 號碼但不記錄在修改之前和之後的值必須使用一個單獨的工具來從表中通過閃回查詢取出這些值因為閃回查詢依賴於 UNDO 段中包含的信息(這些信息是有限的)因此這個工具可能不會從過去很久的時間點上取出舊的值基於觸發器的方法在源數據上捕獲變化因此保證舊的值和新的值都有記錄
  
  在變化期間 FGA 的行為
  數據始終在變化因此它有可能變得適用於審計條件 — 雖然之前它不適用於審計條件反之亦然這個問題帶來了一些關於 FGA 在不同情況下的行為的有趣問題考慮我們的例子其中在 UPDATE 上已經定義了 FGA 策略條件為 BALANCE >= 審計列是 BALANCE
  
  第 種情況
  
  之前BALANCE =
  
  用戶發出
  
  update accounts set balance = where ACCOUNT_NO =
  
  舊的和新的 balance 都小於 審計條件不滿足因此這條語句將不會被審計
  
  第 種情況
  
  之前BALANCE =
  
  用戶發出
  
  update accounts set balance = where ACCOUNT_NO =
  
  新的 balance 大於 審計條件滿足因此這條語句將 會被審計
  
  第 種情況
  
  之前BALANCE =
  
  用戶發出
  
  update accounts set balance = where ACCOUNT_NO =
  
  新的 balance 小於 但舊的 balance 大於 因此審計條件滿足這條語句將被審計
  
  第 種情況
  
  用戶插入一行其中有 BALANCE <
  
  insert into accounts values (X);
  
  因為 balance 不滿足審計條件所以這條語句不被審計如果 balance 列大於或等於 它將被審計
  
  第 種情況
  
  用戶插入一行其中 balance 的值為空
  
  insert into accounts (account_no status) values ( X);
  
  因為 balance 為空該列沒有任何默認值所以審計條件不滿足(比較 NULL >= 結果為 FALSE)這條語句不會被審計重要注意事項假設該列有一個大於 的默認值時這條語句仍然不會被審計即使插入行的 balance 列值大於
  
  所有相關的列?
  考慮在表 ACCOUNTS 上定義的一個策略如下
  
  begin
    dbms_fgaadd_policy (
     object_schema  => ANANDA
     obje
From:http://tw.wingwit.com/Article/program/Oracle/201311/16901.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.