The new version of DB2 9.5 has enhanced DB2 audit facility significantly and now it makes a perfect sense for the DBAs to start using it. The traditional notion on any audit (DB2 or Oracle) is that it is very expensive. That is not the case now as you have the options to configure audit the way you want.
DB2 audit has two work play.
- System Administrator do audits at the instance level
- Security Administrator do audits at the database level
The SYSADMs used to be very powerful in DB2 but not any more. Their powers (SYSADM and DBADM) have been curtailed as it is becoming more and more important to be able to audit what SYSADM or DBADM do in DB2.
I will explain DB2 audit by giving an example that you can do in your DB2 on your laptop. Once you understand it well, you can implement it on your DB2.
Steps for DB2 Audit
- Configure db2 audit active and archive path
- Create Audit tables
- Create a SECADM user
- SYSADM grants SECADM to the new user.
- SECADM creates policies to audit SYSADM and DBAs
Copy this sample script on your Windows laptop to learn DB2 audit
AuditSetup.CMD file – Download scripts here
TITLE %~n0.CMD - Learn Audit SET OUTFILE=%~n0_OUTPUT.TXT @ECHO off cls ECHO Executed by: %USERNAME% Machine: %COMPUTERNAME% On %OS% %DATE% ECHO Executed by: %USERNAME% Machine: %COMPUTERNAME% On %OS% %DATE% > %OUTFILE% ECHO. >> %OUTFILE% set db2instance=db2 REM ------------------------------------------------------------------- REM Security Lab 04 - Audit Facility Setup REM ------------------------------------------------------------------- REM Create C:\db2audit directory IF EXIST C:\db2audit\nul ( rmdir "C:\db2audit" /s/q > NUL ) IF NOT EXIST C:\db2audit\nul ( mkdir C:\db2audit > NUL 2>&1 ) REM Create C:\db2auditArchive directory IF EXIST C:\db2auditArchive\nul ( rmdir "C:\db2auditArchive" /s/q > NUL ) IF NOT EXIST C:\db2auditArchive\nul ( mkdir C:\db2auditArchive > NUL 2>&1 ) REM Create C:\db2auditExtract directory IF EXIST C:\db2auditextract\nul ( rmdir "C:\db2auditExtract" /s/q > NUL ) IF NOT EXIST C:\db2auditExtract\nul ( mkdir C:\db2auditExtract > NUL 2>&1 ) ECHO. >> %OUTFILE% ECHO --------------------------------------------------------------------- >> %OUTFILE% ECHO Change Audit and Archive Directory >> %OUTFILE% ECHO --------------------------------------------------------------------- >> %OUTFILE% ECHO. >> %OUTFILE% db2audit configure datapath "C:\db2audit" archivepath "C:\db2auditArchive" >> %OUTFILE% ECHO. >> %OUTFILE% ECHO --------------------------------------------------------------------- >> %OUTFILE% ECHO Creating Audit Tables to hold the DB2 audit data >> %OUTFILE% ECHO --------------------------------------------------------------------- >> %OUTFILE% ECHO. >> %OUTFILE% db2 CONNECT TO SAMPLE > NUL db2 CREATE SCHEMA AUDIT > NUL db2 SET CURRENT SCHEMA = 'AUDIT' > NUL db2 drop table audit.audit > NUL db2 drop table audit.checking > NUL db2 drop table audit.objmaint > NUL db2 drop table audit.secmaint > NUL db2 drop table audit.sysadmin > NUL db2 drop table audit.validate > NUL db2 drop table audit.context > NUL db2 drop table audit.execute > NUL db2 drop table audit.audit > NUL db2 -tvf "%DB2PATH%\MISC\db2audit.ddl" >> %OUTFILE% db2 CONNECT RESET > NUL ECHO. >> %OUTFILE% ECHO --------------------------------------------------------------------- >> %OUTFILE% ECHO Create a Security Administrator User SECPOT (SECADM authority) >> %OUTFILE% ECHO --------------------------------------------------------------------- >> %OUTFILE% ECHO. >> %OUTFILE% CALL :CreateUser SECPOT ECHO. >> %OUTFILE% ECHO --------------------------------------------------------------------- >> %OUTFILE% ECHO As SYSADM, Grant SECADM to user SECPOT who is Security Administrator >> %OUTFILE% ECHO --------------------------------------------------------------------- >> %OUTFILE% ECHO. >> %OUTFILE% db2 CONNECT TO SAMPLE >> %OUTFILE% db2 -v grant secadm on database to user SECPOT >> %OUTFILE% db2 CONNECT RESET >> %OUTFILE% ECHO. >> %OUTFILE% ECHO --------------------------------------------------------------------- >> %OUTFILE% ECHO As SECADM, Create Audit policies on SAMPLE Database >> %OUTFILE% ECHO --------------------------------------------------------------------- >> %OUTFILE% ECHO. >> %OUTFILE% db2 CONNECT TO SAMPLE USER SECPOT USING SECPOT12345 >> %OUTFILE% db2 drop audit policy CHECK_POLICY > NUL db2 drop audit policy SENSITIVE_DATA_POLICY > NUL db2 -v CREATE AUDIT POLICY CHECK_POLICY CATEGORIES ^ VALIDATE STATUS BOTH, ^ CHECKING STATUS FAILURE, ^ OBJMAINT STATUS BOTH, ^ SECMAINT STATUS BOTH, ^ CONTEXT STATUS NONE, ^ AUDIT STATUS BOTH, ^ SYSADMIN STATUS BOTH ^ ERROR TYPE AUDIT >> %OUTFILE% db2 -v CREATE AUDIT POLICY SENSITIVE_DATA_POLICY ^ CATEGORIES EXECUTE WITH DATA STATUS BOTH ERROR TYPE AUDIT >> %OUTFILE% db2 commit > NUL db2 CONNECT RESET > NUL GOTO :EOF :CreateUser setlocal REM Create user, if it does not exists net user %1 2>NUL > NUL IF %ERRORLEVEL% EQU 2 ( ECHO CREATING USER %1 NET USER /ADD %1 %112345 2>NUL > NUL ) ELSE ( ECHO User %1 already exists ) ECHO. endlocal
After you have run AuditSetup.CMD to setup audits, I will show how SYSADM does auditing at the instance level and how SECADM does auditing at the database level.
Instance Level Auditing by SYSADM
InstanceAudit.CMD file – Download scripts here
TITLE %~n0.CMD - Instance Auditing using db2audit tool SET OUTFILE=%~n0_OUTPUT.TXT @ECHO off cls ECHO Executed by: %USERNAME% Machine: %COMPUTERNAME% On %OS% %DATE% ECHO Executed by: %USERNAME% Machine: %COMPUTERNAME% On %OS% %DATE% > %OUTFILE% ECHO. >> %OUTFILE% set db2instance=db2 del "C:\db2audit\*.*" /s/q/f >: NUL 2>&1 del "C:\db2auditArchive\*.*" /s/q/f >: NUL 2>&1 del "C:\db2auditExtract\*.del" /s/q/f >: NUL 2>&1 db2audit configure scope validate status both errortype audit > NUL db2audit configure scope checking status failure errortype audit > NUL db2audit configure scope objmaint status both errortype audit > NUL db2audit configure scope secmaint status both errortype audit > NUL db2audit configure scope context status none errortype audit > NUL db2audit configure scope audit status both errortype audit > NUL db2audit configure scope sysadmin status both errortype audit > NUL db2audit start > NUL ECHO. >> %OUTFILE% ECHO --------------------------------------------------------------------- >> %OUTFILE% ECHO Do some SQL activity >> %OUTFILE% ECHO --------------------------------------------------------------------- >> %OUTFILE% ECHO. >> %OUTFILE% db2 connect to sample > NUL db2 "values current timestamp" > NUL db2 "create table test (c1 int not null primary key, c2 int)" > NUL db2 "insert into test values (1,2),(2,3),(3,4),(4,5),(5,6),(6,7)" > NUL db2 "update test set c2 = 100 where c1 in (1,2,3)" > NUL db2 "delete from test where c2 = 100" > NUL db2 "drop table test" > NUL db2 "select firstnme, lastname, salary from employee" > NUL db2 "update employee set salary = 200000 where empno = '000010'" > NUL db2 "grant dbadm on database to user secpot" > NUL db2 "revoke dbadm on database from user secpot" > NUL db2 "connect to sample user secpot using 12345" > NUL db2 "connect to sample user secpot using 34567" > NUL db2 "connect to sample user secpot using 37645" > NUL db2 terminate > NUL db2audit flush > NUL db2audit stop > NUL ECHO. >> %OUTFILE% ECHO --------------------------------------------------------------------- >> %OUTFILE% ECHO Archive Audit data and extract >> %OUTFILE% ECHO --------------------------------------------------------------------- >> %OUTFILE% ECHO. >> %OUTFILE% for /f "Tokens=2-4 Delims=/ " %%a in ('date /t /n') do set curdate=%%c%%a%%b db2audit archive >> %OUTFILE% db2audit archive database sample >> %OUTFILE% db2audit extract delasc to C:\db2auditextract from ^ files c:\db2auditarchive\*%curdate%* >> %OUTFILE% ECHO. >> %OUTFILE% ECHO --------------------------------------------------------------------- >> %OUTFILE% ECHO LOAD Extracted Audit data in AUDIT Tables >> %OUTFILE% ECHO --------------------------------------------------------------------- >> %OUTFILE% ECHO. >:>: %OUTFILE% db2 -tf LoadAuditTables.SQL > NUL ECHO. >> %OUTFILE% ECHO --------------------------------------------------------------------- >> %OUTFILE% ECHO Reports from Audit Tables >> %OUTFILE% ECHO --------------------------------------------------------------------- >> %OUTFILE% ECHO. >> %OUTFILE% db2 -tf AuditReports.SQL >> %OUTFILE%
LoadAuditTable.SQL file – Download scripts here
--#SET TERMINATOR @ CONNECT TO SAMPLE @ ECHO -------------------------------------------------@ ECHO LOAD DATA IN AUDIT TABLES in SAMPLE Database @ ECHO -------------------------------------------------@ LOAD FROM 'C:\db2auditextract\audit.del' OF DEL MODIFIED BY DELPRIORITYCHAR LOBSINFILE REPLACE INTO audit.AUDIT NONRECOVERABLE @ LOAD FROM 'C:\db2auditextract\checking.del' OF DEL MODIFIED BY DELPRIORITYCHAR LOBSINFILE REPLACE INTO audit.CHECKING NONRECOVERABLE @ LOAD FROM 'C:\db2auditextract\objmaint.del' OF DEL MODIFIED BY DELPRIORITYCHAR LOBSINFILE REPLACE INTO audit.OBJMAINT NONRECOVERABLE @ LOAD FROM 'C:\db2auditextract\secmaint.del' OF DEL MODIFIED BY DELPRIORITYCHAR LOBSINFILE REPLACE INTO audit.SECMAINT NONRECOVERABLE @ LOAD FROM 'C:\db2auditextract\sysadmin.del' OF DEL MODIFIED BY DELPRIORITYCHAR LOBSINFILE REPLACE INTO audit.SYSADMIN NONRECOVERABLE @ LOAD FROM 'C:\db2auditextract\validate.del' OF DEL MODIFIED BY DELPRIORITYCHAR LOBSINFILE REPLACE INTO audit.VALIDATE NONRECOVERABLE @ LOAD FROM 'C:\db2auditextract\context.del' OF DEL MODIFIED BY DELPRIORITYCHAR LOBSINFILE REPLACE INTO audit.CONTEXT NONRECOVERABLE @ LOAD FROM 'C:\db2auditextract\execute.del' OF DEL MODIFIED BY DELPRIORITYCHAR LOBSINFILE REPLACE INTO audit."EXECUTE" NONRECOVERABLE @ CONNECT RESET@
AuditReports.SQL file – Download scripts here
--#SET TERMINATOR @ CONNECT TO SAMPLE @ ECHO -------------------------------------------------@ ECHO List of Successful Connections @ ECHO -------------------------------------------------@ SELECT TIMESTAMP, SUBSTR(USERID,1,18) USERID, SUBSTR(EXECID,1,18) EXECID, SUBSTR(PLUGINNAME,1,18) PLUGINNAME FROM AUDIT.VALIDATE WHERE EVENT = 'AUTHENTICATION' AND AUTHID IS NOT NULL ORDER BY USERID @ ECHO -------------------------------------------------@ ECHO List of Failed Connections @ ECHO -------------------------------------------------@ SELECT TIMESTAMP, SUBSTR(USERID,1,18) USERID, SUBSTR(EXECID,1,18) EXECID, SUBSTR(PLUGINNAME,1,18) PLUGINNAME FROM AUDIT.VALIDATE WHERE EVENT = 'AUTHENTICATION' AND AUTHID IS NULL ORDER BY USERID @ ECHO -------------------------------------------------@ ECHO List of Objects Created in SAMPLE Database @ ECHO -------------------------------------------------@ SELECT TIMESTAMP, SUBSTR(USERID,1,18) USERID, SUBSTR(AUTHID,1,18) AUTHID, SUBSTR(OBJNAME,1,18) OBJNAME, SUBSTR(OBJTYPE,1,18) OBJTYPE FROM AUDIT.OBJMAINT WHERE EVENT = 'CREATE_OBJECT' ORDER BY USERID @ ECHO -------------------------------------------------@ ECHO List of Objects Dropped in SAMPLE Database @ ECHO -------------------------------------------------@ SELECT TIMESTAMP, SUBSTR(USERID,1,18) USERID, SUBSTR(AUTHID,1,18) AUTHID, SUBSTR(OBJNAME,1,18) OBJNAME, SUBSTR(OBJTYPE,1,18) OBJTYPE FROM AUDIT.OBJMAINT WHERE EVENT = 'DROP_OBJECT' ORDER BY USERID @ ECHO -------------------------------------------------@ ECHO Who is accessing/updating EMPLOYEE TABLE @ ECHO -------------------------------------------------@ SELECT TIMESTAMP, SUBSTR(USERID,1,18) USERID, SUBSTR(SESSNAUTHID,1,18) SESSIONID, SUBSTR(STMTTEXT,1,255) SQL FROM AUDIT."EXECUTE" WHERE EVENT = 'STATEMENT' AND DATABASE = 'SAMPLE' AND STMTTEXT IS NOT NULL ORDER BY USERID @ CONNECT RESET@
Database Level Auditing by SECADM
InstanceAudit.CMD file – Download scripts here
TITLE %~n0.CMD - Database Auditing using SECADM Policies SET OUTFILE=%~n0_OUTPUT.TXT @ECHO off cls ECHO Executed by: %USERNAME% Machine: %COMPUTERNAME% On %OS% %DATE% ECHO Executed by: %USERNAME% Machine: %COMPUTERNAME% On %OS% %DATE% > %OUTFILE% ECHO. >> %OUTFILE% set db2instance=db2 del "C:\db2audit\*.*" /s/q/f > NUL 2>&1 del "C:\db2auditArchive\*.*" /s/q/f > NUL 2>&1 del "C:\db2auditExtract\*.del" /s/q/f > NUL 2>&1 ECHO. >> %OUTFILE% ECHO --------------------------------------------------------------------- >> %OUTFILE% ECHO Start Auditing using 2 policies >> %OUTFILE% ECHO --------------------------------------------------------------------- >> %OUTFILE% ECHO. >> %OUTFILE% db2 -v CONNECT TO SAMPLE USER SECPOT USING SECPOT12345 >> %OUTFILE% db2 -v AUDIT DATABASE USING POLICY CHECK_POLICY >> %OUTFILE% db2 -v AUDIT TABLE %USERNAME%.EMPLOYEE USING POLICY SENSITIVE_DATA_POLICY >> %OUTFILE% db2 -v AUDIT SYSADM, DBADM USING POLICY CHECK_POLICY >> %OUTFILE% db2 COMMIT > NUL db2 CONNECT RESET > NUL ECHO. >> %OUTFILE% ECHO --------------------------------------------------------------------- >> %OUTFILE% ECHO Do some SQL activity >> %OUTFILE% ECHO --------------------------------------------------------------------- >> %OUTFILE% ECHO. >> %OUTFILE% db2 connect to sample > NUL db2 "values current timestamp" > NUL db2 "create table test (c1 int not null primary key, c2 int)" > NUL db2 "insert into test values (1,2),(2,3),(3,4),(4,5),(5,6),(6,7)" > NUL db2 "update test set c2 = 100 where c1 in (1,2,3)" > NUL db2 "delete from test where c2 = 100" > NUL db2 "drop table test" > NUL db2 "select firstnme, lastname, salary from employee" > NUL db2 "update employee set salary = 200000 where empno = '000010'" > NUL db2 "grant dbadm on database to user secpot" > NUL db2 "revoke dbadm on database from user secpot" > NUL db2 "connect to sample user secpot using 12345" > NUL db2 "connect to sample user secpot using 34567" > NUL db2 "connect to sample user secpot using 37645" > NUL db2 terminate > NUL ECHO. >> %OUTFILE% ECHO --------------------------------------------------------------------- >> %OUTFILE% ECHO Stop Auditing using 2 policies, archive and extract audit data >> %OUTFILE% ECHO --------------------------------------------------------------------- >> %OUTFILE% ECHO. >> %OUTFILE% for /f "Tokens=2-4 Delims=/ " %%a in ('date /t /n') do set curdate=%%%%c%%a%%b%% db2 -v CONNECT TO SAMPLE USER SECPOT USING SECPOT12345 > NUL db2 -v AUDIT DATABASE REMOVE POLICY >> %OUTFILE% db2 -v AUDIT TABLE %USERNAME%.EMPLOYEE REMOVE POLICY >> %OUTFILE% db2 -v AUDIT SYSADM, DBADM REMOVE POLICY >> %OUTFILE% db2 COMMIT > NUL db2 CALL SYSPROC.AUDIT_ARCHIVE( 'C:\db2auditArchive', -2 ) > NUL db2 CALL sysproc.audit_delim_extract(NULL,'C:\db2auditextract', ^ null,'db2audit.db.SAMPLE.log.%curdate%',null) db2 CONNECT RESET > NUL ECHO. >> %OUTFILE% ECHO --------------------------------------------------------------------- >> %OUTFILE% ECHO LOAD Extracted Audit data in AUDIT Tables >> %OUTFILE% ECHO --------------------------------------------------------------------- >> %OUTFILE% ECHO. >> %OUTFILE% db2 -tf LoadAuditTables.SQL > NUL ECHO. >> %OUTFILE% ECHO --------------------------------------------------------------------- >> %OUTFILE% ECHO Reports from Audit Tables >> %OUTFILE% ECHO --------------------------------------------------------------------- >> %OUTFILE% ECHO. >> %OUTFILE% db2 -tf AuditReports.SQL >> %OUTFILE%
Run InstanceAudit.CMD to do the audits at the instance level. When you see the output file, you will notice that the SYSADM can only see the connections but not the database level activity as that action can only be performed by the SECADM. When you run DatabaseAudit.CMD, you will see that the output only shows the database level activity but not the instance level. Also, SECADM can also see what SYSADM is doing at the instance or at the database level.
How new DB2 audit is different than the previous versions.
- Audit functions are separated between SYSADM and SECADM
- SECADM can monitor SYSADM and DBAs
- Database auditing is separate at each database within one instance.
- You can audit a single table
- SECADM can audit who is creating or dropping tables
- SECADM can audit all SQL statements
If you are looking for 3rd party solution to analyze your DB2 audit logs, you can look for these solutions: