Monitoring
Log Entries with Logbot
Robert Hayes
Keeping systems secure requires not only copious logging, but
also a regular review of those logs. The more frequently you review
them, the better, and the best situation is real-time alerting based
on log criteria that you define. This technology has been around
for some time through log-tailing and alerting programs (such as
Swatch) and, more recently, through syslog-ng.
Using Swatch to monitor your logs and send a page or email when
critical events occur is nothing new. But, what about monitoring
more mundane events? You may want to see when telecommuters are
using your VPN, or when your spam filter is rejecting email, or
even when someone hits your Web site using a non-standard browser.
Getting paged every time one of these events occurred would quickly
become tiresome, and receiving emails would clog your inbox. As
sys admins, we all have the ability to tail log files and grep
for certain strings, but having a simple cross-platform interface
to view log entries as they occur can help keep you and the users
you support aware of what's happening on your servers.
Logbot is a simple Perl script designed to take output from log-monitoring
software and send it to a conference room on a Jabber server. Because
myriad Jabber clients are available across most major platforms,
Logbot allows your Windows, Mac, and Unix users to view relevant
log entries as they occur. Logbot is perfect for monitoring medium-
to high-volume log entries that would otherwise incur a heavy load
if sent individually as pages or emails. If you're not logging
chat room dialogue, Logbot output is completely ephemeral: you can
run it constantly without worrying about using up valuable drive
space.
The Jabberd Server
Logbot has been written for and tested against the jabberd server
for *nix systems, although it should work with any Jabber server
that supports Multi-User Conferencing (MUC), the protocol that adds
"chat rooms" to your Jabber server. The jabberd project
lives at:
http://jabberd.jabberstudio.org
There you will find a wealth of documentation, the source code itself,
and links to jabberd mailing lists. I will not attempt to cover the
installation and configuration of a jabberd server. Doing so would
consume the entire article, and excellent documentation already exists
on the jabberd Web site. At the time of this writing, the latest stable
version of jabberd that supported multi-user conferencing (muc) was
jabberd 1.4.2 and mu-conference 0.5.2.
Multi-user conferencing does not exist natively within the jabberd
server, rather, it relies on a separate piece of software called
mu-conference, found at:
http://mu-conference.jabberstudio.org
This software is meant to supersede previous group chat protocols,
while simultaneously providing backward compatibility with those protocols.
Because Jabber is a relatively new protocol, it is under constant
development and improvement, and there have been multiple iterations
of this group chat concept.
Conference rooms can easily be created using a Jabber client that
supports the MUC protocol. But, because the name of the chat room
will be hard-coded into the Logbot script, be sure you create persistent
rooms that will not be destroyed if you need to restart the jabberd
server.
The mu-conference software comes with a set of Perl scripts that
will walk you through room creation and create a .xml configuration
file for your conference room. Because you'll be sending syslog
output to this room, you'll probably want to control who has
access to it. If you create the conference room using the mu-conference
scripts, you can make it a "members only" room and specify
which JIDs (Jabber IDs) are allowed to access the room. Adding or
removing users later is as simple as editing the .xml config file.
You'll probably also want to make the room "private".
A private room is simply a room that is not "public" and
will not be displayed in the Jabber browser unless searched for
by a user who is already logged into the room.
If you don't want your conference room service available
to other servers or the Internet at large (a good idea for a secure
server), be sure the conference host is set to conference.localhost
rather than to a fully qualified domain name. Also, because good
security involves good logging, you may want to log room activity.
However, if you're watching particularly voluminous logs, there's
no point in filling up your hard drives with redundant log entries.
For more information on the mu-conference protocol itself, see:
http://www.jabber.org/jeps/jep-0045.html
Once your jabberd server is up and running with mu-conference support,
be sure that Logbot has a JID on your server. The easiest way to do
this is by allowing registration on the server and creating the JID
with a Jabber client. Create a new user named "Logbot" (or
something more creative) with an appropriate password. Once that's
done, be sure that the Logbot user can log into the server and into
the conference room through a Jabber client, before you try it with
the script. Once you can log in and chat using a Jabber client, edit
the script and try it from the command line. There should be enough
debugging output to point you in the right direction if problems arise.
The logbot.pl Script
The Logbot script is written in Perl and makes heavy use of the
Net::Jabber and related modules, which are all available from cpan.org
(see the resources section). It also makes use of some of the example
code distributed with this module. Hooray for open source!
Net::Jabber requires XML::Stream, and if you want to use SSL connections,
be sure you have IO::Socket::SSL and Net::SSLeay. These can be painlessly
installed by running perl -MCPAN -e shell from a root prompt.
Using SSL is optional but recommended. Arguably, it makes little
difference in the overall security of your site, since system log
messages will be flying around your network in UDP plain text if
you are running a centralized syslog-ng server. But, upcoming versions
of syslog-ng will include encryption functions, and keeping plain
text off the wire is always a good idea.
Syslog-ng runs as root by default, so when it calls the logbot.pl
script, it will run as root. It will also continue running, reading
input from STDIN until syslog-ng is stopped or restarted. Syslog-ng
can be chrooted and run as a non-privileged user, but configuring
this is left as an exercise for the reader. Instead of overhauling
my syslog-ng implementation, I dropped the effective permissions
in the script as soon as possible. In this way, although the script
is called by root, it runs with the effective permissions of the
user "nobody". Check your /etc/passwd and /etc/group files
for a non-privileged account name. My "nobody" user has
a UID and GID of 99; your mileage may vary. (More information on
syslog-ng is included later.)
Overall, the script is pretty simple. It does not define any Jabber
callbacks, and as such, will not respond to messages or presence
information sent to it; all it does is take input and send it to
a conference room.
All variables are defined up front and must be edited for your
server configuration. The script is written for use with syslog-ng
or the traditional syslog facility combined with Swatch; comment
or uncomment the Swatch and syslog sections appropriately.
If you do not want to run mu-conference on your jabberd server,
but do want log alerts to be sent to a single recipient (such as
yourself), you can remove the MUCJoin section and replace:
$Connection->MessageSend(to=>"$room\@$mucserver",
with:
$Connection->MessageSend(to=>"$recipient\@$server",
As mentioned previously, the script is started by the syslog-ng user
when used with syslog-ng, and it stays open reading input from STDIN
while connected to the server. When launched by the Swatch user, the
script is called with the matching log entry passed as a command-line
argument, @ARGV. In this case, the script runs and the Logbot user
connects to the server and passes the matching log entry, then quickly
disconnects and exits. The next matching log entry will fire it up
again. If you're using this implementation, you'll notice
that it makes a bit of noise in the chat room every time the Logbot
user connects and disconnects. This is one good reason to upgrade
to syslog-ng.
Using Logbot with Syslog and Swatch
Logbot relies on a separate mechanism to monitor log files, watch
for specific content, and take appropriate action. Swatch (short
for simple watcher) does exactly this. It has been around for ten
years -- long enough to be in every admin's toolbox --
and is invaluable when it comes to keeping an eye on your systems.
Swatch is freely available and has a broad user base. The Swatch
project home page is now:
http://swatch.sourceforge.net
There you can find the most recent source code. It installs like other
Perl software with a simple:
perl Makefile.PL
make
make test
make install
make realclean
It relies on four external Perl modules, which are all available from
cpan.org.
Date::Calc
Date::Parse
File::Tail
Time::HiRes
Swatch relies on a .swatchrc configuration file and, by default, looks
for it in the home directory of the user running Swatch. Any user
can run Swatch, provided that the user has read access to the log
files being tailed. To avoid running Swatch as root, create a dedicated
"loggers" group with a low-privileged user as its member
and give read-only access to the loggers group on the log files you
want to monitor.
Swatch matches specific content using regular expressions in the
.swatchrc file; when a log entry matches your regular expression,
a specific action is taken. The action can be one of the following:
echo the matched text to a terminal, send an email, send a page,
or execute an arbitrary command. When used with the "exec"
action, logbot.pl can take the matched text as an argument array
and send it to the Jabber conference room.
A simple sample .swatchrc file that watches for the string "authentication
failure" and sends the corresponding log entry to Logbot would
look like this:
# Sample .swatchrc file
watchfor /authentication failure/
exec="/usr/bin/perl /path/to/logbot.pl $*"
The $* tells Swatch to take the entire log entry (the whole line)
and send it to the Logbot script. A $4 would send only the fourth
word in the log entry, a $1 the first word, etc.
Swatch has some other special options that may make its use preferable
over syslog-ng (discussed later). Two of the most notable are the
"throttle" and "when" options. The throttle
option takes a time unit (hours:minutes:seconds) as an argument,
and will make sure that the defined action does not execute more
than once during that time period. For example, a throttle option
of 01:00 will ensure that multiple instances of the log entry will
not be acted on if they occur within a minute of the first instance.
If you're monitoring something with a lot of activity (e.g.,
Web server of firewall logs), consider using the throttle option
to lighten the load on your syslog server, network, and Jabber server.
The "when" option will specify when a certain action
should be executed, and when it shouldn't; the argument is
passed as day_of_week:hour_of_day. The "when" option could
be helpful if, for example, you're monitoring logs in a 24x7
NOC environment, where you want to see only when your VPN is in
use outside of regular working hours, or where you want to watch
Web server logs during a specific maintenance window. See the Swatch
man page for other options and important information on the care
and feeding of Swatch.
Using Logbot with Syslog-ng
There is no doubt that Swatch is a valuable tool for admins who
want real-time alerts on log activity. But because it is separate
from the syslog facility itself, there is slight additional overhead
incurred in maintaining it. Syslog-ng is the "new generation"
of syslog and has an impressive list of powerful new features, including
built-in message filtering. Syslog-ng makes it a snap to set up
a centralized logging server with forwarded messages from other
servers easily split into different destination files, or even databases,
based on their source or content. Running logbot.pl on a centralized
log server allows you to watch for suspicious activity on all of
your servers at once, without having to configure Swatch, Logbot,
or syslog-ng on each separate machine. Plus, it will allow you to
harden your jabberd server even further by only allowing connections
from fewer IP addresses.
Syslog-ng is maintained by Bazsi Scheidler and can be obtained
at:
http://www.balabit.hu/en/downloads/syslog-ng
There is an excellent FAQ at:
http://www.campin.net/syslog-ng/faq.html
and an active mailing list. Because syslog-ng is still under active
development, subscribing to the mailing list is recommended for bug-fix
information and announcements. See the resources section for more
syslog-ng links.
The software is available for download as a source tarball, or
as a pre-compiled binary for Debian Linux users. The syslog-ng.deb
package replaces the traditional syslog package on Debian and comes
with its own syslog-ng.conf file tailored for Debian and ready for
use. If you're installing from source, don't forget to
grab libol, a required library used by syslog-ng.
The heart of syslog-ng is its configuration file, by default /etc/syslog-ng/syslog-ng.conf.
Configuring a syslog-ng.conf file from scratch can be daunting,
and the flexibility of this package makes for a complex configuration
file. But fear not -- example configuration files are distributed
with the source code, and once you get the hang of the syntax, expanding
on these files and seasoning them to suit your site requirements
is easy.
As mentioned earlier, the logbot.pl script relies on an external
mechanism to filter your logs and pass the output to Logbot's
STDIN. This is another place where the content-filtering in syslog-ng
shines. Syslog-ng allows you to define different sources for log
entries like unix socket on the host, entries from remote hosts
via UDP or TCP, a named pipe, or even a flat text file. You can
also define specific destinations for the logs entries, such as
a text file, an arbitrary UDP or TCP port on another host (e.g.,
another logging host), a named pipe, unix socket, or an external
program, which is where Logbot fits in.
A snippet of syslog-ng.conf might look like this:
source s_sys { unix-dgram ("/dev/log"); internal(); };
destination d_jabber { program( "/usr/bin/perl /path/to/logbot.pl" ); };
filter f_jabber { match( "authentication failure" ); };
log { source(s_net); filter(f_jabber); destination(d_jabber); };
Note that these lines are simply what would be required for sending
log output to the Logbot script; they do not represent a fully configured,
or even fully functional, syslog-ng.conf file.
The source line specifies that the regular /dev/log unix socket
be used as the source, as well as any messages internal to the syslog-ng
program itself. The destination line specifies the logbot.pl script
as the log entry destination. The log directive puts all of the
pieces together, telling syslog-ng that any log entry coming from
the /dev/log socket containing the words "authentication failure"
should be sent to the logbot.pl script. You can specify sources
and destinations all day. However, until they are combined with
a log statement, the log entries will not go anywhere unless they
are handled by different log and destination directives.
One of the things that makes Logbot possible is the ability to
specify multiple destinations and log directives for a single log
entry. For example, I use the following source and destination directives
on my centralized log server:
source s_net { udp(); };
destination d_net { file("/var/log/syslog-ng/$HOST/$PROGRAM"); };
log { source(s_net); destination(d_net); }; # This is the last line of the file
This serves as a catchall bucket that allows other admins in my office
to configure their hosts to log to our central server merely by pointing
the host at the log server's IP address. With some network hardware,
this is the only variable you can define. Once that host is configured,
the syslog-ng server will automatically create the directory and corresponding
log file, based on the hostname and name of the program that is creating
the logs. Having the Jabber log directive listed above this catchall
allows me to watch for important log entries by delivering them to
the Logbot script, while still delivering them to their "regular"
destination.
Conclusion
With IM servers finding a niche in corporate and enterprise environments,
chat clients are becoming a standard part of every user's workspace.
Multi-user conferencing in chat rooms allows administrators in far-flung
global enterprises to exchange information on systems and networks
quickly and easily. See Figure 1. Selectively forwarding log events
to an intuitive interface that runs across many platforms provides
the benefit of allowing multiple users -- whether they are administrators,
help-desk staff, or executive-level managers -- to see what's
happening on your servers in real-time, without giving out shell
access, file read permissions, or configuring extra ssh clients.
When monitoring non-critical, frequently occurring log events means
receiving equally frequent email or pager alerts, using Logbot allows
a chatty server to forward these log entries without causing your
pager to vibrate itself to pieces or your inbox to reach critical
mass.
Resources
Jabberd server -- http://jabberd.jabberstudio.org
MU-Conference -- http://mu-conference.jabberstudio.org
MUC protocol -- http://www.jabber.org/jeps/jep-0045.html
Net::Jabber module -- http://search.cpan.org/~reatmon/Net-Jabber-1.29
Syslog-ng home page -- http://www.balabit.hu/en/downloads/syslog-ng
Syslog-ng FAQ -- http://www.campin.net/syslog-ng/faq.html
Sample chapter from "Building Secure Servers with Linux"
-- http://www.oreilly.com/catalog/bssrvrlnx/chapter/ch10.pdf
Syslog-ng mailing list -- https://lists.balabit.hu/mailman/listinfo/syslog-ng
Robert Hayes is an RHCE and has a Bachelor's of Science
in Zoology from the University of Texas at Austin. He lives in Austin
and works as a Security Technical Analyst for the state of Texas.
He can be reached at: robert.hayes@mrhaha.net.
|