I den här artikeln kommer jag att fortsätta med Oracle Database Security och jag kommer att presentera några viktiga fakta om standarddatabasrevision, revisionstriggers och revisionspolicyer i Oracle. Databasrevision har två komponenter:övervakning och ihållande registrering av etablerade databasaktivitetsuppsättningar och händelser. Syften med databasrevision är icke-avvisande, utredning av misstänkta aktiviteter, upptäckt av problem som genereras av konfigurationer avseende auktorisering (resursåtkomst), efterlevnad av aktuell lagstiftning och kontroll.
Standardrevision
Vilka aktiviteter granskar vi? Databasstart och -stopp samt anslutningar som görs av databasadministratören granskas implicit av Oracle och data lagras automatiskt i operativsystemet. Tabellen nedan visar andra aktiviteter som kan övervakas:
Var förvarar vi de granskade aktiviteterna?
- i databasen , med hjälp av databasrevisionsspår, där vi har två möjligheter:
- audit_trail =DB
vilket kan göras med följande kod:alter system set audit_trail=db scope=spfile;
- audit_trail =DB
- audit_trail =DB,EXTENDED
med följande kod:alter system set audit_trail= db, extended scope=spfile;
Skillnaden mellan DB och DB,EXTENDED är att den andra fyller i kolumnerna SQLBIND och SQLTEXT CLOB i tabellen SYS.AUD$.
- audit_trail =DB,EXTENDED
- extern , med användning av revisionsspår för operativsystem, med följande möjligheter:
- audit_trail =OS
och koden som används är:alter system set audit_trail=os scope=spfile;
- audit_trail =XML och AUDIT_FILE_DEST =sökvägen (underförstått är $ORACLE_BASE/admin/$ORACLE_SID/adump)
med koden:alter system set audit_trail=xml scope=spfile;
- audit_trail =OS
För att hitta den aktuella konfigurationen av de lagrade granskade aktiviteterna kan man köra följande fråga, skriven med gemener:
select value from v$parameter where name='audit_trail';
Mer användbara kommandon:
[tabell id=43 /]
Låt oss nu ta några exempel på databasrevision.
Här är ett exempel på en standardrevision med granskad information lagrad i databasen:
Den granskade informationen består av SELECT-satserna som körs i databastabellerna.
I SQL Developer, kör följande skript:
alter system set audit_trail= db, extended scope=spfile; AUDIT SELECT TABLE;
Sedan måste databasen startas om. För att göra det, anslut i SQLPlus-terminalen med användarnamn sys som sysdba / lösenord och kör följande satser:
SHUTDOWN IMMEDIATE STARTUP
Observera att ovanstående storlekar skiljer sig från ett system till ett annat.
För att verifiera om granskningsspåret är korrekt inställt, kör följande fråga:
select value from v$parameter where name='audit_trail';
eller:
show parameter audit_trail;
När du vill stoppa granskningen, utför:
NOAUDIT SELECT TABLE;
För att se vilka uttalanden som registrerades av revisionen kan du använda:
select dbms_lob.substr( sqltext, 4000, 1 ) from SYS.AUD$ where OBJ$NAME IN ('EMPLOYEES','DEPARTMENTS','JOBS','LOCATIONS');
eller
select count(*), OBJ$NAME, USERID from SYS.AUD$ where OBJ$NAME IN ('EMPLOYEES','DEPARTMENTS','JOBS','LOCATIONS') group by rollup (OBJ$NAME, USERID);
Ett annat exempel är för standardrevision med granskade data lagrade i en XML-fil, i standardsökvägen.
alter system set audit_trail=xml scope=spfile; AUDIT SELECT, INSERT, UPDATE, DELETE ON employees WHENEVER NOT SUCCESSFUL;
Återigen, starta om databasen:anslut till SQLPlus-terminalen med användarnamnet sys som sysdba / lösenord och kör kommandona SHUTDOWN IMMEDIATE och STARTUP.
Sedan, varje gång en fråga för att välja, infoga, uppdatera och ta bort misslyckas i personaltabellen, bör den registreras i XML-filen.
När vi vill stoppa revisionen kör vi följande kommandon i databasutvecklingsmiljön:
NOAUDIT ALL; NOAUDIT ALL ON DEFAULT;
Och återställ standardrevisionsspåret:
alter system set audit_trail=db scope=spfile;
Nedan är ett exempel på en del av en XML-revisionsfil:
Hur tar vi bort den granskade informationen?
Volymen av de granskade uppgifterna kan bli mycket stora på grund av antalet granskade aktiviteter och deras frekvens. Det är därför det rekommenderas att regelbundet arkivera de granskade uppgifterna och ta bort dem från produktionssystemet.
Om de granskade uppgifterna lagras i databasen (databasrevisionsspår), kan vi använda raderingssatser (men bara efter att vi har arkiverat uppgifterna!):
DELETE FROM SYS.AUD$;
Du kan välja att ta bort den granskade informationen för ett specifikt databasobjekt, till exempel en tabell som heter produkter:
DELETE FROM SYS.AUD$ WHERE OBJ$NAME='PRODUCTS';
Revisionsutlösare
En trigger är ett PL/SQL-block eller CALL-satsen för en PL/SQL-procedur som exekveras automatiskt varje gång en händelse inträffar. Det finns två typer av utlösare:på databasnivå (databassatser) och på applikationsnivå (till exempel genom att trycka på en knapp på ett Oracle-formulär). De utlösare som används för granskning är utlösare på databasnivå. De klassificeras i följande kategorier:
- DML-utlösare – där en DML-sats utlöses i en tabell. Dessa utlösare kan exekveras en gång på kommandonivån oavsett antalet poster (triggers på satsnivån) eller så kan de exekveras FÖR VARJE RAD (triggers på postnivån). Typer av utlösare på rekordnivå:FÖRE STATEMENT, EFTER STATEMENT, FÖRE VARJE RAD, EFTER VARJE RAD;
- I STÄLLET FÖR utlösare – där en DML-sats utlöses på en vy;
- SYSTEM-utlösare – utlöses av händelser som att starta/stoppa databasen, DDL-satser, användarinloggning/utloggning. Typer av systemutlösare:EFTER HÄNDELSE, FÖRE HÄNDELSE.
Frågar SYS.TRIGGER$ tabellen eller ALL_TRIGGERS view erbjuder information om alla utlösare på databasnivå. Till exempel kan den distinkta triggertypen från databasen hittas enligt följande:
SELECT DISTINCT TRIGGER_TYPE FROM ALL_TRIGGERS;
Vyn DBA_TRIGGERS ger information om de utlösare som skapas automatiskt av Oracle-produkterna vid installationen. Om vi vill hitta information om SYSTEM-triggarna ('INNE HÄNDELSE' och 'EFTER HÄNDELSE'), kan vi köra följande sats:
SELECT SUBSTR(OWNER,1,20) OWNER ,SUBSTR(TRIGGER_NAME,1,30), TRIGGER_NAME, SUBSTR(TRIGGERING_EVENT,1,30) TRIGGERING_EVENT, TRIGGER_TYPE FROM DBA_TRIGGERS WHERE TRIGGER_TYPE='BEFORE EVENT' OR TRIGGER_TYPE='AFTER EVENT' ORDER BY TRIGGER_TYPE DESC;
Vid installationen skapas DML-utlösare automatiskt på HR-användarschemat:
SELECT SUBSTR(TABLE_NAME,1,20) TABLE_NAME, SUBSTR(TRIGGER_TYPE,1,30) TRIGGER_TYPE,TRIGGER_BODY FROM DBA_TRIGGERS WHERE OWNER='HR';
För granskning kan vi skapa anpassade triggers för att registrera önskad information, men man bör skapa en speciell tabell för att lagra den granskade informationen.
Det är viktigt att se till att de utvecklade triggarna inte påverkar den normala databasaktiviteten. Syftet med revision är att passivt övervaka den normala, dagliga databasaktiviteten och att lagra den för senare analys. Följaktligen rekommenderas det inte att skapa ISTADEN FÖR utlösare för att returnera resultaten från måltabellerna till granskningstabellen.
DML-utlösare på programsatsnivå kan samexistera med DML-utlösare på postnivå. Ordningen för samtalet är:
- utlösa BEFORE-satsen
- för varje berörd post
- utlösare BEFORE-post
- aktuell DML-åtgärd
- utlösa EFTER-post
- utlösa AFTER-satsen
Användardefinierade triggers kommer endast att exekveras om, enligt Oracle, påståendet är korrekt och kan inträffa. För en felaktig DML-sats eller en som bryter mot en begränsning, kommer ett fel att returneras och triggern kommer inte att exekveras. Därför rekommenderas det för revision att använda speciellt LMD-utlösare på uttalandenivå.
Exempel på granskningsutlösare:
Låt oss anta att vi vill skapa en trigger för att registrera i en revisionstabell (kallad TAB_AUDIT_EMP) information om DML-utlåtanden som fastställer löner över 20 000 (valutan är inte viktig här) för företagets anställda. Vi vill lagra i TAB_AUDIT_EMP sekvensnumret för frågan, användarnamnet, sessionen, värden och datumet.
Detta kan göras med följande:
CREATE TABLE TAB_AUDIT_EMP (secv_id NUMBER(3) PRIMARY KEY, username VARCHAR2(20), session_nr NUMBER(10), hostname VARCHAR2(100), query_date DATE ); CREATE SEQUENCE secv_aud_emp START WITH 1 INCREMENT BY 1; CREATE OR REPLACE TRIGGER huge_salary AFTER INSERT OR UPDATE OR DELETE OF SALARY ON EMPLOYEES FOR EACH ROW WHEN (NEW.salary>20000) BEGIN INSERT INTO TAB_AUDIT_EMP VALUES(secv_aud_emp.NEXTVAL , sys_context('userenv', 'session_user'), sys_context('userenv', 'sessionid'), sys_context('userenv', 'host'), sysdate); END;
Antag att vi gör en löneändring för de anställda på en specifik avdelning:
UPDATE EMPLOYEES SET SALARY=25000 WHERE ID_DEPARTMENT = 1;
Och sedan verifierar vi övervakningen:
select secv_id, substr(username,1,20) username, session_nr, substr(hostname,1,30) hostname, query_date from TAB_AUDIT_EMP;
Revisionspolicyer
Den tredje revisionsmetoden avser revisionspolicyer. Definitionen av en revisionspolicy innehåller följande:
- specifikation av objektet (schema, objektnamn, kolumner) som är föremål för övervakning
- specifikation av de åtgärder som granskats för ett objekt (SELECT, INSERT, UPDATE, DELETE):implicit är det SELECT
- specifikation av de villkor som måste uppfyllas för att registrera den granskade informationen, det görs i WHEN-klausulen i utlösaren och är valfritt
- en händelsehanterare som dessutom hanterar händelsen, vilket den är valfri.
En revisionspolicy kan vara aktiv (ENABLED status) eller inaktiv (DISABLED status). Listan över revisionspolicyerna kan erhållas genom att fråga vyn ALL_AUDIT_POLICIES:
SELECT POLICY_TEXT, ENABLED FROM ALL_AUDIT_POLICIES
För administration av revisionspolicy har vi paketet DBMS_FGA. För att kunna använda detta paket är det nödvändigt att ge behörighet till de användare som ska skriva PL/SQL-kod:
grant execute on dbms_fga to username;
Exempel på revisionspolicy:
Vi vill skapa en revisionspolicy för att registrera DML-utlåtanden som modifierar cheferna (MANAGER_ID) i tabellen AVDELNINGAR. Vi kan välja att skapa en hanterare för policyn, kallad proc_audit_alert, som informerar oss om en ändring angående chefen:
CREATE OR REPLACE PROCEDURE proc_audit_alert ( object_schema VARCHAR2, object_name VARCHAR2, policy_name VARCHAR2 ) AS BEGIN DBMS_OUTPUT.PUT_LINE('Alert! Manager Changed !'); END;
Och policyn kan vara:
CREATE OR REPLACE PROCEDURE proc_audit_manager AS BEGIN DBMS_FGA.ADD_POLICY ( object_schema=>'ADMINDB', object_name=>'DEPARTMENTS', policy_name=>'proc_audit_manager', audit_column=>'ID_MANAGER', enable=>false, statement_types=>'UPDATE', handler_module=>'proc_audit_alert' ); DBMS_FGA.ENABLE_POLICY ( object_schema=>'ADMINDB', object_name=>'DEPARTMENTS', policy_name=>'proc_audit_manager'); END;
Observera att object_schema, object_name, policy_name, audit_column, statement_types och handler_module måste anpassas till den policy du vill skriva.
Sedan kör vi proceduren:
EXECUTE proc_audit_manager;
Vi kan verifiera om policyn är aktiverad:
SELECT ENABLED, POLICY_NAME FROM ALL_AUDIT_POLICIES WHERE OBJECT_NAME='DEPARTMENTS';
Kontrollera sedan om proceduren och policyn fungerar korrekt genom att utföra en uppdatering:
UPDATE DEPARTMENTS SET ID_MANAGER=2 WHERE ID_DEPARTAMENT=1;
Sammanfattningsvis är granskning nödvändig för varje databas och metoderna ovan hjälper dig att hitta en misstänkt aktivitet som kan påverka din databassäkerhet. För mer information om Oracle-databasrevision, se bibliografin nedan.
Bibliografi:
- http://www.datadisk.co.uk/html_docs/oracle/auditing.htm
- http://docs.oracle.com/cd/B10501_01/server.920/a96521/audit.htm
- https://docs.oracle.com/cd/E11882_01/server.112/e10575/tdpsg_auditing.htm#TDPSG50000