auditdistd - Audit trail files distribution daemon
About Security Event Audit
Security Event Audit is a facility to provide fine-grained, reliable and configurable logging of a variety of security-relevant system events, including logins, configuration changes, and file and network access.
About auditdistd
One of the key purposes of logging security events is postmortem analysis in case of system compromise. Currently, the kernel can push audit records directly into a file or make them available through the /dev/auditpipe device. Because audit logs are stored locally by the kernel, an attacker has access to them once the system is compromised, which enables him to remove trails of his activity.
The auditdistd daemon distributes audit records over the TCP/IP network from a local system to a remote system also running the auditdistd daemon. The project focuses on:
- Security. The auditdistd daemon was designed from the ground up to make use of strong sandboxing techniques, like capsicum(4) and jail(2). Entire network traffic is protected by the TLS encryption. In an event of network protocol compromise sandboxing prevents the attacker from accessing or modifying already delivered audit records, not to mention accessing any other parts of the operating system.
- Reliability. Audit records are considered delivered only after confirmation from the remote system that they are safely stored on disk.
- Low latency. The auditdistd daemon uses kqueue(2) to be quickly notified about new audit records, so it can distribute them as fast as possible. The goal here is to reduce number of lost or untrusted audit records in case of a system compromise.
How does auditdistd work
The auditdistd, depending on the configuration can either run in sender-only mode or in receiver-only mode or in both modes.
In the receiver mode it is responsible for receiving audit records from the sender, storing them locally and confirming. It does not interpret received audit records mostly to avoid possible bugs in interpreter code and also to not reduce performance. This also allows to receive audit trail files in an unknown format and continue interrupted connection even in the middle of single audit record. Special care is taken for the receiver to not touch already received data. It can only open existing file in append-only mode if it is the most recent trail file or create new trail file if it will be newer than any other already received file.
In the sender mode auditdistd relies on auditd(8) to pass all newly created trail files to auditdistd-managed directory (/var/audit/dist/) by creating hard links. When trail file is terminated and auditd renames it, it will also rename the file in the /var/audit/dist/ directory. This behavior is enabled by adding 'dist:on' line to the /etc/security/audit_control file. Because hard links are used, both /var/audit and /var/audit/dist directories must be stored on the same file system, as hard links cannot cross mount point boundaries. This design choice allows to keep local retention policy for audit trail files totally independent from the existence of auditdistd daemon. If trail file from /var/audit/ needs to be removed, but auditdistd didn't complete sending it yet, only /var/audit/ entry will be removed and the /var/audit/dist/ entry will be left untouched. And if auditdistd managed to send entire terminated trail file, it will remove only its link from /var/audit/dist/ without touching the entry in /var/audit/ directory.
Quick start
On the receiver host
Ensure that the auditdistd user exists:
# grep ^auditdistd: /etc/master.passwd auditdistd:*:78:77::0:0:Auditdistd unprivileged user:/var/empty:/usr/sbin/nologin
Ensure that the /var/audit/remote directory exists, has proper permission and ownership:
drwx------ 2 auditdistd wheel /var/audit/remote
If not:
# mkdir -m 0700 /var/audit/remote # chown auditdistd:wheel /var/audit/remote
Generate private key and self-signed certificate for the receiver. Auditdistd verifies public key's finger print and does not perform whole PKI verification path. Finger print verification is more trustworthy, but a bit harder to manage in the long run - if certificate is replaced on the receiver all configuration files on the sender hosts has to be updated. This is the quickest method of generating x509 certificate, so it doesn't even bother to configure various fields properly, but as mentioned earlier only public key matters for the sender.
# openssl req -x509 -nodes -newkey rsa:4096 -days 1825 -batch \ -out /etc/security/auditdistd.cert.pem \ -keyout /etc/security/auditdistd.key.pem # chmod 0600 /etc/security/auditdistd.key.pem /etc/security/auditdistd.cert.pem # chown root:wheel /etc/security/auditdistd.key.pem /etc/security/auditdistd.cert.pem
Print certificate public key's finger print in a form ready to be pasted into sender's configuration file:
# openssl x509 -in /etc/security/auditdistd.cert.pem -noout -fingerprint -sha256 | \ awk -F '[ =]' '{printf("%s=%s\n", $1, $3)}' SHA256=8F:0A:FC:8A:3D:09:80:AF:D9:AA:38:CC:8A:86:53:E6:8F:B6:1C:55:30:14:D7:F9:AA:8B:3E:73:CD:F5:76:2B
Generate password used to authenticate both hosts against each other. For example this way:
# dd if=/dev/urandom bs=32 count=1 | openssl base64 | cut -b -32 YjwbK69H5cEBlhcT+eJpJgJTFn5B2SrG
Create /etc/security/auditdistd.conf configuration file:
receiver { host "sender-hostname" { remote "tls://10.0.0.101" password "YjwbK69H5cEBlhcT+eJpJgJTFn5B2SrG" } }
Don't forget to change sender's hostname, its IP address and password.
Because the configuration file contains passwords, set its permissions properly:
# chmod 600 /etc/security/auditdistd.conf # chown root:wheel /etc/security/auditdistd.conf
Add the following line to the /etc/rc.conf file:
auditdistd_enable="YES"
And run:
/etc/rc.d/auditdistd start
On the sender host
Ensure your kernel is compiled with:
options AUDIT
by checking if sysctl kern.features.audit exists and is set to 1.
Ensure that the auditdistd user exists:
# grep ^auditdistd: /etc/master.passwd auditdistd:*:78:77::0:0:Auditdistd unprivileged user:/var/empty:/usr/sbin/nologin
Ensure that the /var/audit/dist directory exists, has proper permission and ownership:
drwxrwx--- 2 auditdistd audit /var/audit/dist
If not:
# mkdir -m 0770 /var/audit/dist # chown auditdistd:audit /var/audit/dist
Add the following line to the /etc/security/audit_control file:
dist:on
Turn on events auditing by starting auditd(8) daemon. Add the following line to the /etc/rc.conf file:
auditd_enable="YES"
And run:
/etc/rc.d/auditd start
Create /etc/security/auditdistd.conf configuration file:
sender { host "receiver-hostname" { remote "tls://10.1.0.100" fingerprint "SHA256=8F:0A:FC:8A:3D:09:80:AF:D9:AA:38:CC:8A:86:53:E6:8F:B6:1C:55:30:14:D7:F9:AA:8B:3E:73:CD:F5:76:2B" password "YjwbK69H5cEBlhcT+eJpJgJTFn5B2SrG" } }
Because the configuration file contains passwords, set its permissions properly:
# chmod 600 /etc/security/auditdistd.conf # chown root:wheel /etc/security/auditdistd.conf
Add the following line to the /etc/rc.conf file:
auditdistd_enable="YES"
And run:
/etc/rc.d/auditdistd start