How to Configure Audit(4) for Security Event Logging on FreeBSD
How to enable FreeBSD BSM auditing, select useful event classes, protect trail storage, rotate safely, filter records, and verify capture.
FreeBSD’s BSM audit subsystem records kernel-mediated security events in structured binary trails. It can distinguish subjects, event classes, success and failure, paths, arguments, and return values in ways ordinary syslog often cannot. It is evidence for accountability and incident response, not an immutable remote ledger: root compromise can still attack local configuration and files, so retention and off-host protection remain part of the design.
Plan classes, storage, and failure policy first
Read the installed class and event definitions before copying a flag set:
less /etc/security/audit_class
less /etc/security/audit_event
man audit_control
Common classes include lo for login/logout, aa for authentication and authorization, ad for administrative actions, ex for program execution, and file-operation classes such as fc, fd, and fw. With no prefix, a class captures successful and failed events; + selects success and - selects failure. Thus lo,+ex means both outcomes for logins but successful executions only.
Broad execution or file-write auditing can generate enormous trails and may capture sensitive command arguments. Estimate volume on a representative host. Prefer a dedicated /var/audit filesystem or dataset with monitoring and enough space that audit growth cannot consume root. Keep permissions root-controlled and delegate reading through the empty-by-default audit group only to trusted analysts.
Choose availability behavior consciously. The cnt policy continues operation when events cannot be audited; stricter policies can stop or degrade the system to preserve accountability. Neither choice is universally correct. Document whether the service must remain available or must fail closed when audit storage is exhausted.
Configure a conservative baseline
Back up /etc/security/audit_control, then use a baseline like:
dir:/var/audit
dist:off
flags:lo,aa,ad
minfree:20
naflags:lo,aa
policy:cnt,argv
filesz:20M
expire-after:30d AND 2G
flags supplies attributable-user defaults. naflags covers events without an authenticated subject, including relevant pre-authentication failures. argv records execution arguments and increases both investigative value and exposure of secrets passed on command lines. Do not enable envv casually; environments frequently contain tokens and credentials.
filesz rotates a trail at the configured size; values below the documented minimum are ignored. minfree is a percentage threshold that invokes /etc/security/audit_warn actions as free space falls. expire-after controls deletion by age and aggregate size; verify the AND/OR semantics in audit_control(5) against the retention policy rather than assuming the example is legally or operationally sufficient.
Use /etc/security/audit_user for exceptions:
root:lo,+ex:no
www:fc,+ex:no
Its fields add always-audit and never-audit selections to global defaults. Do not use no exclusions to create invisible privileged accounts. Review user-specific rules with the same change control as sudo or SSH policy.
Enable auditing and verify kernel state
Enable the daemon and start it:
sysrc auditd_enable="YES"
service auditd start
service auditd status
auditconfig -getcond
auditconfig -getpolicy
auditconfig -getflags
auditconfig -getcond should report an auditing condition rather than disabled. Inspect /var/log/messages for configuration parsing, storage, and audit warnings. A running PID is insufficient if the kernel condition or flags are wrong.
After configuration changes, use the documented audit controls or restart auditd in a maintenance-aware way, then force a clean trail rotation:
service auditd restart
audit -n
Do not rotate active BSM trails with newsyslog or rename them by hand. audit -n asks auditd to terminate the current trail and switch the kernel to a new one, making the closed file safe for compression or archival.
Generate and read a controlled test event
Perform a benign event included by the selected classes, such as a test-account login/logout or an approved administrative command. Rotate the trail, identify the closed timestamp-named file, and convert it:
ls -lt /var/audit
praudit -l /var/audit/AUDITFILE | less
Replace AUDITFILE; do not assume a current symlink on every setup. praudit -l prints one record per line, but grep alone can lose structured context or match a path token from the wrong record.
Use auditreduce to select before rendering:
auditreduce -u testuser /var/audit/AUDITFILE | praudit -l
auditreduce -c lo /var/audit/AUDITFILE | praudit -l
auditreduce -o file=/etc/ssh/sshd_config /var/audit/AUDITFILE | praudit -l
Path selection is post-capture filtering; audit policy is primarily class- and subject-based. The kernel cannot be assumed to capture only one directory because a later auditreduce command can filter for it. Validate that the underlying file event class is enabled.
Rotate, expire, and export without gaps
Audit trails are named for their start and end timestamps. Unterminated trails after a crash require special care and may not trigger normal close hooks. Customize /etc/security/audit_warn for low-space, rotation, and archival actions, but test it: a broken compression or remote-copy command can silently defeat retention.
For periodic rotation independent of size, schedule /usr/sbin/audit -n as the Handbook describes. Monitor free space, trail creation, daemon status, parse errors, and the age of the newest record. Copy closed trails to access-controlled off-host storage, verify transfer integrity, and synchronize host time so timestamps correlate with other systems.
Live monitoring is available through /dev/auditpipe:
praudit /dev/auditpipe
Use it carefully. Displaying audited network I/O through an audited SSH session can create a feedback loop. Audit pipes are for monitoring and do not replace durable trails.
Validate the security outcome
Test successful and failed authentication, one administrative action, rotation, low-space warning behavior in staging, retention expiry, analyst read access, and off-host restore. Confirm ordinary users cannot read trails. Review arguments for accidentally captured secrets and adjust application practices rather than merely hiding useful events.
Preserve the configuration beside the evidence needed to interpret it: the active audit_control, relevant audit_user entries, hostname, boot identifier, time-synchronization status, and FreeBSD version. A trail copied without its policy context may be authentic yet difficult to explain months later. Restrict changes to that context through the same review process used for other security controls, and alert when the policy or audit service changes unexpectedly.
Hash each closed trail before archival, store the manifest separately, and verify hashes during restore exercises. A checksum detects later alteration but does not prove who created the original, so retain transfer logs, access records, and a documented chain of custody when trails may support an investigation. Test the evidence workflow before an incident, including who may export, receive, decrypt, and interpret archived records.
Auditing succeeds when it captures the chosen events, survives rotation, remains searchable, and has an explicit full-disk response. Enabling every class without verifying any of those properties produces noise, not forensic readiness.
Related:
Sources: