Site Logo

IzzySoft


Das inoffizielle Android-HandbuchDas inoffizielle Android-Handbuch
Für 16,99 € bei Amazon kaufen
Das inoffizielle Android-SystemhandbuchDas inoffizielle Android-Systemhandbuch
Für 6,99 € bei Amazon kaufen
Die besten Android-Apps: Android-Systemtools. Fotografie & Freizeit. Büro-Tools, Schule und StudiumDie besten Android-Apps: Android-Systemtools. Fotografie & Freizeit. Büro-Tools, Schule und Studium
Für 2,94 € bei Amazon kaufen
Stand: 2024-03-28 04:07
Preis & Verfügbarkeit können sich geändert haben.

Oracle Auditing

Überblick

Oracle bietet für das Auditing verschiedene technische Ansätze. Je nach Datenbankversion und gewünschtem Einsatzgebiet, ist naturgemäß eine Möglichkeit der anderen vorzuziehen. Um die Entscheidung zu erleichtern, hier zunächst ein grober Überblick über die unterstützten Methoden, sowie ihre Vor- und Nachteile:

Methode Auditing Anmerkung
Oracle Audit Audit von Objekten und Privilegien Zum Aktivieren muss die Datenbank neu gestartet werden
System triggers Audit von Objekten und Systemereignissen Muss selbst programmiert werden
Fine Grained Auditing (FGA) DML/SELECT Auditing Erst ab 9i verfügbar. DML erst ab 10g
System Logs Wichtige Systemereignisse werden automatisch protokolliert Kein Auditing im eigentlichen Sinn

Inhalt

Auditing Methoden

Nachdem zunächst ein grober Überblick gegeben ist, wollen wir uns die Methoden ein wenig genauer anschauen:

Oracle Audit

Der große Nachteil dieser Methode ist, dass die Einrichtung einen Neustart der Datenbank erfordert – was in produktiven Umgebungen nicht immer eine Option ist (ist diese Option nicht gegeben, muss auf eine der anderen Methoden ausgewichen werden). Dieser Neustart muss erfolgen, nachdem man in der init.ora den Parameter audit_trail gesetzt hat. Mögliche Werte für diesen Parameter sind abhängig von der eingesetzten Oracle Version; wir wollen hier nur audit_trail = db betrachten, und für weitere Werte auf die Oracle Dokumentation verweisen.

Nach dem Neustart der Datenbank passiert zunächst einmal solange nichts, bis auch wirklich ein Ziel für das Auditing vorgegeben wurde. Erst dann können mögliche Ergebnisse aus den DBA-Views (dba_audit_*) gelesen werden. Die gewünschten Ziele "markiert" man mit dem Befehl AUDIT. Die Syntax des AUDIT Befehls ist:

audit <statement_option|privilege_option> [by user] [by <session|access>] [whenever <successful|unsuccessful>]

Als Ziele bieten sich an:

Welche Informationen werden nun von Oracle protokolliert, sobald das Auditing aktiviert und auch Ziele definiert wurden?

Diese Informationen sammelt Oracle bei genannter Einstellung (audit_trail=db) in der Datenbank. Abfragen kann man die Zugriffe über die View DBA_AUDIT_TRAIL (bzw. USER_AUDIT_TRAIL auf User-Ebene). Welche Objekte/Privilegien gerade überwacht werden, findet sich auch in den entsprechenden Views (*_AUDIT_STATEMENT, *_AUDIT_OBJECT, etc. – ein Blick auf das Ergebnis der Abfrage SELECT view_name FROM dba_views WHERE view_name LIKE '%AUDIT%' gibt eine ausführliche Liste).

Das Auditing einzelner Objekte/Privilegien lässt sich gezielt mit NOAUDIT wieder abschalten. Um die ganze "Audit-Engine" stillzulegen, bedarf es allerdings wiederum eines Datenbank Neustarts, nachdem der Parameter audit_trail wieder entfernt bzw. auf FALSE gesetzt wurde.

Fazit: Wenn ein Neustart der Datenbank kein K.O. Kriterium ist, lässt sich mit Oracle Audit eine gute Analyse mit detaillierten Ergebnissen durchführen.

System Triggers

