Content-type: text/html
nabou [options]
It stores the properties for each file in a dbm database and will warn you if something has been changed on a file. The most important thing to check for, is the MD5-checksum. This checksum will never be the same if the file content has changed even if only one letter has changed. But you can also look for some other properties, like ownership or filemode. See the section Configuration for more details.
You can use nabou as an Intrusion Detection System or simply as a system monitor.
useshadow 1 # we are using shadow supportYou can comment out large blocks using a C-style comment:
/* passwd /etc/passwd shadow /etc/shadow shells /etc/shells */The configuration is devided into several sections. There are some main-options and some blocks for a special purpose. Most of the options are simply switches, where a value of 1 turns it on and 0 turns it off. If you omit an option then this has the same effect as setting it to 0 (zero).
You can omit an option if nabou provides a buildin default value, which described for every option.
<db> basedir /home/thomas/nabou/db protected 1 cipher IDEA pwdDB thorpwd sugidDB thorsugid csumDB thorcsum cronDB thorcron miscDB thormisc diskusageDB thordu </db>The following attributes must exist:
<mail> rcpt root from root subject report from nabou </mail>The mailblock is required if you turned usemail on. The following attributes must exist:
<bin> sendmail /usr/sbin/sendmail crontab /usr/bin/crontab </bin>
The suid block defines what attributes should be checked for suid sgid files. If there is no suid block configuration or if the suid block contains no appropriate attributes, then nabou will use defaults, which is MD5 check and file-mode check. You can use all chk_* attributes described below in the directory block. You can set chk_all to 1 if you want to perform all available checks. The suid block does not support the exclude, include, inherit or recursive attributes. An example:
<suid> chk_mode 1 chk_size 1 chk_uid 1 chk_gid 1 </suid>
<directory /some/dir>
and ends with
</directory>
You may define as many directory blocks as you need. Previous versions of nabou had some predefined default checks turned on in case your directory block looked like this one:
<directory /etc> </directory>Today it will not do any checks on a dir unless you tell it what to check. it is also possible to define ``recursive 1'' and nothing more, then it will tell you about added or removed files recursively under that dir, but it will not do any check on any file.
These are the options you may define:
<directory /dev> exclude tt* exclude pt* </directory>If you want to ignore files under a subdirectory, then you are required to specify this file/dir relative to the directoy block. An example:
<dir /usr/local> exclude share/blackbox/* </directory>In the example below, /usr/local/share/blackbox/* will be ignored. The exclude attribute cannot used together with the include attriute (see above).
<directory /home/vasall> include .history include todo </directory>The include attribute cannot be used together with the exclude attribute.
Excluded files will not counted.
If you use one or more include statements, then only
the diskusage of these files will be counted.
<directory /bin> chk_md5 1 recursive 1 </directory> <directory /sbin> inherit /bin </directory>In this example, nabou will do an md5-checksum lookup and do a recursive lookup for the directory /sbin. If the inherit attribute refers to a directory, which is not defined within the configuration, then nabou will warn you about this and use the default attributes chk_md5=1 and recursive=0.
You can specify one or more file attributes nabou shall look for:
The attributes above will be used, if you turn on chk_all!
The followng attributes can also be checked:
The following file attributes cannot be checked with nabou:
access time: that's senceless, because, the accesstime changes when nabou calls stat(2) on a file! And the attributes rdev and blcksize. See stat(2) for details or look at the file dbformat.txt shipped with the nabou tarball.
For that reason a new feature exists, which allows you to define check templates. Once you have defined such a template you can apply it to many directories/files within one check block.
DEFINE BLOCKS
Sample:
<define chk_logfile> chk_shrink 1 chk_mode 1 chk_uid 1 chk_gid 1 </define>This defines a new check template called chk_logfile (you can choose any name you like). This particular template is used to check mode/uid/gid bits and to check if a file shrinks, which is generally not good with logfiles.
You are allowed to use any possible check statement and option which is available for directory blocks too.
CHECK BLOCKS
Now that we have defined our own check template, we want to apply it to some file within one block:
<check chk_logfile> /var/log/messages /var/log/wtmp /var/log/faillog /var/log/lastlog /var/log/kernel /var/log/firewall /var/log/secure </check>That's it.
One thing is important: if you want to use the exclude statement inside a check block, then you must specify the absolute pathname, relative pathnames are not allowed (or: they will not work as you expect!) inside check blocks.
<<include /root/anotherfile>>
nabou reads its contents on this position as if is was written overthere. An example:
--- mail.rc --- <mail> rcpt tom@daemon.de from root@localhost subject nabou report </mail> --- end ---
--- nabou.rc --- <<include mail.rc>> ... --- end ---If you run nabou in multiple instances, say one checks only for suid files once a week and another one checks only for files every day, but both instances shall to use identical mailoptions, you can use the construction above.
You can see a complete configuration example in the file nabourc shipped with the nabou tarball.
You can extend the functionality of nabou by writing ``inline scripts'', (I name them ``scriptlets'' from now on). All of this stuff is done inside the nabou configuration file. You can define any number of scriptlets. After defining a scriptlet you can refer to it by using the directory block option
chk_custom nameThe parameter to chk_custom must be the name of a defined scriptlet. nabou will call this scriptlet on every file within a directory. That means, you need to refer to a scriptlet on a per-directory basis. See the example below.
The scriptlet itself must be written in valid perl5. nabou will save this code in an anonymous sub and call it using a closure. This sub will get 3 arguments from nabou, a File object, the current directory and a string containing the current message for the current file.
If the message is empty no other check found something, if is is not empty it contains the explanation of what nabou already found about this file.
The File object needs some further explanation: You can access every file attribute by using the -> notation. Possible attributes are size, uid, atime and so on (see dbformat.txt for more available attributes).
Beside of these, there are two more attributes: filename and md5. filename returns the file name of the current file (the absolute file name!). md5 returns the checksum of the current file. This maybe a MD5 checksum but can also be SHA1 or MD2, which depends on your configuration(see use_algo above!).
If you want complete integration of the scriptlet into the nabou workflow, then you need to return a message, you don't have to print it just out to STDOUT!
One or more script(s) must be defined using the <script> block. This block starts with <script> and ends with </script>. Inside the block you need to define the code using a so called here-document. The name of this here document must be the script-name followed by an end identifier after the magical << characters.
Nabou will read everything in until the end identifier occurs. There is no space, tabulator or anything else allowed after this identifier! The name that you give the scriptlet will be used later for referencing to, by using the chk_custom attribute in the directory block.
An example says it all:
--- snip --- <script> test <<EOF my($file, $dir) = @_; return "SIZE of " . $file->filename . ": " . $file->size . " bytes\n"; EOF </script>
<directory /tmp/test> chk_md5 1 chk_mode 1 chk_custom test </directory> --- snap ---In this example nabou will run the following sub:
sub { my($file, $dir) = @_; return "SIZE of " . $file->filename . ": " . $file->size . " bytes\n"; }on every file it finds in /tmp/test.
Additional you access the complete namespace of nabou. This is powerful, but also danger. But a really good use of this case is that you can access the %config hash, which contains a data structure of the whole configuration. You could create your own configuration block, which will be used by your scriptlet! An example custom config block (which will simply ignored by nabou itself, but it will be loaded into %config!):
<test> user max pass nim9w port 31733 </test>Inside your scriptlet you can access to the values inside <test> using the following method:
$user = $config{test}->{user};or
$pass = $config{test}->{pass};There are two sciptlet names which have a special purpose: BEGIN and END. The BEGIN scriptlet will be executed only once at startup IF it exists, and the END scriptlet will be executed only once at the end respectively IF it exists. This is very usefull if you want to open e file or database, which your scriptlet(s) later can use.
An example:
<script> test <<EOF my($file, $dir) = @_; print TEST " DIR: $dir\n"; print TEST "FILE: " . $file->filename . "\n\n"; return ""; EOF
BEGIN <<EOF open TEST, ">/home/thomas/nabou/test" or die $!; EOF
END <<EOF close TEST; EOF </script> <directory /usr> chk_custom test </directory>As you can see, the ``test'' scriptlet, which will be executed for every file under /usr prints a line to a filehandle ``TE''. Under normal circum- stances this wouldn't be possible, because it were not opened somewhere before. But if you define a BEGIN scriptlet as in the example above, which opens this filehandle, then the ``test'' scriptlet can access this handle.
You need to know, that both the BEGIN and the END scriptlets are not evaluated as a anonymous sub-routine. They are evaluated inside the main namespace, in other words, variables which you define here are accesible globally!
A note about return values of scriptlets: If you don't want the scriptlet to cause a match, then you need to return an empty string:
return "";otherwise it would be a match and appear in the nabou report!
Nabou gathers a list of all running processes with all properties it
can get from /proc. Most properties are those, which you can see when
you use ps. But there are also some other, very interesting properties.
Currently it uses 4 different methods to find out if a process could
be dangerous:
If you use nabou for process monitoring, you can use the -D option, which causes nabou to turn itself into the background (using fork(2). You can also define exceptions for processes which should be ignored furing the normal run, like xterm's or so.
See the provided example config file psrc for a demonstration.
But be warned: This directory may become very huge!
cmdline /root/bin/checkusers.sh cmdline /root/bin/checksnort.shYou can also use perl regular expressions here, but be very careful!
An example:
<exclude /bin/bash> # login shells cmdline -bash md5 c36b467680f96a6c63053df2c0df379e </exclude>
The Process object contains all available information about the current checked process. If the message is empty no other check found something, if is is not empty it contains the explanation of what nabou has already found about this file.
An example:
<script> test <<EOF my($prc, $lastmatch) = @_; if($prc->exe =~ /^\/tmp\/.*sh.*$/) { return "shell running from /tmp!"; } else { return ""; } EOF </script>As you can see, you can access every property using the arrow notation: cmdline is: $prc->cmdline, the pid is: $prc->pid.
Here is a list of all available properties, which can also be used for
reporting (see above about the report option!):
see a more detailed description of the other properties in the proc(5) manpage: ``man proc'', look for ``stat Status information about the process'':
state ppid pgrp session tty tpgid flags minflt cminflt majflt cmajflt utime stime cutime cstime counter priority timeout itrealvalue starttime vsize rss rlim startcode endcode startstack kstkesp kstkeip signal blocked sigignore sigcatch wchan nswap cnswap exit_signal
There is a complete (tested) sample configuration supplied with nabou called psrc, which you can use as a starting point. Addional, there is a script called ps supplied in the sub directory ``supplement'', which you can use to see a complete ps-like listing with the following informations: PID RUID EUID RGID EGID FH TTY EXE CMD.
An example:
nabou --init --config /root/.nabourcPlease note, that the output of the initial run of nabou can become very large! You may redirect this output to a file:
nabou --init --config /root/.nabourc > init-lognabou will ask you for a passphrase if the <db> block option protected is turned on and save the encrypted passprase in the file ``keydb'' in your naboudb basedirectory. The phrase will be encrypted using crypt(1), which is a one-way algorithm. This passphrase will be used later if you want to use the ---update or ---reset option.
If you are using a nabou instance for process-monitoring only as demonstrated by the sample ``psrc'' supplied with the package, then the options -i or -r are redundant.
If the ---reset or ---init(or -i/-r) flag is supplied, nabou will not mail out a report even if usemail is turned on.
Now you are ready to install it as a daily cronjob. An example:
30 0 * * * /root/bin/nabou --config /root/.nabourc > /dev/null 2>&1This crontab entry runs nabou every day at 00:30.
There is another commandline option which you can use to re- initialize it's database: -r or ---reset. But be very careful with this option.
If you only want to update the database entry for one file, you can use the option -u or ---update, which requires a filename as argument. If the <db> block option protected is turned on, then nabou will ask you for a passphrase. If the environment variable $NABOU_PASSWD is set, this value will be used as passphrase.
If you omit a filename for ---update then nabou will perform a normal run based on the current config, which is the same as running nabou without any options (beside ---config).
You can also run multiple instances of nabou, but better use different databases for every instance. If every instance should use some identical config options, you might make use of the include statement mentioned earlier in the CONFIGURATION section.
You can run nabou with the -q or ---quiet flag, which causes it only to report changes. In other words, if nothing changed, no report will be sent/printed.
You can view the contents of a nabou database by using the command line flag -d or ---dump. This flag requires the database name as argument and dumps out a comma separated list, one line for one file. The meanings of each field are described in the file dbformat.txt. The dump will be a little bit formatted, time values will be converted to human-readable values (just as the date command tells you), uid and gid values will be converted to their representations (i.e. 0 = root and so on).
If you prefer to get the raw contents unformatted then you can use the flag ---raw in addition to the ---dump or -d flag.
If you run nabou from crontab (without any options but ---config), then it will NOT update the databases! Instead it will only warn you about changes. The next time it runs, it will warn you again, and so forth, until you log on and update the database yourself using the commandline-flag ---update without any parameters. Nabou will ask you for the passphrase and use this passphrase to decrypt the encrypted record-field. If the result is identical with the exiting(old) record, then it will update that record and create a new encrypted field based on that new record.
If the result does NOT match, then something weird has happend with the database. In this case, it will not update the record and send out an email to the receipient specified in <mail> - alert or to ``root'' if not specified.
If you turn on readonly or protected(which automatically turns on readonly too), then I recommend you to protect your databases.
There are several ways for protecting files from being written. You can use a read-only mounted medium, or you can protect the files using chattr(1). The very best and most secure way is to use LIDS (http://www.lids.org). You can secure the complete nabou database directory and you might protect nabou and you config-file(s) as well:
lidsadm -A -o /root/db -j READ lidsadm -A -o /root/bin/nabou -j READ lidsadm -A -o /etc/nabourc -j READIf LIDS is well configured, then only root logged in from a local console is able to turn off LIDS and thus to perform a nabou update. Remote users, and even root, are not able to turn it off, and because of this - not able to perform an update of nabou.
If you use such a setup, then you can be sure you will be informed, if someone nasty got root and installed a trojan horse or added a new UID 0 user account or something else.
/etc/nabourc /sbin/nabou /usr/doc/nabou-VERSION/*