The Linux audit framework is a security system which can provide accurate information about almost all security-relevant actions running processes may take on a system. The logs created using the audit framework can be used to investigate potential security incidents.

Loggable actions include, but are not limited to:

  • accessing/changing sensitive files
  • execution of specific binaries
  • opening network connections
  • loading kernel modules

Audit is typically used together with SELinux, however this article discusses configuring the audit framework on its own within a Yocto project and some example of auditing rules.

 

Enabling the auditing subsystem in the kernel

Before proceeding with the userspace daemon auditd, you need to enable kernel support for auditing. This can be done via menuconfig, e.g.

bitbake virtual/kernel -c menuconfig

or via explicit config fragments:

CONFIG_AUDIT=y

Some kernels (like those from meta-arm-bsp) may already enable auditing by default. If that is the case, you do not need to do anything for this step.

 

Getting auditd

Honister and later (3.4+)
Users on Honister or a later Yocto release do not need any special layer configuration to get auditd, as it is included in meta-oe.
Hardknott and Dunfell (3.1, 3.3)
Users on Dunfell or Hardknott should add the meta-selinux layer at git://git.yoctoproject.org/meta-selinux to their source tracking system and BBLAYERS variable, pinning the appropriate revision for their Yocto release.

For example, using repo with Hardknott, we can use this manifest entry and this BBLAYERS assignment:

  <project name="meta-selinux" path="sources/meta-selinux" remote="yocto" revision="8b94f828a292d0e61d83aeeeeb4001c7cde08721" upstream="hardknott" />
BBLAYERS += " ${BSPDIR}/sources/meta-selinux"

Earlier releases
Projects on earlier releases of Yocto or OpenEmbedded Classic no longer benefit from regular security updates at the time of writing. The instructions provided may or may not still work, but this is not recommended.

 

Installing auditd

To install auditd, add auditd to the IMAGE_INSTALL list of packages for your image. This installs the auditd userspace daemon and init scripts to launch it automatically on boot.

IMAGE_INSTALL_append = " auditd"

If you are not using systemd, then start-stop-daemon is also needed for audit’s rules to load correctly.

IMAGE_INSTALL_append = " auditd dpkg-start-stop"

auditd in action

With auditd installed and our firmware image deployed, we can now see the two components of the auditing system in the list of running processes:

  • The kernel task kauditd
  • The userspace auditd daemon
root@imx8qxp-b0-mek:~# ps | grep audit
   31 root         0 SW   [kauditd]
  598 root     11304 S<   /sbin/auditd

If we check the audit log in /var/log/audit/audit.log, we see a message that the system has started:

root@imx8qxp-b0-mek:~# cat /var/log/audit/audit.log
type=DAEMON_START msg=audit(1520598905.876:992): op=start ver=3.0.1
  format=enriched kernel=5.10.69+g54bd61ba352b auid=4294967295 pid=598 uid=0
  ses=4294967295 res=successAUID="unset" UID="root"

However, since we just installed it, we are not logging anything yet. To log an action like reading from /etc/passwd, we can add a new auditing rule with auditctl.

root@imx8qxp-b0-mek:~# auditctl -w /etc/passwd -p warx -k passwd

Explanation of the options:

Option Description
-w /etc/passwd Adds a new watch for the file at the given path, /etc/passwd. This option only works with existing files and directories, not wildcards.
-p warx Specifies the type of watch to perform. In this case, Write, Attribute change, Read, and eXecute will be logged when performed on the given file.
-k passwd Specifies a group name for this watch. For example, we may also want to watch /etc/shadow with a group named passwd.

After doing this, we can read from /etc/passwd:

root@imx8qxp-b0-mek:~# cat /etc/passwd > /dev/null

And check the audit log again:

type=PATH msg=audit(1677197344.196:4): item=0 name="/etc/passwd" inode=176
  dev=fc:01 mode=0100644 ouid=0 ogid=0 rdev=00:00 nametype=NORMAL cap_fp=0
  cap_fi=0 cap_fe=0 cap_fver=0 cap_frootid=0OUID="root" OGID="root"

The file access was successfully written to the audit log.

 

Using rules files

A rules file is any file used with auditd that adds functionality like the above. Rules files consist of a format identical to the command-line format of auditctl, but also allow extra whitespace and comments. An example is shown below.

30-passwd.rules
# Watch writes to passwd file
-w /etc/passwd -p wa -k passwd

# Watch all accesses to shadow file
-w /etc/shadow -p warx -k passwd

# Watch for groups changes
-w /etc/group -p wa -k passwd

There are a number of sample rules that come with auditd that you may like to use. A full list of these rules can be found in the sources.

 

Installing rules

To use a rule, copy its file into /etc/audit/rules.d and it will be loaded when audit starts.

To simplify the process, you can use a custom-audit-rules.bb recipe like the following:

SUMMARY = "Custom rules for audit"
DESCRIPTION = "Adds additional audit rules"

LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/${LICENSE};md5=0835ade698e0bcf8506ecda2f7b4f302"

# Audit rules files are placed in the custom-audit-rules directory adjacent to the recipe location.
AUDIT_RULES := " 30-pci-dss-v31.rules 40-local.rules 41-containers.rules"
RDEPENDS_${PN} := "audit"

python () {
    d.setVar('SRC_URI', ' '.join(f'file://{path}' for path in d.getVar('AUDIT_RULES').split()))
}

do_install() {
    RULES_DIR=${D}${sysconfdir}/etc/audit/rules.d
    install -d $RULES_DIR

    for rule in ${AUDIT_RULES}; do
        install -m 0644 ${S}/$rule $RULES_DIR/$rule
    done
}

FILES_${PN} := "${sysconfdir}/audit/rules.d/*"

For a directory structure like the following,

└── recipes-security
    └── audit
        ├── custom-audit-rules
        │   └── 30-passwd.rules
        └── custom-audit-rules.bb

This recipe will install any specified rules under custom-audit-rules.

 

Conclusion

Using auditd is a simple way to enhance the security posture of your IoT device which can help actively monitor and investigate potential security breaches.

Learn more about our VigiShield offering which implements a number of security best practices, including audit logs.

Liam White McShane, Junior Embedded Systems Engineer, has over a year of experience in designing and debugging embedded systems. He specializes in providing customers with software and firmware services for their devices. Liam holds a bachelor’s degree in Computer Science from the University of Pittsburgh.