Oracle Unified Auditing: Sending Audit Data Using Syslog

In the first part of this blog series, we looked at how Oracle Unified Auditing captures audit records inside the database. Now, let’s look at how to send Unified Audit Data Using Syslog to an external logging server for centralized monitoring and forensic visibility.

Forwarding Unified Audit Data Using Syslog is a simple way to externalize Oracle audit records. It integrates with SIEM platforms, enterprise logging tools, and centralized monitoring solutions. It also provides near real-time visibility while keeping audit records outside the database host.

Configuring Unified Audit Data Using Syslog

Oracle provides a built-in mechanism to write the Database Unified Audit records to the operating system syslog files: UNIFIED_AUDIT_SYSTEMLOG. Let’s dive into how to use this.

Syslog is a universal standard and provides near real-time forwarding of audit events to a central location. So to begin with, we will set the parameter

ALTER SYSTEM SET unified_audit_systemlog='LOCAL1.NOTICE' SCOPE=SPFILE;

In this example: UNIFIED_AUDIT_SYSTEMLOG = LOCAL1.NOTICE which means:

Facility = LOCAL1
Priority = NOTICE

The facility part classifies the source of the message, while the priority part indicates the severity level of the message.

Once you set the database parameter, configure rsyslog on the operating system. Rsyslog uses the same facility and priority to route the message. You can map that FACILITY.PRIORITY value to a logfile. For example:

local1.notice    /var/log/oracle/unified_audit.log

This tells rsyslog: For messages coming in as local1.notice,write them to /var/log/oracle/unified_audit.log

So the database parameter and the rsyslog rule need to match logically, to map out the audit writes

The important point is that the facility and priority must match in the db and the rsyslog config file.

Example rsyslog Configuration

So let’s say we have an ASM instance and 2 database instances running on my db host.

Database host:       db-host-01
ASM Unstance :       +ASM
Database 1 :         DB1
Database 2 :         DB2
Central syslog host: syslog-server-01
Central syslog IP:   10.x.x.x

We will need to assign a FACILITY.PRIORITY for each instance to keep the audit data separated. I would highly recommend this approach, as it makes it cleaner to ingest the records on a third-party tooling.

FACILITY.PRIORITY in the database

# ASM  --> unified_audit_systemlog=local0.info
# Database 1  --> unified_audit_systemlog=local1.notice
# Database 2  --> unified_audit_systemlog=local2.notice

Now I will map out these FACILITY.PRIORITY in the local rsyslog configuration on the database host. Additionally, using separate identifiers makes log rotation and cleanup easier. It gives us the flexibility to apply different retention policies for each audit source

cat /etc/rsyslog.conf

# ASM Audit
local0.info      /var/log/oracle/asm_audit.log
local0.info      @@10.x.x.x:514

# Oracle Database Unified Audit
local1.notice    /var/log/oracle/db1_audit.log
local1.notice    @@10.x.x.x:514

# Oracle Database Unified Audit
local2.notice    /var/log/oracle/db2_audit.log
local2.notice    @@10.x.x.x:514

In the above configuration, the first line for each source writes a local copy.

local0.notice    /var/log/oracle/asm_audit.log

The second line forwards the same message to the central syslog server.

local0.notice    @@10.x.x.x:514

In rsyslog, The forwarding syntax is important:

@10.x.x.x:514     UDP forwarding
@@10.x.x.x:514 TCP forwarding

For audit logs, TCP is preferable because it is more reliable than UDP. After updating the configuration, we would need to restart the syslog service.

systemctl status rsyslog
systemctl restart rsyslog
systemctl status rsyslog

Handling Multiple Database Instances

Our mapping is as follows: the important thing is the facility.priority combination should be different for each instance

SourceFacility.PriorityDatabase ParameterLocal Log FileCentral Destination
ASM Auditlocal0.infoLOCAL0.INFO/var/log/oracle/asm_audit.log10.x.x.x:514
DB1 Unified Auditlocal1.noticeLOCAL1.NOTICE/var/log/oracle/db1_audit.log10.x.x.x:514
DB2 Unified Auditlocal2.noticeLOCAL2.NOTICE/var/log/oracle/db2_audit.log10.x.x.x:514

Once this is configured, Oracle sends selected Unified Audit records to syslog, and rsyslog handles the local write and forwarding to the external syslog server. You should now be able to view the records in your syslog as well as your external syslog server.

Please note that you can also use a third-party logging service instead of rsyslog to forward audit logs to an external server. A common approach is to use rsyslog to write the audit data to local syslog files, and then use a Cloud Ops Agent or another log forwarder to ship those files to an external destination.

Syslog Limitations

When you query your database, a typical Unified Audit Trail record is extremely rich, and you can see a lot of information, as shown in the screenshot below.

unified audit record

However, when you look at the records forwarded to syslog i.e. audit records in the file /var/log/oracle/db1_audit.log will look something like this

May 17 03:29:17 dbhost-1 journal[551028]: Oracle Unified Audit[551028]: LENGTH: '178' TYPE:"4" DBID:"XXXXX38" SESID:"2262626412" CLIENTID:"" ENTRYID:"2" STMTID:"5" DBUSER:"MYUSER1" CURUSER:"MYUSER1" ACTION:"101" RETCODE:"0" SCHEMA:"" OBJNAME:""

May 17 03:29:17 dbhost-1 journal[551026]: Oracle Unified Audit[551026]: LENGTH: '167' TYPE:"4" DBID:"XXXXX38" SESID:"680131052" CLIENTID:"" ENTRYID:"2" STMTID:"4" DBUSER:"MYUSER2" CURUSER:"MYUSER2" ACTION:"101" RETCODE:"0" SCHEMA:"" OBJNAME:""

As you can see, Oracle writes only selected audit fields to syslog. Many important fields, such as OS user, terminal, client, and SQL text, are not written to syslog. Oracle tracks this expected behavior under Bug ID 29468765: UNIFIED AUDITING FIELDS OSUSER, TERMINAL, CLIENT NOT SENT TO SYSLOG.

Per Oracle, Oracle limits syslog forwarding to selected key audit fields because of the “1024-byte message size limitation of typical syslog.” Oracle further mentions that:

The complete audit record exists in the UNIFIED_AUDIT_TRAIL. The entry in syslog will NOT replace the complete audit record written to UNIFIED_AUDIT_TRAIL but will help Forensic Auditors to verify and ensure no audit record is unauthorizedly deleted.

Again, as you will notice in the ACTION field in syslog, instead of the name of the action (As seen in the unified_audit_trail) the ACTION Code (101) is listed. So you would need to decode this and map out this action name later for analysis or on your third party tool that views this data.

select * from audit_actions where action=101;

    ACTION NAME
---------- ----------------------------
       101 LOGOFF

So in my opinion, using rsyslog is usually enough for near real-time visibility, alerting, and basic forensic tracking, but it is certainly not enough for a complete audit analysis. The picture is quite incomplete.

Beyond Syslog

Syslog is a good starting point for sending Unified Audit records outside the database host. It is built into Oracle Database, simple to configure, widely supported, and useful for near real-time visibility.

But syslog does not give you the full audit record. For deeper audit analysis, you need a custom extraction process that reads the complete Unified Audit data from the database and forwards it externally.

In the next part, I will walk through that setup using Google Cloud Ops Agent as the forwarder. I will also cover the local housekeeping tasks needed to manage the files safely.


Discover more from oratrails-aish

Subscribe to get the latest posts sent to your email.