Linux Audit system

The Linux Audit system provides fine-grained logging of security-related events, known as Linux audit logs. It is enabled by creating Linux auditing rules that specify which events to log. For example, you can add rules to audit:

  • Access to a specific file or directory

  • Specific system calls

  • Commands executed by a user

  • Authentication events

  • Network access

The Audit system architecture comprises:

  • A kernel component that generates events

  • The auditd daemon collects events from the kernel component and writes them to a log file

  • The audisp dispatcher daemon relays events to other applications for additional processing

  • The auditctl control utility to configure the kernel component

It also provides a set of tools for reading the Audit log files:

  • aulast lists the last logged-in users

  • aulastlog outputs the last login for all machine users

  • aureport produces summary reports of the Audit logs

  • ausearch searches Audit logs for events matching given criteria

  • auvirt lists virtual machine sessions found in the Audit logs

For more information about the audit system, see System Auditing in the Red Hat Enterprise Linux Security Guide, your operating system manual, and the Linux Audit Documentation Project repository on GitHub.

Linux Audit rules

The Linux Audit system generates events according to Audit rules. These rules can be set dynamically with the auditctl utility or stored persistently in the /etc/audit/rules.d folder. Persistent rule files are automatically compiled to /etc/audit/audit.rules when auditd is initialized.

There are three types of rules:

  1. A control rule modifies the auditing behavior

  2. A file system rule watches a file or directory

  3. A system call rule logs an event for a particular system call

See Defining Audit Rules in the Red Hat Enterprise Linux Security Guide for further details on Linux Audit rules.

Some common control rules are:

  • -b backlog to set the maximum number of audit buffers. Specify a bigger value for busier systems with a high log volume.

  • -D to delete all rules and watches. This rule is typically the first one.

  • -e [0..2] to control auditing. The accepted values are 0 to disable auditing temporarily, 1 to enable it, or 2 to lock the configuration until the next reboot (typically the last rule).

Example 1. Linux Audit control rules

The following is a set of basic rules commonly found in rulesets.

# Delete all rules (typically the first rule)
-D

# Increase buffers from the default 64 to 320
-b 320

# Lock Audit rules until the next reboot (the last rule)
-e 2

To create a file system rule, use -w path -p permissions -k key_name as follows:

  • The path argument defines the file or directory you want to audit.

  • The permissions argument sets the type of access to audit. It accepts a combination of r (read access), w (write access), x (execute access), and a (attribute change).

  • The key_name argument is an optional tag for identifying the rule.

Example 2. Linux Audit file system rule

This rule monitors /etc/passwd for modifications and tags access events with passwd.

-w /etc/passwd -p wa -k passwd

To create a system call rule, use -a action,filter -S system_call -F field=value -k key_name as follows:

  • The action argument can be either always (to generate a log entry) or never (to suppress a log entry). Generally, you add always rules first because rules are matched from top to bottom.

  • The filter argument is one of task (when a task is created), exit (when a system call exits), user (when a call originates from user space), or exclude (to filter events).

  • The system_call argument specifies the system call name. You can specify the -S flag more than once to monitor multiple system calls.

  • The field=value pair can be used for additional filtering options and can also be specified more than once.

  • The key_name argument is an optional tag for identifying the rule.

Example 3. Linux Audit system call rule

This rule audits system time changes.

-a always,exit -F arch=b64 -S adjtimex -S settimeofday -k system_time

System call rules can audit activities related to files, such as:

  • Creation

  • Modification

  • Deletion

  • Changes in access permissions and ownership

Example 4. Linux Audit file deletion rule

This rule audits file deletions with the unlink or rename command.

-a always,exit -F arch=b64 -S unlink,unlinkat,rename,renameat -F success=1 -F auid>=1000 -F auid!=unset -F key=successful-delete

You can also audit network connections with system call rules.

Example 5. Linux Audit networking rule

This rule audits successful incoming or outgoing external network connections.

-a always,exit -F arch=b64 -S accept,connect -F key=external-access

Combine the different rules to create a ruleset.

Example 6. Linux Audit rules file

Below is a simple Linux Audit ruleset based on the above examples.

/etc/audit/rules.d/audit.rules
# Delete all rules
-D

# Increase buffers from the default 64 to 320
-b 320

# Watch /etc/passwd for modifications and tag with 'passwd'
-w /etc/passwd -p wa -k passwd

# Audit system time changes
-a always,exit -F arch=b64 -S adjtimex -S settimeofday -k system_time

# Lock Audit rules until the next reboot
-e 2

See The Linux Audit Project and auditd-attack repositories on GitHub for more examples.

Forwarding Linux Audit logs to syslog

You can configure the Linux Audit system to forward log messages to a local syslog daemon.

