眾所周知,在業務高峰期,某些針對Oracle數據庫的操作具有很高的風險,比如修改表結構、修改實例參數等等,如果沒有充分評估和了解這些操作所帶來的影響,這些操作很可能會導致故障,輕則導致應用錯誤,重則導致數據庫服務不可用。
另外,在非業務高峰期,某些看似風險不大的操作也可能會導致嚴重後果,比如不按管理流程修改表結構,如果這個表正好是Oracle GoldenGate復制組的一部分,修改了源端結構而沒有通知OGG的相關人員,沒有在目標端進行相同的操作,而DDL復制功能也沒有打開的情況下,就會導致復制進程故障,導致數據不一致,在某些應用場景下,這也是很嚴重的生產事故。
目前,傳統的應對方法還是強調管理,不管是客戶還是服務商都在不斷強調制度和規范,希望從制度建設和工程師的職業素養上著手,防止DBA的這種隨意的危險操作。
但是,管理制度畢竟是“軟性”的,把希望寄托在工程師自覺地遵守制度和“自我修養”上,並不能保證萬無一失。
Oracle提供的安全組件,可以用來限制、阻斷這種隨意的危險操作,用技術手段保證管理制度被遵守。
我們要討論的是Oracle數據庫的安全組件之一: Oracle Database Vault(DV),它的主要功能是保護敏感數據和職責分離。
DV保護敏感數據主要通過Realm(安全域),Realm可以簡單理解為敏感數據的集合,DV通過realm的配置來指定用戶是否可以訪問Realm保護的數據,如果在DV中沒有給訪問權限,即使是sysdba也無權訪問受Realm保護的數據,這是DV的核心功能,但不是本文的重點。
DV還有一個很重要的功能,Command Rules,就是可以按一定的判斷條件,允許或阻止數據庫用戶執行DDL、DML以及DCL命令,而且對特權用戶,包括sysdba都有效。這個功能正好可以滿足我們限制dba的需求。
大家如果想詳細了解DV的功能,可以訪問Oracle官網:http://www.oracle.com/technetwork/database/options/database-vault/index-085211.html
Oracle Database Vault最低支持的數據庫版本是9.2.0.8,早期是單獨的一個安裝包。從11g開始,Oracle的數據庫安裝介質中包含了這個組件,想要使用這個組件的用戶需要在安裝時勾選Database Vault選項。除了安裝相關的軟件組件,還需要在創建數據庫時,創建相關的數據庫對象。
Database Vault可以使用相關的存儲過程來實現命令行方式的配置、管理,也可以通過web管理界面來管理,在早期,必須安裝EM,才能使用web管理界面,從11gR2起,數據庫自帶的dbcontrol也可以進行web界面的管理了。
除了前面講到的Realm和Command Rules,還有兩個概念要介紹一下,一個是Factor(認證因子),另一個是Rule sets(規則集)。
Factor(認證因子)就是可以用於進行條件判斷的因素,比如客戶端主機名,客戶端IP等等,Oracle內置了一些常用的Factor,用戶也可以自己創建Factor,Factor可以是一個表達式,也可以是一個存儲過程的返回值。
Rule Sets簡單說就是判斷條件的集合,類似SQL的where之後的判斷條件,當規則集的判斷條件返回為true時,DV允許用戶訪問數據或執行特定的命令。Rule sets中的Rule可以引用Factor做判斷。
這個例子是最簡單的,不需要使用Factor,只使用Rule Sets和Command Rules就可以完成。我們用數據庫用戶test來示范:
登錄DV的管理頁面:
創建一個Rule Set,名字叫”Can not drop table in business time”,選擇Any True,意思是說規則集中的規則(判斷條件)任何一個為True,規則集判斷結果就為True。其實All True就相當於and,Any True就相當於or
這兩個RULE也很好理解,就是判斷當前時間是否為業務時間,在這裡,為了便於做實驗,把業務時間定義為11:45~11:55,這個規則集判斷當前時間,如果當前時間不在業務時間內,規則集返回True。
然後創建Command Rule,如下圖:
這個Command Rule的意思就是指定的Rule Set 返回True時,允許drop test用戶下的表,否則即使是sysdba或表的owner也無權drop table。
效果:
其他我們想控制的Alter Table等Command Rule的設置方法類似。
實際工作中,我們經常遇到這樣的情況:應用開發人員都有應用用戶的口令,他們可以隨意用SQL*PLUS或PL/SQL Developer這樣的工具連接到生產庫上,如果一時搞混了生產庫和測試庫,就可能有悲劇發生。最好的解決方法就是限制應用用戶所用的工具,應該只允許中間件以這個用戶連接,其他工具都不允許連接。
這個例子會用到Factor,首先我們創建一個Factor,取用戶會話的Module:
用SQL*PLUS登錄數據庫,驗證這個Factor取出的值:
引用Factor的方法就是DVF.F$+Factor name,在Linux本機登錄,Module就是上面顯示的那樣,在windows上遠程登錄,Module的值是“SQLPLUS.EXE”。
下面創建Rule Set,名字叫“Limit SQL*PLUS“,
注意是“Any True”
創建RULE:
創建Command Rule:
按照這種規則,除了SYS,SYSTEM,DV_MANAGER之外的用戶,不管是本地還是遠程,都不能用SQL*PLUS登錄。
用SQL Developer登錄正常:
現實場景中,我們希望DBA遵守制度,比如在修改表結構之前,通知OGG相關人。或者為了增加安全性,要求DBA做的重大操作,必須得到老板的批准。DV可以利用Dual Key功能滿足這種需求。
簡單說,我們可以寫一個存儲過程,判斷流程中需要通知的人是否在線,如果在線,才允許執行相應的操作。而那個需要被通知的人,只要擁有connect數據庫的權限就行,他(她)的登錄動作就變成了一種授權或被通知後的確認。
具體步驟:
首先給DV的管理員授權,讓用戶可以訪問字典視圖和編寫存儲過程:
SQL> GRANT CREATE PROCEDURE TO dv_manager;
Grant succeeded.
SQL> GRANT SELECT ON V_$SESSION TO dv_manager;
Grant succeeded.
我們假設授權的用戶是“BOSS“,而執行操作的用戶是”TEST“,相應的判斷BOSS是否在線的存儲過程如下:
CREATE OR REPLACE FUNCTION check_boss_logged_in
return varchar2
authid definer as
v_session_number number := 0;
v_allow varchar2(10) := 'TRUE';
v_deny varchar2(10) := 'FALSE';
BEGIN
SELECT COUNT(*) INTO v_session_number
FROM SYS.V_$SESSION
WHERE USERNAME = 'BOSS';
IF v_session_number > 0
THEN RETURN v_allow;
ELSE
RETURN v_deny;
END IF;
END check_boss_logged_in;
/
使用DV管理員創建這個Function,然後授權給DVSYS:
SQL>GRANT EXECUTE ON check_boss_logged_in to DVSYS;
創建Rule Set:
Name:Dual Key
Evaluation Options:Any True
規則如下:
創建Command Rule:
這個Command Rule達到的效果是,如果test用戶想alter owner為test的table,必須boss用戶同時在線,否則報錯,無權限。如果是其他人修改test用戶下的表,不受這個限制。
最後的效果:
BOSS用戶沒有在線,那麼TEST用戶alter table報錯
只有在test用戶通知了boss用戶,或者按照流程,得到了boss用戶的批准,boss用戶用登錄數據庫這個動作來代表確認,test用戶才可以修改表結構: