I figured I would share with you, a setup I am using on all my BSD servers to monitor changes to the filesystem.
The idea is to be notified by email at a certain interval (eg: once a day) with a list of all files that have changed since last time the check ran.
This, allows you to be notified when files change without your knowledge, for example, in the event of a cracker breaking into the server or if you accidentally, recursively chowned /, and you managed to interrupt the command; mtree allows you to see how many of the files were affected, and fix them.
As mtree also reports HOW the files were changed. For example, in the chown scenario it would mention the expected uid/gid and what it changed to. This would allow for an automated recovery of such a disaster.
In addition to the e-mail notifications it will also keep a log file (by default in /var/log/mtree.log)
The utility we’ll use for this on FreeBSD is mtree (On GNU/Linux you’d have to use tripwire or auditd).
I wrote a perl script which uses mtree to accomplish what I described above: download it.
So basically, to set it up, you can do the following:
mkdir /usr/mtree
cd /usr/mtree
touch fs.mtree fs.exclude
wget http://linkerror.com/programs/automtree
chmod +x automtree
Now, if you run ./automtree -h you’ll see a list of valid options with some documentation:
Usage: ./automtree [OPTION] ...
Show or E-mail out a list of changes to the file system.
mtree operation options:
-u, --update Updates the file checksum database after
showing/mailing changes.
-uo, --update-only Only update the file checksum database.
-p, --path Top level folder to monitor (default: /)
-q, --quiet Do not output scan results to stdout or any
other output.
Path configuration options:
-l, --log Logfile location
(default: /var/log/mtree.log)
--mtree Set the location of the mtree executable.
(default is /usr/sbin/mtree)
--checksum-file Set the location of the file containing the
mtree file checksums.
(defaul: /usr/mtree/fs.mtree)
--exclude-file Set the location of the file containing the
list of files and folders to exclude from the
mtree scan. (default is /usr/mtree/fs.exclude)
E-mail options:
-e, --email Adds specified e-mail address as destination.
--sendmail Set the location of the sendmail executable.
(default: /usr/sbin/sendmail)
--reply-to Set the e-mail reply-to address.
--subject Sets The e-mail subject.
Misc options:
-h, --help Display this help text.
Example usage:
./automtree -uo
./automtree -u -q -e foo@example.com -e bar@example.com
./automtree /var/www --mtree /usr/local/sbin/mtree
As you can see, by default, the script will just index the entire filesystem, as the default for the -p option is / … In order to do this you’ll want to ignore some folders, so edit the fs.exclude file, and stick at least this into it:
./dev
./proc
./var
./tmp
./usr/mtree
./usr/share/man
./usr/share/openssl/man
./usr/local/man
./usr/local/lib/perl5/5.8.8/man
./usr/local/lib/perl5/5.8.8/perl/man
Note that you have to prefix folders with ./
So now, in order to automatically scan and receive notifications, the command which will go into crontab is:
./automtree -u -q -e foo@example.com
(It is possible to add multiple -e options for multiple e-mail destinations.)
The command above will not output to stdout (-q), email filesystem changes to foo@example.com (-e foo@example.com), and automatically update the checksum file with the newly discovered changes (-u).
An example crontab line, to check every 3 hours (type crontab -e to edit your crontab):
0 */3 * * * /usr/mtree/automtree -u -q -e youremail@example.com &> /dev/null
The script won’t send an e-mail if there are no changes to report.