Auditd ingest pipeline with forwarded logs

I have a central log server where all my audit logs are sent via rsyslog. I was running into an issue where the standard auditd ingest pipeline didn't properly parse the audit log because when it is sent from a remote host it has to use the imfile module and that adds fields to the audit log message.

Here are example messages from a remote host forwarded and the audit log of the central log server

audit message forwarded from remote host to central log server
2022-06-14T09:58:35-05:00 rruxsiem1 tag_audit.log type=USER_CMD msg=audit(1655218707.100:227399): pid=14916 uid=1149 auid=1149 ses=32109 msg='cwd="/etc" cmd=7375202D terminal=pts/3 res=success'

audit message from central log server running filebeat
type=USER_CMD msg=audit(1656363195.272:957042): pid=24683 uid=1000 auid=1000 ses=835 subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 msg='cwd="/var/log/rruxsiem1" cmd=7375202D terminal=pts/0 res=failed'

Note the audit message forwarded using imfile has a timestamp, hostname, and tag inserted before the message so the standard parsing implemented by the auditd ingest pipeline wasn't parsing properly. I am posting the solution that I implemented in case this helps anyone else. I added a processor to the auditd.yml module to fix this.

# Module: auditd
# Docs: https://www.elastic.co/guide/en/beats/filebeat/7.15/filebeat-module-auditd.html

- module: auditd

  log:
    enabled: true

    # Set custom paths for the log files. If left empty,
    # Filebeat will choose the paths depending on your OS.
    var.paths: ["/var/log/*/audit*"]
    
    # audit logs forwarded from remote hosts have different format
    # determine if forwarded from remote based on log path
    # forwarded audit logs have path /var/log/{hostname}/audit.log
    # local audit logs have path /var/log/audit/audit.log
    input:
      processors:
        - if:
            not:
              regexp:
                log.file.path: "^/var/log/audit/audit*"
          then:
            - dissect:
                tokenizer: "%{imfile.timestamp} %{host.hostname} %{imfile.tag} %{message}"
                field: "message"
                target_prefix: ""
                overwrite_keys: "true"
            - add_tags:
                tags: [forwarded]
            - copy_fields:
                fields:
                  - from: host.hostname
                    to: host.name
                fail_on_error: false
                ignore_missing: true

The processor checks the log file path and if not the path for a local audit log runs a dissect processor to parse out the first 3 fields added by the imfile module, then adds a forwarded tag so the main filebeat.yml processor doesn't try to add the local host name, and for completeness copies the host.hostname field to the host.name field. Not sure why there are two but in the local audit record both are populated.

Hope this helps someone else. If there is a better solution feel free to post.

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.