Example 7. Configuring Linux Audit to forward logs to NXLog Agent

Enable the Linux Audit syslog plugin to forward logs to the /dev/log socket. The example below shows a modified /etc/audisp/plugins.d/syslog.conf file to enable log forwarding to syslog.

active = yes
direction = out
path = builtin_syslog
type = builtin
args = LOG_INFO
format = string

To verify your configuration, you can add a test rule in /etc/audit/rules.d/audit.rules to monitor modifications to a file, such as /tmp/audit_syslog.

-w /tmp/audit_syslog -p wa

You can then configure NXLog Agent to collect syslog messages from the /dev/log socket.

By default, NXLog Agent runs as the restricted nxlog user and cannot bind to the /dev/log socket. See Running as a different user or group in the NXLog Agent Reference Manual for instructions to address this.

The configuration below uses the im_uds input module to collect logs from the dev/log socket. The Exec block filters for messages containing the string audit_syslog and parses matching messages with the parse_syslog_bsd() procedure of the xm_syslog module. Finally, it converts records to JSON format using the to_json() procedure of the xm_json module.

<Extension syslog>
    Module    xm_syslog
</Extension>

<Extension json>
    Module    xm_json
</Extension>

<Input linux_audit>
    Module    im_uds
    UDS       /dev/log
    <Exec>
        if not ($raw_event =~/.+audit_syslog.+/) {
            drop();
        }
        parse_syslog_bsd();
        to_json();
    </Exec>
</Input>

Restart auditd and NXLog Agent to apply the configuration changes:

# systemctl restart auditd
# systemctl restart nxlog
Output sample
{
  "EventReceivedTime": "2022-09-28T21:09:13.959876+00:00",
  "SourceModuleName": "linux_audit",
  "SourceModuleType": "im_uds",
  "SyslogFacilityValue": 1,
  "SyslogFacility": "USER",
  "SyslogSeverityValue": 6,
  "SyslogSeverity": "INFO",
  "SeverityValue": 2,
  "Severity": "INFO",
  "Hostname": "administrator",
  "EventTime": "2022-09-28T21:09:13.000000+00:00",
  "SourceName": "audispd",
  "Message": "node=administrator type=SYSCALL msg=audit(1588108153.953:1246): arch=c000003e syscall=257 success=yes exit=3 a0=ffffff9c a1=55a4e3921110 a2=41 a3=1a4 items=2 ppid=2417 pid=3374 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts0 ses=3 comm=\"vim\" exe=\"/usr/bin/vim.basic\" key=\"audit_syslog\""
}

Collecting Linux Audit logs with im_linuxaudit

NXLog Agent includes the im_linuxaudit input module, which directly accesses the kernel component of the Linux Audit system. With this module, you can configure audit rules and collect logs all within NXLog Agent without requiring tools such as auditd or other userspace software.

If a Linux Audit System (im_linuxaudit) module instance is suspended and the Linux Audit backlog limit is exceeded, all system processes that generate audit messages will be blocked. For this reason, we recommend disabling FlowControl for im_linuxaudit module instances. When flow control is disabled, NXLog Agent will discard messages instead of suspending log processing. In addition, to reduce the risk of data loss, you can increase the LogQueueSize of subsequent module instances or introduce a pm_buffer instance.
Example 8. Configuring Linux Audit rules and collecting audit logs with NXLog Agent

This example uses im_linuxaudit to configure and collect Linux Audit logs. It specifies the ruleset in the configuration with the Rules block directive.

nxlog.conf
<Input linux_audit>
    Module         im_linuxaudit
    FlowControl    FALSE
    <Rules>
        # Delete all rules (This rule has no affect; it is performed
        # automatically by im_linuxaudit)
        -D

        # Increase buffers from the default 64 to 320
        -b 320

        # Watch /etc/passwd for modifications and tag with 'passwd'
        -w /etc/passwd -p wa -k passwd

        # Audit system time changes
        -a always,exit -F arch=b64 -S adjtimex -S settimeofday -k system_time

        # Lock audit rules until the next reboot
        -e 2
    </Rules>
</Input>
Example 9. Loading Linux Audit rules from a file

Alternative to the configuration example above, you can use the LoadRule directive to load the rules from a file. You must place the file in a location accessible by NXLog Agent and different than the Linux Audit rules folder /etc/audit/rules.d.

nxlog.conf
<Input linux_audit>
    Module         im_linuxaudit
    FlowControl    FALSE
    LoadRule       '/opt/nxlog/etc/audit.rules'
</Input>

Collecting Linux Audit logs with userspace tools

There are several ways to collect logs via the regular Linux Audit userspace tools, including from auditd logs and by network via audispd.

Setting up auditd

