Auditing DB2 type Databases
This is a set of steps to set up the basis for auditing for DB2 types databases. SYSADM will control this aspect. We will then follow on to use Database level auditing using SQL so that the SECADM has this control through Policies and Profiles. You can use instance level, but it is not very controllable nor performant. While you can run auditing at an istance level, it is best to control at Database level. You can actually get to table level auditing.
Database level auditing is all stored in the database in the system catalog tables, so it starts when the database activates, is backed up with the database and restored with the database.
however we will use the configure function of db2audit
Here is a knowledge center article on the topic of db2audit as well.
Setting it up
Using db2audit
This is a set of steps to set up the basis for auditing for DB2 types databases. SYSADM will control this aspect. We will then follow on to use Database level auditing using SQL so that the SECADM has this control through Policies and Profiles. You can use instance level, but it is not very controllable nor performant. It is best to control at Database level, then you can actually get to table level auditing.
Database level auditing is all stored in the database in the system catalog tables, so it starts when the database activates and is backed up with the database and restored with the database.
- Login to the Openshift cluster Example:
oc login --token=sha256~Hxk5vF3JbWyhGuxsnmHKaJcG6dHc8bOEDBhiGLCkRZI --server=https://c100-e.us-east.containers.cloud.ibm.com:30156
- Set the project or namespace, in my case it is zen. This lets you not need to use -n
on every command. Toms-MBP:cpd352 tjm$ oc project zen Now using project "zen" on server "https://c100-e.us-east.containers.cloud.ibm.com:30156".
- This will list the available head nodes of the db2u based databases which you have provisioned in your Cloud Pak for Data platform.
Toms-MBP:/ tjm$ oc get po --selector name=dashmpp-head-0 NAME READY STATUS RESTARTS AGE c-db2oltp-1610989723055231-db2u-0 1/1 Running 0 10d c-db2wh-1614550695007498-db2u-0 1/1 Running 0 10d
- Exec into the pod
Toms-MBP:/ tjm$ oc exec -ti c-db2wh-1614550695007498-db2u-0 bash
- Other option is to use remote shell
oc rsh c-db2wh-1614550695007498-db2u-0
- Other option is to use remote shell
- Become db2inst1 This will give you the environment to access and excute these commands
[db2uadm@c-db2wh-1614550695007498-db2u-0 /]$ su - db2inst1 Last login: Thu Jan 28 21:58:11 UTC 2021 on pts/3 [db2inst1@c-db2wh-1614550695007498-db2u-0 - Db2U db2inst1]$
- Change directories to
cd sqllib/adm
[db2inst1@c-db2wh-1614550695007498-db2u-0 - Db2U db2inst1]$ cd sqllib/adm
- Verify that db2audit exists and you have done everything so far correctly.
[db2inst1@c-db2wh-1614550695007498-db2u-0 - Db2U adm]$ ls db2audit db2audit
- There are only two commands you should use with db2audit. These are describe and configure. If you use others like, Audit active: “TRUE” you will end up with instance level auditing which we do not want.
- To understand what is configured run
db2audit describe
[db2inst1@c-db2wh-1614550695007498-db2u-0 - Db2U adm]$ db2audit describe DB2 AUDIT SETTINGS: Audit active: "FALSE " Log audit events: "FAILURE" Log checking events: "FAILURE" Log object maintenance events: "FAILURE" Log security maintenance events: "FAILURE" Log system administrator events: "FAILURE" Log validate events: "FAILURE" Log context events: "NONE" Return SQLCA on audit error: "FALSE " Audit Data Path: "" Audit Archive Path: "" AUD0000I Operation succeeded.
- To understand what is configured run
- Notice the the Audit Data Path and Archive Path are empty. We need to configure these otherwise there will be no logs. Later we will choose between synchronous and asynchronous logging. This is where the output from that decision is going to go.
Since these are pods, you want to write the logs out to a Persistant Volume which is located in/mnt
in the pod. - The next command is how you will configure db2audit to change the Paths we mentioned before. This command is
db2audit configure
. Lets configure the datapath and archivepath - Configure datapath
- To configure the location for the active audit files issue the following command. This directory, similar to tran logs, should not have much competition as you may get performance contention. I am picking the
/mnt/backup
which maps to a separate Persistent Volume.db2audit configure datapath your chosen path
- First make the directory, otherwise you will get a permission error.
mkdir /mnt/backup/security
- Now issue the configure command:
db2audit configure datapath /mnt/backup/security
[db2inst1@c-db2wh-1614550695007498-db2u-0 - Db2U adm]$ db2audit configure datapath /mnt/backup/security AUD0000I Operation succeeded.
- To configure the location for the active audit files issue the following command. This directory, similar to tran logs, should not have much competition as you may get performance contention. I am picking the
- Configure archivepath
- To configure the location for the active audit files issue the following command. This directory we care less about contention and performance. In this example, I am still writing to the same directory, but you may choose a different path
/mnt/backup
which maps to a separate Persistent Volume.db2audit configure archivepath your chosen path
- First make the directory, otherwise you will get a permission error.
mkdir /mnt/backup/archive
- Now issue the configure command:
db2audit configure archivepath /mnt/backup/archive
[db2inst1@c-db2wh-1614550695007498-db2u-0 - Db2U adm]$ db2audit configure datapath /mnt/backup/archive AUD0000I Operation succeeded.
- To configure the location for the active audit files issue the following command. This directory we care less about contention and performance. In this example, I am still writing to the same directory, but you may choose a different path
- Lets see if the changes have taken place using
db2audit describe
[db2inst1@c-db2wh-1614550695007498-db2u-0 - Db2U adm]$ db2audit describe DB2 AUDIT SETTINGS: Audit active: "FALSE " Log audit events: "FAILURE" Log checking events: "FAILURE" Log object maintenance events: "FAILURE" Log security maintenance events: "FAILURE" Log system administrator events: "FAILURE" Log validate events: "FAILURE" Log context events: "NONE" Return SQLCA on audit error: "FALSE " Audit Data Path: "/mnt/backup/security/" Audit Archive Path: "/mnt/backup/archive/" AUD0000I Operation succeeded.
For more information on db2audit, visit the IBM Knowledge Center
Synchronous or Asynchronous log writing that is the question
As of now you have set up where the logs will be written, next is to set up how they are written. By default, there is no database buffer when writing out logs to the datapath or active audit log. Let’s call this a synchronous write, which has performance implications as it is writing directly to the path. You can set up an audit buffer, which will right in memory while older records are being written to the datapath. Obviously asynchronous will be more performant, but if you have a database crash are you willing to potentially lose that memory buffered audit logs. 99% of the time, someone will ask who accessed the database or what was happening at the time of the crash. Do your own cost benefit analysis on which one you choose. I will show you how to configure both.
- By default synchronous is set up with a buffersize of 0. You can also set this by issuing:
db2 update dbm cfg using audit_buf_sz 0
[db2inst1@c-db2wh-1614550695007498-db2u-0 - Db2U adm]$ db2 update dbm cfg using audit_buf_sz 0 DB20000I The UPDATE DATABASE MANAGER CONFIGURATION command completed successfully.
- If you are looking to use a audit buffer, which is considered asynchronous for test or you have a reason to not write directly, you can set up a buffer sized at 64 or 128 depending on the dynamic SQL. You can also set this by issuing:
db2 update dbm cfg using audit_buf_sz 64
[db2inst1@c-db2wh-1614550695007498-db2u-0 - Db2U adm]$ db2 update dbm cfg using audit_buf_sz 64 DB20000I The UPDATE DATABASE MANAGER CONFIGURATION command completed successfully.
NOTE: These changes are persisted and will not revert on a pod restart.
For more information on audit_buf_sz, visit the IBM Knowledge Center
Database level Auditing
This product hub link on DB2 Wareshouse auditing is very helpful
Main Objects that can be audited
Objects | Description |
---|---|
Database | All events dealing with connections at a database level |
Table | Only Events you can or should used is Execute. SQL statements, rows returned, executable environment. You can get this with or without data. Execute is expensive, not as expensive as Context, as there is a lot of logging that will come from it. Context has too much data. You can audit Untyped tables, Nicknames, and Material Query Tables (MQT) but you can’t audit views. Remember you are auditing an object. If you have 2 tables (with policies) that are part of the MQT, the MQT is not audited unless it has a policy. Note: If you drop a table that is audited, and you recreate the table, you have to apply the policy again to that table. |
Authorities | You can assign a policy to multiple authorities. |
Users, Groups and Roles | You can assign a policy to any of these to audit actions by these objects. |
Trusted Context | You can and should monitor trusted applications. |
For more information on Audit Object types, visit the IBM Knowledge Center
Main Events that can be audited
Database event types that can be audited
Event type | Description |
---|---|
Audit (AUDIT) |
Generates records when audit settings are changed or when the audit log is accessed |
User validation (VALIDATE) |
Generates records when authenticating users or retrieving system security information |
Authorization checking (CHECKING) |
Generates records during authorization checking of attempts to access or manipulate DB2 objects or functions |
Object maintenance (OBJMAINT) |
Generates records when creating or dropping data objects |
Security maintenance (SECMAINT) |
Generates records when granting or revoking object or database privileges or DBADM authority Records are also generated when the database manager security configuration parameters SYSADM_GROUP, SYSCTRL_GROUP, or SYSMAINT_GROUP are modified |
System administration (SYSADMIN) |
Generates records when operations requiring SYSADM, SYSMAINT, or SYSCTRL authority are performed |
Operation execution (EXECUTE) |
Generates records to accurately track the SQL statements that are issued by a user. Options are with data or with out data. This operation can be expensive |
Operation context (CONTEXT) |
Generates records to show the operation context when a database operation is performed. This category allows for better interpretation of the audit records. When used with the log’s event correlator field, a group of events can be traced back to a single database operation that can provide needed context when analyzing audit results.</br>This operation can be very expensive. |
For more information on Audit Events, visit the IBM Knowledge Center
Creating policies
You can create many different policies with different intents and use cases. Maybe you want to audit a table or a role then you would write up a policy for this to be applied to the table or role. When you think about a policy, there is one policy to many objects.
Note: I am assuming that autocommit is set to true. If not you will be to commit each statement for them to take hold. If it is set to Autocommit=true then once the cursor returns, it’s enabled and working.
- You will need a list of databases
db2 LIST ACTIVE DATABASES
- I have a database called CP4DEMO. Connect to the database:
db2 connect to cp4demo
[db2inst1@c-db2wh-1614550695007498-db2u-0 - Db2U adm]$ db2 connect to cp4demo Database Connection Information Database server = DB2/LINUXX8664 11.5.5.0 SQL authorization ID = DB2INST1 Local database alias = CP4DEMO
- Create a policy. In my case, it is a generic policy called DBAUDPRF, yours may be more specific to the usecase of the business.
db2 create audit policy DBAUDPRF CATEGORIES AUDIT STATUS BOTH, SECMAINT STATUS FAILURE, OBJMAINT STATUS BOTH, CHECKING STATUS FAILURE, VALIDATE STATUS FAILURE ERROR TYPE NORMAL
[db2inst1@c-db2wh-1614550695007498-db2u-0 - Db2U adm]$ db2 create audit policy DBAUDPRF CATEGORIES AUDIT STATUS BOTH, SECMAINT STATUS FAILURE, OBJMAINT STATUS BOTH, CHECKING STATUS FAILURE, VALIDATE STATUS FAILURE ERROR TYPE NORMAL DB20000I The SQL command completed successfully.
For more information on Audit Policies, visit the IBM Knowledge Center
Reviewing Policies
- All Audit policies are stored in SYSCAT&& schema and in a table called **AUDITPOLICIES. To review the policies you can execute this SQL.
db2 "select * from SYSCAT.AUDITPOLICIES"
- Results are not pretty, but you can see that the DBAUDPRF policy is listed when created, altered etc. I have shorten this to protect the innocent.
[db2inst1@c-db2wh-1614550695007498-db2u-0 - Db2U adm]$ db2 "select * from SYSCAT.AUDITPOLICIES" AUDITPOLICYNAME AUDITPOLICYID CREATE_TIME ALTER_TIME AUDITSTATUS CONTEXTSTATUS VALIDATESTATUS CHECKINGSTATUS SECMAINTSTATUS OBJMAINTSTATUS SYSADMINSTATUS EXECUTESTATUS EXECUTEWITHDATA ERRORTYPE REMARKS --------------- ---------- ----------- ---------- ---------- ------------ ------------ --------- -------- ------- -------- --------- ------------ ---------- DBAUDPRF 100 2021-03-11-15.33.26.803714 2021-03-11-15.33.26.803714 B N F F F B N N N N - 1 record(s) selected.
Applying Policies
An object (DATABASE, ROLE, GROUP, TABLE) can only have one policy. How you have build out your database structure with GROUPS and ROLES will allow you to have a USER who is in a ROLE and a GROUP or multiple GROUPS have many policies applied to the user, because the USER doesn’t have a policy applied directly to the id, instead the GROUP or ROLE has the POLICY applied.
Example: Maybe I create a SENSITIVE_DATA_PRF and I want to apply this many object. The command to apply this to multiple objects uses a comma to separate the arguments: db2 audit authority DBADM, role teller, role accounting, role marketing, role support using policy SENSITIVE_DATA_PRF
We have created a policy, verified it exists in the Database, now we want to apply it to the database. This is done using the AUDIT command. db2 audit database using policy \<policy\>
- Assuming you are still connected to the database, tell the audit facilty that you are going to audit this database using a certain policy. I apply DBAUDPRF policy to the CP4DEMO database using this command:
db2 audit database using policy DBAUDPRF
[db2inst1@c-db2wh-1614550695007498-db2u-0 - Db2U adm]$ db2 audit database using policy DBAUDPRF DB20000I The SQL command completed successfully.
- If this was for say a role of TELLER you can add/replace using the following.
db2 audit role teller using TELLERPRF
ordb2 audit role teller replace TELLERPRF
Deeper information on Audit Policies
Reviewing policies applied.
- All Applied Audit policies are stored in SYSCAT schema and in a table called AUDITUSE. To review the policies you can execute this SQL.
db2 "select * from SYSCAT.AUDITUSE"
- Results are not pretty, but you can see that the DBAUDPRF is listed under AUDITPOLICYNAME and applied to the OBJECTNAME CURRENT SERVER, altered etc. I have shorten this to protect the innocent.
[db2inst1@c-db2wh-1614550695007498-db2u-0 - Db2U adm]$ db2 "select * from SYSCAT.AUDITUSE" AUDITPOLICYNAME AUDITPOLICYID OBJECTTYPE SUBOBJECTTYPE OBJECTSCHEMA OBJECTNAME AUDITEXCEPTIONENABLED --------------- ------------- ---------- ------------- ------------- ------------- ------------------ DBAUDPRF 100 - CURRENT SERVER N 1 record(s) selected.
Removing policies objects
- I have applied a policy and now want to remove it. Database is slightly different as you have one policy applied at the Database level and you can apply finer grained policies to roles and tables. To remove the applied policy from the database the command is
db2 audit database remove policy
. - If you had created a policy for a table for example the command would be
db2 audit table employee remove policy
Managing Storage and Logs
Archiving the Active logs
- Archive out of the active file to the archive directory.
call sysproc.audit_archive('', -2)
- Frst argument is the location of the output. You have set a default earlier in the
db2audit configure
, so you can make this NULL or change it if you wantcall sysproc.audit_archive('/auditarchive', -2)
- Second argument is either -1 for current database members or NULL or -2 for all database members.
[db2inst1@c-db2wh-1614550695007498-db2u-0 - Db2U db2inst1]$ db2 "call SYSPROC.AUDIT_ARCHIVE(NULL, NULL)" Result set 1 -------------- DBPARTITIONNUM PATH FILE SQLCODE SQLSTATE SQLERRMC MEMBER -------------- -------------------- ---------------------------------------- ---------- -------- --------- ------ 0 /mnt/backup/archive/ db2audit.db.CP4DEMO.log.0.20210312125805 0 - - 0 1 record(s) selected. Return Status = 0
- Frst argument is the location of the output. You have set a default earlier in the
- Verify that is exists in the correct directory
[db2inst1@c-db2wh-1614550695007498-db2u-0 - Db2U db2inst1]$ ls -l /mnt/backup/archive/ total 12 -rw-------. 1 db2inst1 db2iadm1 8712 Mar 12 12:58 db2audit.db.CP4DEMO.log.0.20210312125805
For more information on AUDIT_ARCHIVE, visit the IBM Knowledge Center
Prepare them for use
- Let’s parse out the archive logs into more specific logs that can be used later when we load them into a database. The following command will extract out all records where the file name has a date of 20210312.
call sysproc.audit_delim_extract(NULL, NULL, NULL, '%20210311%', ' ')
It will produce the following files. Files produced:- audit.del
- checking.del
- objmaint.del
- sysadmin.del
- validate.del
- context.del
- execute.del
- auditlobs
[db2inst1@c-db2wh-1614550695007498-db2u-0 - Db2U db2inst1]$ db2 "call sysproc.audit_delim_extract(NULL, NULL, NULL, '%20210312%', '')" Return Status = 0
- Let’s see what the output looks like:
[db2inst1@c-db2wh-1614550695007498-db2u-0 - Db2U db2inst1]$ ls /mnt/backup/archive/ audit.del auditlobs checking.del context.del db2audit.db.CP4DEMO.log.0.20210312125805 execute.del objmaint.del secmaint.del sysadmin.del validate.del
- If you wanted to move these to a place of safe keeping you can use the
scp
command to copy the files from this cluster to another persistent store. Then delete the copied files freeing up this space for future usage. You will want to do these periodically so you do not run out of volume space. The mount I choose is also where you Database backups will be stored.
For more information on AUDIT_DELIM_EXTRACT, visit the IBM Knowledge Center
Automating Archiving and Delimiting the archive files
Setting up the Administrative Task Scheduler
- Set the DB2_ATS_ENABLE registry variable to YES, TRUE, 1, or ON.
For example:db2set DB2_ATS_ENABLE=YES
Creating Scheduled Archive Task
- Create an ADMIN_TASK using SYSPROC.ADMIN_TASK_ADD called DAILY AUDIT ARCHIVE which triggers the Stored Procedure AUDIT_ARCHIVE with no specific arguments at 2PM ET execute this command:
db2 "CALL SYSPROC.ADMIN_TASK_ADD( 'DAILY AUDIT ARCHIVE', CURRENT_TIMESTAMP, NULL, NULL, '00 19 * * *', 'SYSPROC', 'AUDIT_ARCHIVE','VALUES("NULL","NULL")', NULL, NULL )"
- At 2PM each day, a new audit file archive will be created:
[db2inst1@c-db2wh-1614550695007498-db2u-0 - Db2U db2inst1]$ ls -l /mnt/backup/archive/db2audit* -rw-------. 1 db2inst1 db2iadm1 8712 Mar 17 19:00 /mnt/backup/archive/db2audit.db.CP4DEMO.log.0.20210317190000 -rw-------. 1 db2inst1 db2iadm1 348393 Mar 18 19:00 /mnt/backup/archive/db2audit.db.CP4DEMO.log.0.20210318190000
Creating Scheduled Archive Task
- Create an ADMIN_TASK using SYSPROC.ADMIN_TASK_ADD called DAILY AUDIT DELIMIT which triggers the Stored Procedure AUDIT_DELIM_EXTRACT with no specific arguments at 2PM ET execute this command:
db2 "CALL SYSPROC.ADMIN_TASK_ADD( 'DAILY AUDIT DELIMIT', CURRENT_TIMESTAMP, NULL, NULL, '20 19 * * *', 'SYSPROC', 'AUDIT_DELIM_EXTRACT','VALUES("NULL", "NULL", "NULL", "'%20210319%'", "''")', NULL, NULL )"
- At 2:20PM each day, a new audit file archive will be created in
[db2inst1@c-db2wh-1614550695007498-db2u-0 - Db2U db2inst1]$ ls -l /mnt/backup/archive/db2audit* -rw-------. 1 db2inst1 db2iadm1 8712 Mar 17 19:00 /mnt/backup/archive/db2audit.db.CP4DEMO.log.0.20210317190000 -rw-------. 1 db2inst1 db2iadm1 348393 Mar 18 19:00 /mnt/backup/archive/db2audit.db.CP4DEMO.log.0.20210318190000
db2 "call sysproc.audit_delim_extract(NULL, NULL, NULL, '%20210312%', '')"
Storing Records for Analysis
Create Audit Database
- Create an audit database with audit schema. When you create this database the pagesize should be greater that
8k
probably best set to32768
.
Best not to be in the same production database as it would be extra load on the system. You probably also want to give SECADM load privileges so that the SYSADM doesn’t need to load for the security person. This would be isolated for just security audit analytics.- Create schema
db2 create schema audit
- Set the schema so you don’t have to type it over and over again,
db2 set current schema="AUDIT"
- create tables Use the
db2audit.ddl
in thesqllib/misc
directory to create the database tables. If the database was not created with 32K pagesize then you will want to create a tablespace with apagesize=32768
, then add in tablespace name to each CREATE TABLE statement indb2audit.ddl
. –db2 +o -tf sqllib/misc/db2audit.ddl
- Create schema
For more information on Creating Audit Database, visit the IBM Knowledge Center
Loading Data in the Audit Database
- Load files created from the
audit_delim_extact
stored proc (create DB with tablespace pages at 32K) For more information on Loading Data into Audit Database, visit the IBM Knowledge Center