The configuration file for samhain is named samhainrc by default. Also by default, it is placed in /etc. (Name and location is configurable at compile time). The distribution package comes with a commented sample configuration file.
This section introduces the general structure of the configuration file. Details on individual entries in the configuration files are discussed in Section 5.4> (which files to monitor), Section 4.1> (what should be logged, which logging facilities should be used, and how these facilities are properly configured), and Section 5.11> (monitoring login/logout events).
The configuration file contains several sections, indicated by headings in square brackets (e.g. [Database]). Sections exist to group related directives and avoid eventual name clashes among options. Any particular section may occur multiple times.
Each section may hold zero or more key=value pairs. Keys are not case sensitive, and space around the '=' is allowed, as well as before the key and after the value. More specifically: the line is processed by splitting into key and value at the first '=', trimming whitespace from the beginning and end of both key and value, and converting the key to lowercase.
Blank lines and lines starting with '#' are comments. Everything before the first section and after an [EOF] is ignored. The [EOF] end-of-file marker is optional. The file thus looks like:
# this is a comment [Section heading] key1=value key2=value [Another section] key3=value key4=value
For boolean values the following are equivalent (case-insensitive): True, Yes, or 1. Likewise, the following are equivalent (case-insensitive): False, No, or 0.
In lists, values can be separated by space, tabs, or commas.
![]() | Tip |
---|---|
Each section may occur multiple times. |
![]() | Note |
---|---|
You can explicitely end the configuration file with an [EOF] (on a separate line), but this is not required, unless there is some junk beyond that may confuse the parser. A PGP signature does not qualify as 'junk' if samhain is compiled to verify the signature. |
As of version 2.5.3, it is possible to use shell expansion to define the value of an option. For any configuration file option written as Key = $( shell_command ), the string contained within the $() will be passed literally to the shell (by invoking /bin/sh -c shell_command), and the first line returned by the shell - after stripping the newline char - will replace the $(..). If there is no output within 120 seconds, samhain will ignore the configuration option (and report an error).
The PATH environment variable will be set to "/sbin:/bin:/usr/sbin:/usr/bin:/usr/ucb", the SHELL variable to "/bin/sh", the IFS variable to " \t\n", and the TZ variable will be copied from the startup environment. No other environment variables will be set.
In case you are unsure about the need for escaping: yes, the whole string will be passed as a single argument to the shell, like calling /bin/sh -c 'shell_command' from the shell, BUT since this is done from within a C program rather than from a shell, there are no single quotes surrounding the whole string.
In the following example, we parse the output of ifconfig to supply a list of all interfaces to the "PortCheckInterface" option.
# # Lines broken for display purposes. Must be ONE line in config file!!! # Linux/Solaris, FreeBSD, OpenBSD $Linux:.*:.* PortCheckInterface=$( /sbin/ifconfig | grep 'inet addr:' | sed 's/.*r:\([0-9.]*\).*/\1 /' | tr -d '\n'; echo ) $end # Solaris, FreeBSD, OpenBSD $(SunOS|FreeBSD|OpenBSD):.*:.* PortCheckInterface = $( /sbin/ifconfig -a| grep 'inet ' | sed 's/.*t \([0-9.]*\) .*/\1 /' | tr -d '\n';echo ) $end
Conditional inclusion of entries for some host(s) is supported via any number of @if.. / @else / @fi directives. @if.., @else, and @fi must each be on separate lines. Configuration options in the @if.. (or the optional @else) branch will be read or ignored depending on the result of the test.
Supported tests are as follows:
@if hostname_matches regex will succeed if the hostname matches the regular expression given.
@if system_matches regex will succeed if the string sysname:release:machine — i.e. $(uname -s):$(uname -r):$uname - m) — matches the regular expression given.
@if file_exists path will succeed if a file with the given absolute path exists. Wildcards/regular expression are not supported.
@if interface_exists address will succeed if a network interface with the given address exists.
@if command_succeeds command will execute /bin/sh -c command and succeed if the exit status is zero. The PATH environment variable will be set to "/sbin:/bin:/usr/sbin:/usr/bin:/usr/ucb", the SHELL variable to "/bin/sh", the IFS variable to " \t\n", and the TZ variable will be copied from the startup environment. No other environment variables will be set.
You can negate a test by saying '@if not ..'. The 'not' may be replaced by a '!'. The following are all valid: '@if not file_exists /etc/motd', '@if !file_exists /etc/motd', and '@if ! file_exists /etc/motd'.
![]() | Note on backward compatibility |
---|---|
For backward compatibility, instead of @if hostname_matches hostname you can also say @hostname. Likewise, instead of @if system_matches sysname:release:machine you can also say $sysname:release:machine. Also, the old method of negating by prepending a '!' to the '@' ('$') is still supported, as well as the use of '@end' ('$end') instead of '@fi'. |
@if hostname_matches foobar # only read if hostname is 'foobar' @else # read if hostname is NOT 'foobar' @fi @if not hostname_matches foobar # not read if hostname is 'foobar' @fi @if system_matches Linux:2.6.24-21-generic:i686 # only read if $(uname -s):$(uname -r):$(uname -m) # matches Linux:2.6.24-21-generic:i686 @fi @if !system_matches Linux:2.6.24-21-generic:i686 # not read if $(uname -s):$(uname -r):$(uname -m) # matches Linux:2.6.24-21-generic:i686 @fi