Trigger bieten eine Möglichkeit, sich selbst ein angepasstes Auditing zu erstellen, welches auch keinen Neustart der Datenbank erfordert. Dafür erfordern sie allerdings ein wenig Handarbeit: Zuerst muss eine Tabelle angelegt werden, in welcher die Ereignisse sodann protokolliert werden können. Und anschließend gilt es dann auch noch, sich die passenden Trigger zu bauen - was den komplizierteren Teil dieser Aufgabe darstellt. Dafür kann das Ergebnis dann sehr genau an die Anforderungen angepasst werden - was sonst nur mit [Fine Grained Auditing(#fga) möglich ist (und auch erst ab 9i bzw. gar 10g).

Was lässt sich nun alles triggern? Wie schon in der Übersicht aufgezeigt, sind dies Systemereignisse auf Datenbank- und Schemaebene, DML Statements und INSTEAD OF Triggers auf Views (die uns im Sinne des Auditing allerdings hier nicht interessieren). Generell können Trigger ausgeführt werden:

Um nun aber unser Auditing zu realisieren, müssen wir etwas tiefer in die Trigg-Kiste greifen. Die Syntax für CREATE TRIGGER lässt sich leicht aus dem Oracle-Handbuch heraussuchen. Die eigentliche Aktion, die der Trigger nun durchführen soll (nämlich einen Eintrag in unsere Logging Tabelle zu erstellen, und zwar mit allen gewünschten Details), ist da schon etwas aufwändiger. Ein ausbaufähiges Beispiel hierfür findet sich in der Oracle Dokumentation, unter "Using Triggers", im Abschnitt "Auditing with Triggers: Examples" – wer also an dieser Methode interessiert ist, möge bitte dort weiterlesen.

Nicht (mehr) benötigte Trigger kann man mit DROP TRIGGER löschen oder, falls man später wieder auf selbigen zurückgreifen möchte, mit ALTER TRIGGER..DISABLE abschalten.

Fazit: Etwas aufwändiger - kann aber zu einem maßgeschneiderten Auditing führen. Allerdings nicht für SELECT Statements geeignet.

Fine Grained Auditing (FGA)

Während man bis zur Version 8i nur aus obigen beiden (und der letzten) Methoden wählen konnte, kommt ab Version 9i eine interessante Alternative hinzu: Das Fine Grained Auditing. Der Name lässt es bereits vermuten: Hier kann die Anpassung bis ins Detail gehen. Und das weit weniger Umständlich, als mit unseren gerade behandelten Triggern. Dafür sind sie aber auch auf SELECT und DML Statements beschränkt, bei Oracle 9i sogar nur auf erstere.

Das Ganze wird gesteuert über das Package dbms_fga, und lässt sich bis auf Spaltenebene granulieren. So ist es nicht nur möglich, alle Zugriffe auf eine Tabelle zu protokollieren - sondern man kann es sogar so konfigurieren, dass z.B. nur alle Zugriffe auf eine Tabelle protokolliert werden, bei dem der Wert für eine Spalte eine bestimmte Größe übersteigt. Großartige Programmierkünste sind dafür nicht notwendig - die Aufrufe sind leicht verständlich. Nähere Details finden sich in der Oracle Dokumentation sowie auf den im Anhang verlinkten Seiten.

Fazit: Spätestens ab 10g die zu bevorzugende Methode, wenn SELECT und/oder DML Statements zu überwachen sind.

DML FGA mit Oracle 9i

In Version 9i unterstützt Oracle lediglich FGA für SELECT Statements. Mit ein paar Tricks lässt sich das in geringem Umfang aufbohren, indem man FGA mit Triggern kombiniert. Um z.B. INSERT Statements auf eine Tabelle mit zu protokollieren, auf die man bereits FGA angesetzt hat, erstellt man sich einen Trigger AFTER INSERT ON <tabelle>, der aus den Daten des INSERT Statements ein SELECT generiert, und so den gerade eingefügten Datensatz wieder abfragt - und schon greift das FGA wieder. Um dieses "künstliche SELECT" von den regulären zu unterscheiden, hilft es z.B., ein Feld mit AS insert_cmd umzubenennen.

Das ist freilich etwas aufwändiger, da man für jede Tabelle manuell einen passenden Trigger generieren muss. Mit ein paar Programmierkenntnissen kann man sich jedoch ein kleines PL/SQL Skript erstellen, welches das Statement über die Informationen aus dem Data Dictionary für jede beliebige Tabelle generieren kann.

Einfacher ist es, wenn man nur feststellen möchte, ob auf ein Objekt überhaupt noch Zugriffe stattfinden, und wenn ja, von wem. Für diesen Fall lassen sich recht einfache kleine Prozeduren verwenden, die ich hier ausnahmsweise einmal quoten möchte:

Auditing aktivieren:

CREATE OR REPLACE PROCEDURE iz_audit_on (user_name IN VARCHAR2,table_name IN VARCHAR2) IS
 -- Establish auditing to the table specified by the parameters
 -- Param user_name : Owner of the table
 -- Param table_name: Name of the table
 PROCEDURE do_trigger(uname IN VARCHAR2,tname IN VARCHAR2) IS
   -- create the trigger
   -- uname: Owner
   -- tname: Table
   stmt VARCHAR2(2000);
 BEGIN
   stmt   := 'CREATE OR REPLACE TRIGGER '||uname||'.iz_audit_'||tname
           ||' BEFORE INSERT OR UPDATE OR DELETE ON '||uname||'.'||tname
           ||' DECLARE cnum NUMBER; BEGIN '
           ||' IF INSERTING THEN SELECT COUNT(*) AS insert_cmd'
           ||'   INTO cnum FROM '||uname||'.'||tname||' WHERE 1=0;'
           ||' ELSIF DELETING THEN SELECT COUNT(*) AS delete_cmd'
           ||'   INTO cnum FROM '||uname||'.'||tname||' WHERE 1=0;'
           ||' ELSIF UPDATING THEN SELECT COUNT(*) AS update_cmd'
           ||'   INTO cnum FROM '||uname||'.'||tname||' WHERE 1=0;'
           ||' END IF; END;';
   EXECUTE IMMEDIATE stmt;
 EXCEPTION
   WHEN OTHERS THEN
     dbms_output.put_line('! Could not create trigger on table '||uname||'.'||tname||': ');
	 dbms_output.put_line('- '||stmt);
	 dbms_output.put_line('- '||SQLERRM);
 END;
 PROCEDURE do_audit(uname IN VARCHAR2,tname IN VARCHAR2) IS
   -- enable auditing and then call the do_trigger procedure
   -- uname: Owner
   -- tname: Table
   stmt VARCHAR2(2000);
 BEGIN
   dbms_fga.add_policy(
     object_schema=>uname,
     object_name=>tname,
     policy_name=>tname||'_SELECT'
   );
   -- create the trigger only if the FGA policy was created (otherwise
   -- exception handler fires)
   do_trigger(uname,tname);
 EXCEPTION
   WHEN OTHERS THEN
     dbms_output.put_line('! Could not create FGA policy for table '||uname||'.'||tname||': '||SQLERRM);
 END;
BEGIN
 do_audit(user_name,table_name);
END;
/

Auditing deaktivieren:

CREATE OR REPLACE PROCEDURE iz_audit_off (user_name IN VARCHAR2,table_name IN VARCHAR2) IS
 -- Disable the auditing established with iz_audit_on
 -- Param user_name : Owner
 -- Param table_name: Name of the audited table
 PROCEDURE do_trigger(uname IN VARCHAR2,tname IN VARCHAR2) IS
   -- drop triggers
   -- uname: Owner
   -- tname: Table
   stmt VARCHAR2(2000);
 BEGIN
   stmt   := 'DROP TRIGGER '||uname||'.iz_audit_'||tname;
   EXECUTE IMMEDIATE stmt;
 EXCEPTION
   WHEN OTHERS THEN
     dbms_output.put_line('! Could not drop trigger on table '||uname||'.'||tname||': ');
	 dbms_output.put_line('- '||stmt);
	 dbms_output.put_line('- '||SQLERRM);
 END;
 PROCEDURE do_audit(uname IN VARCHAR2,tname IN VARCHAR2) IS
   -- drop FGA policies and call the do_trigger procedure
   -- uname: Owner
   -- tname: Table
   stmt VARCHAR2(2000);
 BEGIN
   dbms_fga.drop_policy(
     object_schema=>uname,
     object_name=>tname,
     policy_name=>tname||'_SELECT'
   );
 EXCEPTION
   WHEN OTHERS THEN
     dbms_output.put_line('! Could not drop FGA policy for table '||uname||'.'||tname||': '||SQLERRM);
 END;
BEGIN
 do_audit(user_name,table_name);
 -- drop the trigger even if FGA policy could not be dropped:
 do_trigger(uname,tname);
END;
/

Beide Prozeduren werden jeweils mit den Parametern UserName (d.h. das Schema, in welchem sich das zu überwachende Objekt befindet) und TableName (also dem Namen der zu überwachenden Tabelle) aufgerufen. Die erste Prozedur, iz_audit_on(), erstellt zunächst eine Policy für SELECT Statements auf die angegebene Tabelle, und legt anschließend den Trigger für die DML Statements an. Beides jeweils in dem Schema, in welchem sich auch das zu überwachende Objekt befindet (wem das nicht gefällt, der kann es ja im Skript einfach anpassen). Die zweite Prozedur (iz_audit_off()) macht den Vorgang wieder rückgängig – etwa bereits generierte Eintrage in der Tabelle SYS.FGA_LOG$ werden jedoch nicht wieder entfernt. Die Policies werden nach dem Schema <Tabellenname>_SELECT benannt, die Trigger heißen jeweils <Username>.IZ_AUDIT_<Tabellenname>.

Zu den Prozeduren sei noch angemerkt, dass es sich hier nur um "Rohfassungen" als "Anschauungsmaterial" handelt. Sie funktionieren zwar "Out-of-the-Box" (auch wenn ich selbstverständlich keinerlei Haftung und Gewährleistung übernehme), jedoch sollten speziell die Exceptions noch ein wenig besser angepasst werden.

Die geloggten Informationen finden sich in diesem Fall, wie beim FGA, in der genannten Tabelle SYS.FGA_LOG$, und lassen sich natürlich auch bequem über die entsprechende DBA-View DBA_FGA_AUDIT_TRAIL abfragen.

Fazit: Sollte Oracle Audit z.B. aufgrund des notwendigen Neustarts der Datenbank nicht in Frage kommen, und sich eine Migration auf 10g ebenfalls nicht anbietet, ist dies ein guter Kompromiss für das Überwachen von SELECT und/oder DML Statements – und ggf. auch alles andere, was Trigger hergeben.

System Logs

Die System-Logfiles sind zwar kein Auditing im eigentlichen Sinne - es lässt sich aber doch einige "Audit-Information" hier entnehmen. So werden sämtliche Startups/Shutdowns der Datenbank, die Logfile-Wechsel und vieles mehr protokolliert. Alle oben genannten Auditing Funktionen lassen sich nicht rückwirkend aktivieren – die Logs werden jedoch generell geschrieben, und geben so noch manche Information preis, die im alert_log zu finden sind.

Fazit: Grundlegende Informationen lassen sich auch mit einfachsten Mitteln finden …

Ein einfacher Login-Monitor

Ohne viel Zuarbeit (und ohne weitere Voraussetzungen) lässt sich ein einfacher Login-Monitor realisieren, der die Anmeldung eines gegebenen Benutzers im alert_log protokolliert:

CREATE OR REPLACE TRIGGER monitor_log
  AFTER LOGON ON DATABASE
  DECLARE
    line v$session%rowtype;
  BEGIN
    IF sys.login_user = 'MONITOR' THEN
      SELECT * INTO line FROM v$session WHERE sid=TO_NUMBER(SUBSTR(dbms_session.unique_session_id,1,4),'XXXX');
      dbms_system.ksdwrt(2,'MONITOR logged in from "'||line.machine||'" using "'||line.module||'" as OS-User "'||line.osuser);
    END IF;
  EXCEPTION
    WHEN OTHERS THEN dbms_system.ksdwrt(2,'Monitor logged in!');
  END;
/

Hierbei lassen sich natürlich die protokollierten Details beliebig ergänzen. Im Beispiel-Code wird der Login Zeitpunkt (automatisch bei einem neuen eintrag von Oracle ergänzt), der Name des Rechners, von dem der Login erfolgte, das vom Benutzer verwendete Programm, sowie der OS-Benutzer protokolliert. Ein Eintrag sieht dann etwa so aus:

Tue Oct 16 10:25:30 2007 MONITOR logged in from "machine.domain.com" using "sqlplus@machine.domain.com (TNS V1-V3)" as OS-User "monitor"

Überblick / Allgemein

Oracle Audit

Trigger

Fine Grained Auditing:

2020-11-18