Practical auditing on FreeBSD

I'm looking into auditing solutions, and in addition to the pretty straightforward auditd, found https://krvtz.net/posts/practical-process-audit-on-freebsd.html which hints at analysing the collected trail using bsmtrace3 rules.

I would rather like to ask about auditing in practice, beyond what is written. If you have experience monitoring a number of FreeBSD boxes for audit and security purposes, I would be glad to hear about these points:
  • Setup for shipping logs to a remote (if substantially different from `praudit /dev/auditpipe | homebrew-script-to-send-somewhere`)
  • Batched or real-time analysis (recommended software, rulesets, practices on reviewing/creating rulesets)
  • War stories
Thank you!
 
Looking through the threads and resources, some related bits:

generic background​

See http://www.trustedbsd.org/docs.html

auditd:​

Bug about record format when "host" option present in audit_control:​

I've made a quick comparison with my Mac OS X 10.6, which comes with the exact same audit implementation: it works flawlessly. During the comparison, I've noticed that a typical record from auditd on the Mac starts with "header,..." when the same record would start with "header_ex,..." on my FreeBSD. Then I've noticed that very early auditd files (from my first tests) are reading "header" instead of "header_ex".

I've found out that auditreduce -c XX works on auditd records that start with "header", but does not work on records that start with "header_ex".

I've commented out the host field in audit_control, and now new records are created with "header" instead of "header_ex" on the FreeBSD server. It looks like it closely relates to the bug pr#149806. That allows me to use auditreduce with -c flag.

Using setaudit to solve process attribution problem:​

Okay, I'll try... but BSM auditing is still pretty much voodoo to me, so I'm trying to piece together the way I had it set up based on experimentation and a very vague memory... so it will require some experimentation on your part.

I had this in /etc/security/audit_user:

Code:
www:ex:

... which I believe will cause www user to audit all execve() style function calls. Don't forget to restart auditd after changing that stuff, and of course make sure it's running (that was my first gotcha when trying to recreate a working setup just now).

The issue is that "www" will never "log in" to set the audit context, which is what setaudit is for. This caused Apache to successfully audit all execve() functions for me:

# setaudit -a www -m ex /usr/local/etc/rc.d/apache22 restart

Then I can see the events through praudit:

# praudit /dev/auditpipe0
Code:
header,167,10,execve(2),0,Thu May 26 14:15:55 2011, + 738 msec
exec arg,/usr/local/bin/php-cgi
exec env,TZ=EST5EDT
path,/usr/local/bin/php-cgi
attribute,755,root,wheel,105,41199924,164635936
subject,www,www,www,www,www,6186,0,0,0.0.0.0
return,success,0
trailer,167

I then used security/bsmtrace to set up a white list of things that were acceptable for Apache to be executing (eg, php-cgi, via mod_fcgid), and had it alert me if anything else ran (ie, perl, python, or php, would indicate someone trying to exec() a long-running script and that one of my scripts got owned). I think I also had it set up to alert, very loudly, on execve() events on anything inside of /tmp.

My setup was definitely not failure-proof, and did provide false-positives (for example, most PHP forum packages can't trust one particular PHP function for some reason or another, IIRC it was something to do with getting the time, and so would exec() a system binary every chance they got to get it) but it did work. Note that if you were running suexec or whatever, you'd probably want to open up the context a bit more than just the www uid.

I have no idea how these exact settings apply to your particular use case, that's an exercise for you to figure out, but setaudit worked for me at one point. Maybe someone much better versed in it than me can point you further in the right direction, and/or correct any mistakes I've made above. :)

Note about setaudit now being available:​

Quick update: setaudit(8) landed in the FreeBSD src tree in November, 2025 (src: dcb0790bad434ace7cf53259e7a9bcefbef1c69b).

bsmtrace​

syslog-ng​

syslog-ng has configuration that reads the logs (via the "current" file, not the auditpipe), see https://www.syslog-ng.com/community/b/blog/posts/freebsd-audit-source-for-syslog-ng
  • I don't really see the point in the xml or json transforms, but the -l flag to praudit to print related reconds on a single line is nice (now, without xml, are these fixed-column entries? since they get concatenated ... the argv of execve seem dynamic, so with -l indeed one would use -x too, explaining the xml).

auditdistd​

See https://wiki.freebsd.org/auditdistd - seems promising.

Other, tangentially related​

not event based​

 
Back
Top