Linux Audit System

The Linux Audit system provides fine-grained logging of security related events, so called, Linux audit logs. The system administrator configures Linux auditing rules to specify what events are logged. For example, rules may be configured for logging of:

  • access of a specific file or directory,

  • specific system calls,

  • commands executed by a user,

  • authentication events, or

  • network access.

The Audit system architecture includes:

  • a kernel component which generates events,

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

  • the audisp dispatcher daemon which relays events to other applications for additional processing, and

  • the auditctl control utility which provides configuration of the kernel component.

These tools are provided for reading the Audit log files:

  • aulast prints out a listing of the last logged in users,

  • aulastlog prints out the last login for all users of a machine,

  • aureport produces summary reports of the Audit logs,

  • ausearch searches Audit logs for events fitting given criteria, and

  • auvirt prints a list of virtual machine sessions found in the Audit logs.

For more information about the audit system, see the System Auditing chapter of the Red Hat Enterprise Linux Security Guide, the installed manual pages, and the Linux Audit Documentation Project.

Audit rules

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

There are three types of rules: a control rule modifies Audit’s behavior, a file system rule watches a file or directory, and a system call rule generates a log event for a particular system call. For more details about Audit rules, see the Defining Audit Rules page of the Red Hat Enterprise Linux Security Guide.

Common control rules include the following.

  • -b backlog: Set the maximum number of audit buffers. This should be higher for busier systems or for heavy log volumes.

  • -D: Delete all rules and watches. Normally used as the first rule.

  • -e [0..2]: Temporarily disable auditing with 0, enable it with 1, or lock the configuration until the next reboot with 2 (used as the last rule).

Example 1. Control rules

This is a set of basic rules, some form of which is likely to be found in any ruleset.

# Delete all rules (normally used first)
-D

# Increase buffers from default 64
-b 320

# Lock Audit rules until reboot (used last)
-e 2

To create a file system rule, use -w path -p permissions -k key_name.

  • The path argument defines the file or directory to be watched.

  • The permissions argument sets the kinds of accesses that are logged, and is a string containing one or more 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. File System rule

This rule watches /etc/passwd for modifications and tags these 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.

  • The action argument can be either always (to generate a log entry) or never (to suppress a log entry). Generally, use never rules before always rules, because rules are matched from first to last.

  • 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 by name, and can be repeated by using multiple -S flags.

  • The field=value pair can be used to specify additional match options, and can also be used more than once.

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

Example 3. System Call rule

This rule generates a log entry when the system time is changed.

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

System call rules can also monitor activities around files, such as:

  • creation,

  • modification,

  • deletion,

  • access, permission, and owner modifications.

Example 4. Deletion rule

This rule generates a log entry when a file is deleted 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

External connections can be monitored with the example below.

Example 5. Networking rule

This rule checks whether an incoming or outgoing external network connection has been established.

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

The different types of rules are combined to form a ruleset.

Example 6. The audit rules file

This is a simple Audit ruleset based on the above examples.

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

# Increase buffers from default 64
-b 320

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

# Generate a log entry when the system time is changed
-a always,exit -F arch=b64 -S adjtimex -S settimeofday -k system_time

# Lock Audit rules until reboot
-e 2

For more examples of rules, see the The Linux Audit Project and auditd-attack sections on GitHub.

Logging audit messages to local Syslog

The Audit system can also be customized to forward log messages to Syslog.

Example 7. Logging audit messages to local Syslog

The Audit’s syslog plugin should be enabled to forward logs to the /dev/log socket. In this case, the /etc/audisp/plugins.d/syslog.conf file should be edited to look like the sample below.

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

A sample rule can be created in the /etc/audit/rules.d/audit.rules file to monitor modifications of the /tmp/audit_syslog file.

-w /tmp/audit_syslog -p wa

NXLog needs to be configured to accept Syslog messages from the /dev/log socket.

By default, NXLog cannot bind to the /dev/log socket due to the limitations of the nxlog user. See the Running Under a Non-Root User on Linux section for ways to handle this.

The configuration below accepts logs from the socket using the im_uds module and the Exec block selects only messages which contain the audit_syslog string. These messages are parsed with the parse_syslog_bsd() procedure of the xm_syslog module and converted to JSON using the to_json() procedure of the xm_json module.

<Extension _syslog>
    Module    xm_syslog
</Extension>

<Extension json>
    Module    xm_json
</Extension>

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

After configuring, auditd and NXLog should be restarted:

# systemctl restart auditd
# systemctl restart nxlog

Below is an output sample of a JSON-formatted log entry which can be obtained using this configuration.

{
  "EventReceivedTime": "2020-04-28T21:09:13.959876+00:00",
  "SourceModuleName": "from_uds",
  "SourceModuleType": "im_uds",
  "SyslogFacilityValue": 1,
  "SyslogFacility": "USER",
  "SyslogSeverityValue": 6,
  "SyslogSeverity": "INFO",
  "SeverityValue": 2,
  "Severity": "INFO",
  "Hostname": "administrator",
  "EventTime": "2020-04-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\""
}

Using im_linuxaudit

NXLog Enterprise Edition includes an im_linuxaudit module for directly accessing the kernel component of the Audit System. With this module, NXLog can be configured to configure Audit rules and collect logs without requiring the Linux auditd or any other userspace software.

If a Linux Audit System (im_linuxaudit) module instance is suspended and the Audit backlog limit is exceeded, all processes that generate Audit messages will be blocked. For this reason, it is recommended for most cases that FlowControl be disabled for im_linuxaudit module instances. With flow control disabled, a blocked route will cause Audit messages to be discarded. To reduce the risk of log data being discarded, make sure the route’s processing is fast enough to handle the Audit messages by adjusting the LogQueueSize of the following modules and/or adding a pm_buffer instance.
Example 8. Auditing with im_linuxaudit

This configuration uses a <Rules> block to specify a rule set.

nxlog.conf
<Input 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 default 64
        -b 320

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

        # Generate a log entry when the system time is changed
        -a always,exit -F arch=b64 -S adjtimex -S settimeofday -k system_time

        # Lock Audit rules until reboot
        -e 2
    </Rules>
</Input>
Example 9. Using a separate rules file with im_linuxaudit

This configuration is the same as the previous, but it uses a separate rules file. The referenced audit.rules file is identical to the one shown in the above example, but it is stored in a different location (because auditd is not required).

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

Using the linux auditd userspace

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

Setting up auditd

First, the audit userspace components must be installed and configured.

  1. Install the Audit package. Include the audispd-plugins package if required for use with audispd (see the Collecting via the network with audispd section below).

    • For RedHat/CentOS:

      # yum install audit
    • For Debian/Ubuntu:

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

  3. After modifying the configuration or rules, enable or restart the auditd service to reload the configuration and update the rules (if they are not locked).

    • For RedHat/CentOS:

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

      # systemctl restart auditd

Reading Linux auditd logs

By default, auditd logs events to /var/log/audit/audit.log with root ownership. NXLog can be configured to read logs from that file.

  1. NXLog cannot read logs owned as root when running as the nxlog user. Either omit the User option in nxlog.conf to run NXLog as root, or adjust the permissions as follows (see Reading Rsyslog log files for more information about /var/log permissions):

    1. use the log_group option in /etc/audit/audit.conf to set the group ownership for Audit log files,

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

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

  2. Configure NXLog (see the example below) and restart.

Example 10. Reading from audit.log

In the Input block of this configuration, Audit logs are read from file, the key-value pairs are parsed with xm_kvp, and then some additional fields are added. In the Output block, the messages are converted to JSON format, BSD Syslog headers are added, and the logs are sent to another host via TCP.

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

<Extension _syslog>
    Module      xm_syslog
</Extension>

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

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

<Output out>
    Module      om_tcp
    Host        192.168.1.1
    Port        1514
    Exec        to_json(); to_syslog_bsd();
</Output>

Collecting via the network with audispd

The Audit dispatcher (audispd) can be configured to forward log events to a remote server using the audisp-remote plugin included in the audispd-plugins package.

  1. Configure the audisp-remote plugin. Use appropriate values for the remote_server and format directives.

    /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 by editing /etc/audisp/plugins.d/au-remote.conf and setting active = yes.

  3. Optionally, auditd may be configured to forward logs only (and not write to log files). Edit /etc/audit/auditd.conf and set write_logs = no (this option replaces log_format = NOLOG).

  4. Configure NXLog (see the example below), then restart NXLog.

  5. Restart the auditd service.

Example 11. Collecting via the network

With the following configuration, NXLog will accept Audit logs via TCP from audispd on the local host, parse the key-value pairs with xm_kvp, and add some additional fields to the event record.

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

<Input in>
    Module      im_tcp
    Host        127.0.0.1
    Port        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 this topic 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.

Last revision: 05 May 2020