Filtering Alert Messages
When we first implemented the FileChangeWarning alarm, we reported absolutely everything that was ctime changed. It quickly became apparent that too much was being reported, that we had to scale back, that we didn't need to know about ordinary log file changes, for example.
We want to be alerted about what is truly noteworthy, but we don't want to be unduly alarmed, or perhaps worse to become overwhelmed or bored (so that we tend to ignore the routine messages, risking a failure to catch the non-routine buried within).
So, we implemented the following rule to filter alert messages (we began with just "text", and added "data" and "empty file" along the way):
rule // skip, don't bother to report/log if // $inlin =~ "log$" && $command("=file $inlin") =~~ "text|data|empty file" next endif
(We commented out the '$inlin =~ "log$"' because a clever cracker might name program files, e.g., "thislog" or "thatlog".)
Lately, we are growing tired of seeing reports about the same directories changing daily (because they have text or data files within), for example:
WARNING: FileChangeWarning Report ctime-changed files/dirs in file systems/trees that should be stationary /opt/samba/var/locks: directory drwxr-xr-x 2 root root 512 Sep 8 02:39 /opt/samba/var/locks
So, we added "directory" to the regular expression:
rule // skip, don't bother to report/log if // $inlin =~ "log$" && $command("=file $inlin") =~~ "text|data|empty file|directory" next endif
This begins to trouble us a bit, though. Are we perhaps filtering alert messages too much?
We've added still another logical flag to our defines.cfg file:
paranoid FALSE // if TRUE, report every security-related message // (we have put '#ifdef paranoid' wrappers around // some 'output mail' and 'output log' statements // for some of the less important security-related // messages)
We then put an '#ifndef paranoid' wrapper around the FileCheckWarning bypass rule:
#ifndef paranoid rule // skip, don't bother to report/log if // $inlin =~ "log$" && $command("=file $inlin") =~~ "text|data|empty file|directory" next endif #endifdef
If we are not paranoid, then we bypass the unimportant stuff and go on to the next line of input. If we are paranoid, we continue processing the current input line in the rules that follow.
So now, with paranoid generally set to FALSE, for all systems we won't receive quite so many FileCheckWarning messages. Suppose, however, that we have reason to be paranoid about warsaw's security and wish to see everything security-related for that machine. We might do this (again, in defines.cfg):
#if warsaw paranoid TRUE #else paranoid FALSE #endif
Or, we might decide to give special attention to Solaris 2.5 machines:
paranoid #if solaris25 TRUE #else FALSE #endif
(Note the two different #if-#endif wrapper styles used above.)
(Or we could leave in place the default 'paranoid FALSE' in defines.cfg and override at the command line with: piktc -iv +D paranoid ... +H solaris25)
Here's another way we might write the bypass rule:
rule // skip, don't bother to report/log set $filetype = $command("=file $inlin") if $filetype =~~ "text|data|empty file" #ifndef paranoid // if we're not paranoid, then ignore these also: || $filetype =~~ "directory" #endifdef next endif
Another adjustment we might make is to 'output mail' if paranoid (set to TRUE) else 'output log' if not paranoid (set to FALSE). Or we might 'output log' everything, whether paranoid or not.
There's really no end to the potential complexity here, is there?
For more examples, see Developer's Notes.