First, install and configure the Linux Audit userspace components:

  1. Install the audit package. Include the audispd-plugins package if you will be using audispd. See Forwarding audit logs over the network with audispd below.

    • On Red Hat/CentOS:

      # yum install audit
    • On Debian/Ubuntu:

      # apt-get install auditd
  2. Configure Auditd by editing the /etc/audit/auditd.conf file. See Configuring the Audit Service in the Red Hat Enterprise Linux Security Guide and the auditd.conf(5) man page.

  3. Enable and restart the Auditd service to reload the configuration. Make sure that the rules are not locked, or changes will not be applied until the next system reboot.

    • On Red Hat/CentOS:

      # service auditd start
      # systemctl enable auditd
    • On Debian/Ubuntu:

      # systemctl restart auditd

Collecting Auditd logs

By default, Auditd writes events to /var/log/audit/audit.log. NXLog Agent can read logs from this file.

The Auditd log file requires root privileges to access it. NXLog Agent will not be able to read the file when running as the restricted nxlog user. You can either omit the User and Group global directives from nxlog.conf to run NXLog Agent as root or adjust the permissions as follows. See Reading Rsyslog log files for more information.

  1. Use the log_group option in /etc/audit/audit.conf to set the group ownership for Auditd log files.

  2. Change the current ownership of the log directory and files with chgrp -R adm /var/log/audit.

  3. Add the nxlog user to the adm group with usermod -a -G adm nxlog.

  4. Configure NXLog Agent and restart the system to apply the changes.

Example 10. Collecting logs from audit.log

This configuration uses the im_file input module to read the Auditd log file. Next, it parses key-value pairs with the xm_kvp module and enriches log records with the $Hostname, $FQDN, $Tag, and $SourceName fields. Finally, it converts log records to JSON format with the to_json() procedure of the xm_json module.

nxlog.conf
<Extension json>
    Module          xm_json
</Extension>

<Extension audit_parser>
    Module          xm_kvp
    KVPDelimiter    ' '
    KVDelimiter     =
    EscapeChar      '\'
</Extension>

<Input linux_audit>
    Module          im_file
    File            '/var/log/audit/audit.log'
    <Exec>
        audit_parser->parse_kvp();
        $Hostname = hostname();
        $FQDN = hostname_fqdn();
        $Tag = "audit";
        $SourceName = "selinux";
        to_json();
    </Exec>
</Input>

Forwarding audit logs over the network with audispd

The Audit dispatcher audispd can forward events to a remote server with the audisp-remote plugin included in the audispd-plugins package.

  1. Configure the audisp-remote plugin. Specify the appropriate remote_server and format for your environment.

    /etc/audisp/audisp-remote.conf
    remote_server = 127.0.0.1
    port = 60
    transport = tcp
    queue_file = /var/spool/audit/remote.log
    mode = immediate
    queue_depth = 2048
    format = ascii
    network_retry_time = 1
    max_tries_per_record = 3
    max_time_per_record = 5
    heartbeat_timeout = 0
    
    network_failure_action = stop
    disk_low_action = ignore
    disk_full_action = ignore
    disk_error_action = syslog
    remote_ending_action = reconnect
    generic_error_action = syslog
    generic_warning_action = syslog
    overflow_action = syslog
  2. Activate the plugin from /etc/audisp/plugins.d/au-remote.conf by setting active = yes.

  3. Optionally, you can disable logging to file by Auditd. Edit /etc/audit/auditd.conf and set write_logs = no (this option is the same as log_format = NOLOG).

  4. Configure and restart NXLog Agent.

  5. Restart the Auditd service.

Example 11. Receiving audit logs over the network

This configuration uses the im_tcp input module to listen for logs on TCP port 60. It parses key-value pairs with the xm_kvp module and enriches log records with the $Hostname, $FQDN, $Tag, and $SourceName fields.

nxlog.conf
<Extension audit_parser>
    Module          xm_kvp
    KVPDelimiter    ' '
    KVDelimiter     =
    EscapeChar      '\'
</Extension>

<Input linux_audit>
    Module          im_tcp
    ListenAddr      0.0.0.0:60
    <Exec>
        audit_parser->parse_kvp();
        $Hostname = hostname();
        $FQDN = hostname_fqdn();
        $Tag = "audit";
        $SourceName = "auditd";
    </Exec>
</Input>
Disclaimer

While we endeavor to keep the information in our guides up to date and correct, NXLog makes no representations or warranties of any kind, express or implied about the completeness, accuracy, reliability, suitability, or availability of the content represented here. We update our screenshots and instructions on a best-effort basis.

The accurateness of the content was tested and proved to be working in our lab environment at the time of the last revision with the following software versions:

NXLog Agent version 5.5.7535
Ubuntu 20.04
Centos 7

Last revision: 5 October 2022