About Omnidiff
Omnidiff is a general purpose file monitor. It watches for changes, and reports them via email (in universal-diff format).
Only files that Omnidiff knows about will be monitored. The configuration file
defaults to /etc/omnidiff.conf
, but you can specify an alternate path at
run-time by passing it as an argument, e.g.
omnidiff /usr/local/etc/omnidiff.conf
Get Omnidiff at: https://github.com/tangledhelix/omnidiff
Requirements
At least Perl 5.6, and the Text::Diff
module.
License
This software is released under the Simplified BSD License. See the LICENSE
file for the full text.
Installing Omnidiff
Generally you want something like this:
cd && git clone https://github.com/tangledhelix/omnidiff.git
cd ~/omnidiff
cp bin/omnidiff* /usr/bin
cp etc/omnidiff.conf.sample /etc/omnidiff.conf
Then edit /etc/omnidiff.conf
to your liking.
If upgrading, make sure you don't overwrite your existing omnidiff.conf
.
If you don't have root access, see below for installing as an unprivileged user.
Email parameters
By default, email will be sent from root
to root
. You can change those
values in the config file by setting email_from
and email_to
to other
email addresses.
By default, the email will be sent using /usr/sbin/sendmail
. You can change
that by setting email_program
in the config file.
You can customize the subject by setting email_subject
in the config file.
If you insert the token %d
, it will be replaced by the number of files which
this email shows changes for. The default subject line is:
[omnidiff] %d file(s) changed
Defining individual files to watch
Any line starting with the word file
defines a file to watch for changes.
This must be a fully qualified path.
file /etc/passwd
file /etc/group
Defining files using file globbing
Any line starting with the word files
defines a glob pattern. You can use
wildcards or grouping patterns, as in these examples.
# Match all files in a directory
files /path/to/dir/*
# Match all *.cfg files
files /path/to/dir/*.cfg
# Match *.c and *.h files
files /path/to/dir/*.[ch]
# Match *.cfg and *.ini files
files /path/to/dir/*.{cfg,ini}
# Match one character position with '?'
# This would match dns21, dns22, dns23, ...
files /path/to/dir/dns2?.conf
Omnidiff automatically ignores certain files such as Emacs and Vim swap/backup files, and RCS/CVS archive files.
*~ *,v #* .*.swp
Lastly, globbing ignores directories, because we can't diff them. Or at least,
omnidiff doesn't know how to diff a directory. This automatically excludes some
things we don't need, such as RCS/
, CVS/
, .svn/
, and .git/
.
Defining filters
Any line starting with the word filter
defines a filter pattern to use for
the most recently defined file
. A filter pattern is typically used to
obscure sensitive data in the diff output; since it travels by email, we don't
want to include passwords, for example.
Filters can use any valid Perl regex syntax. See perlre(1) and perlreref(1) for more information.
file /etc/shadow
filter s/^([^:]+):[^:]+:/$1:******:/gm
The above example will watch the shadow file, but filter out the encrypted password before sending the email.
Note that you should use the /gm
modifier on most filters. Omnidiff reads
entire diff files into a string value, so you need /m
to work correctly in
that context. For the same reason /g
is needed; otherwise only the first
match is changed! I have not enforced /gm
though, because it's possible
there are edge cases where you'd want the other behavior.
Testing filters
You may find omnidiff-filter-test
to be helpful in writing filters. Run it
without arguments for help on using it.
Testing a filter is always a good idea. Otherwise, there's no way to really know if your filter code works.
Cached files
Omnidiff uses a cache directory as a holding pen for working files. For each file Omnidiff watches, there will be three files in the cache directory.
- A copy of the current version of the file
- A copy of the file as it appeared before the most recent change
- A diff of the changes between the above two files
(Files that have been configured in Omnidiff, but which have not yet been changed, will have only the first file.)
Generally these files are only there for Omnidiff to use. But from time to time, it is handy to have the files available for review.
By default, Omnidiff uses /var/cache/omnidiff
for this purpose, but you can
customize the path by setting cache_dir
in the config file.
For files with a filter defined, Omnidiff only applies the filter to the email it sends. The cached diff file contains the raw content of the diff. So in cases where a diff email comes through and the filter obscures information that you need to see, you can go to the diff file to review it. However, only one diff is kept; if another change is detected in a subsequent run, the previous diff is lost.
Running via cron
Most likely you will want to run Omnidiff via cron so it can watch files for you. Assuming you are using the default config file path, all you need to do is call omnidiff.
*/5 * * * * /usr/bin/omnidiff
It could be you want mutiple config files to watch things at different time intervals. That's easy too.
*/5 * * * * /usr/bin/omnidiff /etc/omnidiff-critical.conf
0 * * * * /usr/bin/omnidiff /etc/omnidiff-hourly.conf
0 0 * * * /usr/bin/omnidiff /etc/omnidiff-daily.conf
Running as an unprivileged user
The examples above tend to assume you are a sysadmin running this script as root, but you can just as easily run all of this out of your home directory on a shared web host or similar.
cd && git clone https://github.com/tangledhelix/omnidiff.git
Edit $HOME/omnidiff/etc/omnidiff
to have...
cache_dir /home/jdoe/omnidiff/cache
email_from me@mydomain.com
email_to me@mydomain.com
Run in your personal crontab:
*/5 * * * * /home/jdoe/omnidiff/bin/omnidiff /home/jdoe/omnidiff/etc/omnidiff.conf