Linux Server Security (2nd Edition( [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Linux Server Security (2nd Edition( [Electronic resources] - نسخه متنی

Michael D. Bauer

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید







12.2. Syslog-ng


As useful and ubiquitous as syslog is, it's
beginning to show its age. Modern Unix and Unix-like systems are
considerably more complex than they were when syslog was invented,
and they have outgrown both syslog's limited
facilities and its primitive network-forwarding functionality.

Syslog-ng ("syslog new generation")
is an attempt to increase syslog's flexibility by
adding better message filtering, better forwarding, and eventually
(though not quite yet), message integrity and encryption. In
addition, Syslog-ng supports remote logging over both the TCP and UDP
protocols. Syslog-ng is the brainchild of and is primarily developed
and maintained by Balazs
("Bazsi") Scheidler.

Although its' much newer than syslogd, Syslog-ng is
both stable and mature and has already been incorporated into major
Linux distributions, including SUSE and Debian. A couple of its
advanced security features are still works in progress, but Syslog-ng
can be used in conjunction with TCP
"tunneling" tools such as
stunnel and ssh to
authenticate or encrypt log messages sent to remote hosts.


12.2.1. Installing Syslog-ng from Binary Packages


As I just mentioned,
Syslog-ng is already a
standard package in the Debian and SUSE distributions as a drop-in
replacement for syslogd. Debian's deb package is
called syslog-ng, as is SUSE's
RPM package. If you run Red Hat or Fedora, a simple Google search for
"syslog-ng rpm" will turn up at
least a couple of different sources of Syslog-ng RPMs for your
distribution.

One of these will probably be Seth Vidal's page at
http://www.dulug.duke.edu/~skvidal/RPMS/. The
subdirectories fc1/ and
fc2/ contain binary RPMs for Fedora.
You'll need both the syslog-ng
and libol packages.

Of these three distributions (Debian, SUSE, and Fedora), only in
Debian does Syslog-ng seamlessly replace
syslogd. For SUSE and Fedora,
you'll have a little bit of setup to do before you
can go much further.


12.2.1.1 Replacing syslogd with Syslog-ng on SUSE


Once you've installed the RPM
syslog-ng, you need to follow these steps (as
root, naturally):

Enter the command SuSEconfig --module syslog-ng.

Stop syslogd with the command rcsyslog
stop
.

Open /etc/sysconfig/syslog with the text editor
of your choice, and change the value of the
SYSLOG_DAEMON variable to
syslog-ng.

Start Syslog-ng with the command rcsyslog start.

As you can see, both syslogd and Syslog-ng are
started by the same init script. Therefore, do
not make the change to
/etc/sysconfig/syslog (in Step three) before
stopping the syslog service, otherwise you may end up with both
syslogd and Syslog-ng running, with
unpredictable results.

12.2.1.2 Replacing syslogd with Syslog-ng on Fedora (Vidal's RPMs)


Unlike with SUSE, in
Fedora
syslogd and Syslog-ng (as packaged by Seth
Vidal) each have their own startup script. When you install the
libol and syslog-ng RPMs,
the post-installation script will automatically start Syslog-ng and
enable its startup script, but will leave
syslogd both running and enabled.

Follow these steps to gracefully replace syslogd
with Syslog-ng:

Stop syslogd with the command
/etc/init.d/syslog stop.

Restart Syslog-ng with the command /etc/init.d/syslog-ng
restart
.

Disable syslogd with the command
chkconfig --del syslog.

You are now ready to configure Syslog-ng! You can skip ahead to Section 12.2.3.


12.2.2. Compiling and Installing Syslog-ng from Source Code


If you can't find Syslog-ng
binaries for your Linux distribution, or simply want the very latest
version, you'll need to compile Syslog-ng from
source code. This is no big deal at all.

First, you need to obtain the latest Syslog-ng source code. As of
this writing, the most current major version of Syslog-ng is 1.6. For
a few years, development was branched into 1.4, the
"stable" branch, and 1.5,
"experimental"; 1.6 represents the
maturation of 1.5. Note that Debian 3.0 still ships with 1.4.

Version 1.5 is the experimental branch, and although
it's officially disclaimed as unstable, some people
use it on production systems due to its new field expansion
feature, which allows you to write
messages in your own custom formats. If you decide this functionality
is worth the risk of running experimental code, be sure to subscribe
to the Syslog-ng mailing list (see
http://lists.balabit.hu/mailman/listinfo/syslog-ng
to subscribe).

Speaking of which, it probably behooves you to browse the archives of
this mailing list periodically even if you stick to the stable branch
of Syslog-ng. Bazsi Scheidler tends to prioritize bug fixes over
documentation, so Syslog-ng documentation tends to be incomplete and
even out of date.

But Bazsi not only maintains the mailing list, he also very actively
participates in it, as do other very knowledgeable and helpful
Syslog-ng users and contributors. Thus the mailing list is an
excellent source of Syslog-ng assistance. Before posting a question,
you may wish to see if anyone else has asked it first. See the
Syslog-ng mailing list archives at http://lists.balabit.hu/pipermail/syslog-ng/.

Syslog-ng
can be downloaded from Bazsi Scheidler's web site at
http://www.balabit.com/downloads/syslog-ng/.
In addition to Syslog-ng itself, you'll need the
source code for
libol,
Syslog-ng's support library; this is available at
http://www.balabit.com/downloads/libol/.

Unzip and untar both archives. Compile and install
libol first, then Syslog-ng. For both packages,
the procedure is the same:

Change the working directory to the source's root:

cd packagename Run the source's configure script:

./configure Build the package:

./make Install the package:

./make install This will install everything in the default locations, which for both
libol and Sylog-ng are subdirectories of
/usr/local (e.g.,
/usr/local/lib,
/usr/local/sbin, etc.). If you wish to install
either package somewhere elsee.g., your home directory (which
is not a bad place to test new software)then in Step 2, pass
that directory to configure with the
--prefix= flag as in Example 12-11.

Example 12-11. Telling configure where to install the package


mylinuxbox:/usr/src/libol-0.2.23# ./configure --prefix=/your/dir/here After both libol and Syslog-ng have been
compiled and installed, you need to set up a few things in
Syslog-ng's operating environment. First, create the
directory /etc/syslog-ng. Next, copy one or more
of the example syslog-ng.conf files into this
directory from the source distribution's
contrib/ and doc/
directories (unless you intend to create your
syslog-ng.conf completely from scratch).

Finally, you need to create a startup script for
syslog-ng in /etc/init.d,
and symbolic links to it in the appropriate runlevel directories (for
most Linux distributions, /etc/ rc2.d,
/etc/rc3.d, and /etc/rc5.d). Sample
syslog-ng init scripts for several Linux
distributions are provided in the Syslog-ng source
distribution's contrib/
directory. If you don't find one there that works
for you, it's a simple matter to make a copy of your
old syslog or sysklogd init
script and hack it to start syslog-ng rather
than syslogd.

12.2.3. Setting Syslog-ng's Startup Parameters


Syslog-ng reads most of its
configuration information from its
syslog-ng.conf file, which normally resides in
/etc/syslog-ng. However, a number of crucial
behaviors must be passed to the syslog-ng
command as arguments (flags). Flags supported by the
syslog-ng daemon, Versions 1.6 and higher, are
listed in Table 12-6.

Table 12-6. syslog-ng startup flags

Flag

Description

-d

Print debugging messages.


-v

Print even more debugging messages.


-f filename

Use filename as the configuration file
(default=/etc/syslog-ng/syslog-ng.conf).


-V

Print version number.


-p pidfilename

Name process-ID-file pidfilename
(default=/var/run/syslog-ng.pid).


-C /chroot/path

After reading configuration file, chroot to the path
/chroot/path.


-u username

After initialization, drop root privileges and run as unprivileged
user username.


-g groupname

After initialization, change group from root to
unprivileged group
groupname.

Most of these are self-explanatory, but the last three are of special
note. -C allows you to specify a chroot jail for
Syslog-ng to run in. -u and -g
allow you to specify a nonprivileged user account and group,
respectively, for Syslog-ng to run as.

These three flags go together: if you chroot Syslog-ng but allow it
to run as root (which it does by default), an
attacker will have a much easier time breaking out of the chroot
jail.

12.2.3.1 Building a chroot jail for Syslog-ng


To set up a nonprivileged account, a nonprivileged
group, and a chroot jail for Syslog-ng, follow this procedure:

su to root if
you're not root already.

Create an unprivileged group account for Syslog-ng, e.g., by adding
the following line to /etc/group:

syslogng:x:77:

Create an unprivileged system account for Syslog-ng, e.g., via the
following command:

bash-# useradd -d /var/logjail -g syslogng -r syslogng (Note that in Linux, the -r flag tells
useradd that this will be a system account,
causing useradd to automatically set the
account's shell to /bin/false
and to choose an appropriately low value for its UID.) Create the jail:

bash-# mkdir -p /var/logjail/var/log
bash-# mkdir -p /var/logjail/etc/syslog-ng
bash-# mkdir /var/logjail/dev
bash-# mkdir /var/logjail/lib (Our actual changed root will be /var/logjail,
but it needs to contain some subdirectories.) Move syslog-ng.conf into the jail, and turn its
old location into a symbolic link:

bash-# cd /etc/syslog-ng
bash-# mv ./syslog-ng.conf /var/logjail/etc/syslog-ng
bash-# ln -s /var/logjail/etc/syslog-ng/syslog-ng.conf syslog-ng.conf Create jailed /dev/xconsole and
/dev/tty10 devices:

bash-# cd /var/logjail/dev
bash-# mknod -m 0660 xconsole p
bash-# mknod -m 0660 tty10 c 4 10
bash-# chgrp syslogng ./xconsole ./tty10 Copy some things:

bash-# cp /etc/localtime /var/logjail/etc
bash-# cp /etc/nsswitch.conf /var/logjail/etc
bash-# cp /etc/resolv.conf /var/logjail/etc
bash-# grep syslogng /etc/passwd > /var/logjail/etc/passwd
bash-# grep syslogng /etc/group > /var/logjail/etc/group
bash-# cp /lib/libnss.so.2 /var/logjail/lib At this point, the whole jail should be owned by the user
root and the group root,
which is cool so long as the chroot directory itself
(/var/logjail/) is
"other-executable," e.g.,
drwxr-xr-x. But Syslog-ng must be able to
create/write files in the jail's
var/log/ subdirectory, so we need to tweak the
latter's group ownership and group permissions, like
so:

bash-# chgrp syslogng /var/logjail/var/log
bash-# chmod g+wx /var/logjail/var/log That's it! We may now start Syslog-ng with the flags
-C /var/logjail -u syslogng -g syslogng.

The master syslog-ng process will still read its
config from /etc/syslog-ng/syslog-ng.conf (not
/var/logjail/etc/...), but immediately after
that, it will chroot itself to the specified jail.

Note, however, that the paths you specify in
syslog-ng.conf file( )
statements should all be relative to the changed root. In other
words, use file("/var/log/messages"), not
file("/var/logjail/var/log/messages"). Any path
you specify in syslog-ng.conf will, in practical
terms, end up with /var/logjail automatically
affixed to the beginning of it.

12.2.3.2 Where to specify Syslog-ng's startup parameters


If your Syslog-ng startup script is
"self-contained" as in Debian, you
should set Syslog-ng's startup parameters (flags)
directly within the script. If you're using Seth
Vidal's Syslog-ng RPMs for Fedora, edit the file
/etc/sysconfig/sylog-ng and define the startup
parameters with SYSLOGNG_OPTIONS. If
you're running SUSE, specify the startup flags by
editing the file /etc/sysconfig/syslog and
setting the value of the variable
SYSLOG_NG_PARAMS.

12.2.4. Configuring Syslog-ng


There's quite a bit more involved in configuring
Syslog-ng
than with syslog, but that's an outcome of its
flexibility. Once you understand how
syslog-ng.conf works, writing your own
configurations is simple, and adapting sample configurations for your
own purposes is even simpler. Its main drawback is its haphazard
documentation; hopefully, what follows here will mitigate that
drawback for you.

By default, Syslog-ng's configuration file is named
syslog-ng.conf
and resides in /etc/ syslog-ng/.
Let's dissect a simple example of one in Example 12-12.

Example 12-12. A simple syslog-ng.conf file


# Simple syslog-ng.conf file.
options {
use_fqdn(no);
sync(0);
};
source s_sys { unix-stream("/dev/log"); internal( ); };
source s_net { udp( ); };
destination d_security { file("/var/log/security"); };
destination d_messages { file("/var/log/messages"); };
destination d_console { usertty("root"); };
filter f_authpriv { facility(auth, authpriv); };
filter f_messages { level(info .. emerg)
and not facility(auth, authpriv); };
filter f_emergency { level(emerg); };
log { source(s_sys); filter(f_authpriv); destination(d_security); };
log { source(s_sys); filter(f_messages); destination(d_messages); };
log { source(s_sys); filter(f_emergency); destination(d_console); };

As you can see, a syslog-ng.conf file consists
of options{}, source{},
destination{}, filter{}, and
log{} statements. Each statement may contain
additional settings, usually delimited by semicolons.

Syntactically, syslog-ng.conf is very similar to
C and other structured programming languages. Statements are
terminated by semicolons; whitespace is ignored and may therefore be
used to enhance readability (e.g., by breaking up and indenting
lengthy statements across several lines).

After defining global options, message sources, message destinations,
and message filters, combine them to create logging rules.


Some of the options and features I'm about to
describe are specific to Syslog-ng Versions 1.5, 1.6 and later. If a
given feature doesn't work on your distribution,
check the version of your Syslog-ng package.

12.2.4.1 Global options


Global options are set in syslog-ng.conf's
options{} section. Some options may be used in the
options{} section and in one or more other
sections. Predictably, options set within
source{}, destination{},
filter{}, and log{} sections
overrule those set in options{}. Table 12-7 lists some of the most useful of
Syslog-ng's options.

Table 12-7. Syslog-ng options


Option

Description

chain_hostnames( yes | no
)

After printing the hostname provided by TCP or UDP
message's sender, show names of all hosts by which
the message has been handled (default=yes).


keep_hostname( yes | no
)

Trust hostname provided by TCP or UDP message`s
sender (default=no).


use_fqdn( yes | no )

Record full name of TCP or UDP message sender
(default=no).


use_dns( yes | no )

Resolve IP address of TCP or UDP message sender
(default=yes).


use_time_recvd( yes | no
)

Set message`s timestamp equal to time message was
received, not time contained in message
(default=no).


time_reopen( NUMBER
)

Number of seconds after a TCP connection dies before reconnecting
(default=60).


time_reap( NUMBER
)

Number of seconds to wait before closing an inactive file (i.e., an
open logfile to which no messages have been written for the specified
length of time) (default=60).


log_fifo_size(
NUMBER
)[1]

Number of messages to queue in memory before processing if
syslog-ng is busy; note that when queue is full,
new messages will be dropped, but the larger the fifo size, the
greater syslog-ng's RAM
footprint (default=100).


sync( NUMBER
)Footnote 2

Number of lines (messages) written to a logfile before file is
synchronized (default=0).


owner(
string )Footnote 2

Owner of logfiles syslog-ng creates
(default=root).


group( string
)Footnote 2

Group for logfiles syslog-ng creates
(default=root).


perm( NUMBER
)Footnote 2

File permissions for logfiles syslog-ng creates
(default=0600).


create_dirs( yes | no
)
Footnote 2

Whether to create directories specified in destination file paths if
they don't exist (default=no).


dir_owner( string
)Footnote 2

Owner of directories syslog-ng creates
(default=root).


dir_group( string
)Footnote 2

Group for directories syslog-ng creates
(default=root).


dir_perm( NUMBER
)Footnote 2

Directory permissions for directories syslog-ng
creates (default=0700).

[1] These options may also be used in
file( ) declarations within
destination{} statements.


[2] [2] These options may also be used in file()
declarations within destination{} statements.


Options that deal with hostnames and their resolution
(chain_hostnames( ), keep_ hostname(), use_fqdn( ), and
use_dns) deal specifically with the hostnames of
remote log clients and not with hostnames or IP addresses referenced
in the body of the message.

In other words, if syslog-ng.conf on a central
log server contains this statement:

options { use_dns(yes); };

and the remote host joe-bob, whose IP address is
10.9.8.7, sends this message:

Sep 13 19:56:56 s_sys@10.9.8.7 sshd[13037]: Accepted publickey for ROOT from
10.9.8.254 port 1355 ssh2 then the log server will log:

Sep 13 19:56:56 s_sys@joebob sshd[13037]: Accepted publickey for ROOT from
10.9.8.254 port 1355 ssh2 As you can see, 10.9.8.7 was resolved to joebob,
but 10.9.8.254 wasn't looked up. (For now, you can
disregard the s_sys@ in front of the hostname;
I'll explain that shortly.) The
use_dns(yes) statement applies only to the
hostname at the beginning of the message indicating which host sent
it; it doesn't apply to other IP addresses that may
occur later in the message.

Note also that options related to files and directories may be
specified both in the global options{}
statement and as modifiers to file( )
definitions within destination{} statements.
file( ) options, when different from their global
counterparts, override them. This allows you to create a
"rule of thumb" with specific
exceptions.

The chain_hostname( ) and keep_hostname() options are also worth mentioning. By default,
keep_hostname( ) is set to no,
meaning that syslog-ng will not take the
hostname supplied by a remote log server at face value;
syslog-ng will instead resolve the source IPs of
packets from that host to determine for itself what that
host's name is. This is in contrast to syslog, which
takes remote hosts' names at face value.

chain_hostname( ) determines whether
syslog-ng should list all hosts through which
each message has been relayed. By default, this option is set to
yes.

Example 12-13 illustrates the effects of
keep_hostname(no) and chain_hostname(yes)
(i.e., syslog-ng's
default behavior). It shows a log message (in this case, a
syslog-ng startup notification) being generated
locally and then relayed twice. host1, which
gives its hostname as "linux,"
generates the message and then sends it to
host2. host2 records both
"linux" and
"host1," having double-checked that
hostname itself via DNS. Finally, the message is relayed to
host3.


Example 12-13. A log message relayed from one host to two others


Original log entry on host1:
Sep 19 22:57:16 s_loc@linux syslog-ng[1656]: syslog-ng version
1.4.13 starting
Entry as sent to and recorded by host2:
Sep 19 22:57:16 s_loc@linux/host1 syslog-ng[1656]: syslog-ng version
1.4.13 starting
Same log entry as relayed from host2 to host3:
Sep 19 22:57:16 s_loc@linux/host1/host2 syslog-ng[1656]: syslog-ng version
1.4.13 starting There are several interesting things to note in this example. First,
you can see that in the second entry (the one logged by
host2), Syslog-ng does not clearly indicate that
"linux" is actually
host1it simply adds the
"real" hostname after the
"fake" one in the slash-delimited
hostname chain.

Second, the timestamp is identical in all three log entries.
It's unlikely that three hosts would be in sync to
the millisecond and be able to relay log
messages amongst themselves virtually instantaneously. In fact, the
timestamp given to the message by the originating host
(host1 here) is preserved on each host to which
the message is relayed, unless a host has its own
use_time_recd( ) option set to
yes (which causes syslog-ng
to replace message-provided timestamps with the time at which the
message was received locally).

Finally, Example 12-13 also shows that when
host1 created the message, this host (actually
its local syslog-ng process) appended
s_loc, to the message; this is the label of the
source{} on host1 from which
the local syslog-ng process received the
message. Example 12-14 lists
host1's
syslog-ng.conf file, the one responsible for the
first entry shown in Example 12-13.

Example 12-14. host1's syslog-ng.conf file


options { };
source s_loc { unix-stream("/dev/log"); internal( ); };
destination d_host2 { udp("host2" port(514)); };
destination d_local { file("/var/log/messages"); };
log { source(s_loc); source(s_net); destination(d_host2); destination(d_local); };

Which brings us to the next topic: Syslog-ng message sources.

12.2.4.2 Sources


The
syslog-ng.conf file listed in Example 12-14 contains one source{}
definition, which itself contains two source
drivers (message inputs).
syslog-ng.conf may contain many
source{} definitions, each of which may, in turn,
contain multiple drivers. In other words, the syntax of source
definitions is as follows:

source sourcelabel { driver1( [options] ); driver2( [options] ); etc. };

where sourcelabel is an arbitrary string
used to identify this group of inputs, and where
driver1( ), driver2(
)
, etc. are one or more source drivers that you wish to
treat as a single group.

Let's take a closer look at the source definition in
Example 12-14:

source s_loc { unix-stream("/dev/log"); internal( ); };

This line creates a source called s_loc that
refers to messages obtained from /dev/log (i.e.,
the local system-log socket) and from the local
syslog-ng process.

Syslog-ng is quite flexible in the variety of source drivers from
which it can accept messages. In addition to Unix sockets (e.g.,
/dev/log), syslog-ng
itself, and UDP streams from remote hosts, Syslog-ng can accept
messages from named pipes, TCP connections from remote hosts, and
special files (e.g., /proc files). Table 12-8 lists
Syslog-ng's supported
source drivers.

Table 12-8. Source drivers for Syslog-ng


Source

Description

internal( )

Messages from the syslog-ng daemon itself.


file("filename" [options])

Messages read from a special file such as
/proc/kmsg.


pipe("filename" )

Messages received from a named pipe.


unix_stream("filename" [options])

Messages received from Unix sockets that can be read from in the
connection-oriented stream modee.g.,
/dev/log under kernels prior to 2.4; the maximum
allowed number of concurrent stream connections may be specified
(default=100).


unix_dgram("filename" [options])

Messages received from Unix sockets that can be read from in the
connectionless datagram modee.g., klogd
messages from /dev/log under kernel 2.4.x.


tcp([ip(address)] [port(#)]
[max-connections(#)] [keep-alive(yes|no)] )

Messages received from remote hosts via the TCP protocol on the
specified TCP port (default=514) on the specified
local network interface (default=all); the maximum
number of concurrent TCP connections may be specified
(default=10), and keep-alive
can be set to yes to keep the socket open even
through SIGHUPs.


udp([ip(address)] [port(#)])

Messages received from remote hosts via the udp protocol on the
specified UDP port (default=514) on the specified
local network interface (default=all).

As we just saw in Example 12-14, internal() is syslog-ng itself:
syslog-ng sends itself startup messages, errors,
and other messages via this source. Therefore, you should include
internal( ) in at least one
source{} definition. file( ) is
used to specify special files from which
syslog-ng should retrieve messages. The special
file you'd most likely want
syslog-ng to read messages from is
/proc/kmsg.

Note, however, that file( ) is
not intended for use on regular text files. If
you wish syslog-ng to
"tail" dynamic logfiles written by
other applications (e.g., httpd),
you'll need to write a script that pipes the output
from a tail -f
[filename]
command to logger. (For
instructions on using logger, see the section
"Testing System Logging with
logger" later in this chapter.) unix_stream( ) and
unix_dgram( ) are important drivers:
these read messages from connection-oriented and connectionless Unix
sockets, respectively. Linux kernels Versions 2.4.1 and higher use
Unix datagram sockets: if you specify /dev/log
as a unix_stream( ) source, kernel messages
won't be captured. Therefore, use
unix_dgram( ) when defining your local-system log
source, e.g.:

source s_loc { unix-dgram("/dev/log"); internal( ); };

If your kernel is pre-2.4.0, you should instead use
unix_stream( ) for /dev/log.

tcp( ) and udp( ) read messages
from remote hosts via the connection-oriented TCP protocol and the
connectionless UDP protocol, respectively. In both tcp() and udp( ), a listening address and a
port number may be specified. By default,
syslog-ng listens on 0.0.0.0:514that is,
"all interfaces, port 514."
(Specifically, the default for tcp( ) is
0.0.0.0:TCP514, and for udp( ) is 0.0.0.0:UDP514.) Example 12-15 shows source statements for
tcp( ) and udp( ), with IP and
port options defined.

Example 12-15. tcp( ) and udp( ) sources


source s_tcpmessages { tcp( ip(192.168.190.190) port(10514) );
};
source s_udpmessages { udp( ); };

In Example 12-15, we're defining the
source s_tcpmessages as all messages received on
TCP port 10514, but only on the local network interface whose IP
address is 192. 168.190.190. The source
s_udpmessages, however, accepts all UDP messages
received on UDP port 514 on all local network interfaces.

Besides ip( ) and port( ),
there's one more source option I'd
like to cover. max_ connections( ), which can be
used only in tcp( ) and unix_stream(
)
sources, restricts the number of simultaneous connections
from a given source that syslog-ng will accept.
This is a trade-off between security and performance: if this number
is high, then few messages will be dropped when the server is under
load, but at the expense of resources. If this number is low, the
chance that logging activity will bog down the server is minimized,
but whenever the number of maximum connections is reached, messages
will be dropped until a connection is freed up.

The correct syntax for max-connections( ) is
simple: specify a positive integer between the parentheses. For
example, let's adapt the tcp( )
source from Example 12-15 to accept a maximum of 100
concurrent TCP connections from remote hosts:

source s_tcpmessages { tcp( ip(192.168.190.190) port(10514) max-connections(100) ); };

By default, max-connections( ) is set to 100 for
unix-stream( ) sources and 10 for tcp(
)
sources.

By the way, TCP port 514 is the default listening port not only for
syslog-ng, but also for
rshd. This isn't a big deal,
for the simple reason that rshd has no business
running on an ostensibly secure Internet-accessible system. If, for
example, you wish to use both syslog-ng and
rshd on an intranet server (even then I
recommend sshd instead), you should specify a
different (unused) port for syslog-ng to accept
TCP connections on.

12.2.4.3 Destinations


Syslog-ng can be configured to send
messages to the same places syslog can: ASCII files, named pipes,
remote hosts via UDP, and TTYs. In addition,
Syslog-ng can send messages to Unix
sockets, remote hosts via TCP, and to the standard inputs of
programs. Table 12-9 lists the allowed destination
types (called drivers) in Syslog-ng.

Table 12-9. Supported destination drivers in syslog-ng.conf


Driver

Description

file("filename[$MACROS]" )

Write messages to a standard ASCII-text logfile. If file
doesn't exist, syslog-ng will
create it. Macros may be used within or in lieu of a filename; these
allow dynamic naming of files (see Table 12-10).


tcp("address" [port(#);] )

Transmit messages via TCP to the specified TCP port
(default=514) on the specified IP address or
hostname. (You must specify an address or name.)

udp("address" [port(#);] )

Transmit messages via UDP to the specified UDP port
(default=514) on the specified IP address or
hostname. (You must specify an address or name.)

pipe("pipename")

Send messages to a named pipe such as
/dev/xconsole.


unix_stream("filename" [options])

Send messages in connection-oriented stream mode to a Unix socket
such as /dev/log.


unix_dgram("filename" [options])

Send messages in connectionless datagram mode to a Unix socket such
as /dev/log.


usertty( username )

Send messages to specified user's console.


program("/path/to/program")

Send messages to standard input of specified program with specified
options.

Each of these destination drivers supports various options, some of
the most important of which are indicated in Table 12-9. See the HTML-format documentation included
with Syslog-ng for complete lists and explanations of these options.
For now, let's focus on the file() destination driver.

As with ordinary syslog, file( ) is the most
important type of destination. Unlike syslog, Syslog-ng supports
filename-expansion macros, output templates, and a number of options
that give one much more granular control over how logfiles are
handled.

When you specify the name of a file for
syslog-ng to write messages to, you may use
macros to create all or part of the filename. For example, to tell
syslog-ng to write messages to a file whose name
includes the current day, you could define a destination like this:

destination d_dailylog { file("/var/log/messages.$WEEKDAY"); };

When Syslog-ng writes to this particular destination, it will use the
filename /var/log/ messages.Tues,
/var/log/messages.Wed, etc., depending on what
day it is.

But that's not all you can do with these macros: by
combining them in a template( ) declaration, you
can use them to create custom log-message templates! This is one of
the most important features introduced in Syslog-ng Versions 1.5 and
1.6.

For example, if you create a destination in
syslog-ng.conf like so:

destination d_file {
file("/var/log/$YEAR.$MONTH.$DAY/messages"
template("$FULLDATE $TZ $HOST [$LEVEL] $MSG\n")
template_escape(no)
);
};

then your log messages will be written to the file
messages in the directory
/var/log/2004.09.30/, and each message within
that file will look something like this:

2004 Aug 18 00:11:11 CDT host1 [info] kernel: klogd 1.4.1, log source = /proc/kmsg
started.

The template( ) option is now supported in
all Syslog-ng destination drivers, not just
file( ).

Table 12-10 shows a complete
list of supported
filename/template macros.

Table 12-10. Macros supported in file( ) destinations


Macro

Expands to

PROGRAM

The name of the program that sent the message. Avoid using this in
untrusted environments: the program name is highly variable and is
determined by the process sending the message to Syslog-ng.


HOST

The name of the host that originated the message.


FULLHOST

Same as HOST, but with fully qualified domain name.


FACILITY

The facility to which the message was logged.


PRIORITY or LEVEL (synonyms)

The designated priority level.


TAG

Facility plus priority, in the form of a two-digit hexadecimal
number. Numbers are shown in Tables Table 12-1 and
Table 12-2.


DATE

Date stringFootnote 2, e.g., Aug 18
ch12-FTNOTE-ID-85004
00:07:18
.


FULLDATE

Date stringFootnote 2 with year, e.g.,
2004 Aug 18 00:07:18.


ISODATE

ISO-formatted date stringFootnote 2, e.g.,
2004-08-18T00:07:18-0500.


YEAR

The current year.[3]

MONTH

The current month.Footnote 2

DAY

The current day.Footnote 2

WEEKDAY

The current day's name (Monday,
etc.).Footnote 2

HOUR

The current hour.Footnote 2

MIN

The current minute.Footnote 2

SEC

The current second.Footnote 2

TZOFFSET

Time zone expressed as difference from GMT, e.g.
-0600.


TZ

Time zone expressed as abbreviation, e.g.,
"CST."

MESSAGE

The actual body of the log message. In practice,
you'd never want this to be part of a filename; this
macro is intended for use with templates.

[3] If the global option
use_time_recvd( ) is set to
yes, this macro's value will be
taken from the local system time when the message was received;
otherwise, for messages from remote hosts, the timestamp contained in
the message will be used.


As with syslog, if a file specified in a file( )
destination doesn't exist,
syslog-ng will create it. Unlike syslog,
Syslog-ng has a number of options that can be implemented both
globally and on a per-logfile basis. (Global settings are overridden
by per-logfile settings, allowing you to create
"general rules" with exceptions.) For example, whether and how
syslog-ng
creates new directories for its logfiles is controlled via the
options create_dirs( ), dir_owner(), dir_group( ), and dir_perm(
)
. Example 12-16 illustrates the use of
these options within a destination{} statement.

Example 12-16. Controlling a file( ) destination's directory-creating behavior


destination d_mylog { file("/var/log/ng/image/library/english/10020_mylog" create_dirs(yes) dir_owner(root)
dir_group(root) dir_perm(0700)); };

Example 12-16 also happens to show the default values
of the dir_owner, dir_group( ),
and dir_perm( ) options.
While this may seem unrealistic (Why would anyone go to the trouble
of setting an option to its default?), it's
necessary if nondefaults are specified in a global
options{} statement and you want the default
values used for a specific fileremember, options set in a
destination{} statement override those set in an
options{} statement.

Other global/file-specific options can be used to set characteristics
of the logfile itself: owner( ), group(), and perm( ), which by default are set
to root, root, and
0600, respectively. In case
you're wondering, there is no create_file() optionsyslog-ng has the
irrevocable ability to create files (unless that
file's path includes a nonexistent directory and
create_dirs( ) is set to no).
Example 12-17 shows a destination definition that
includes these options.

Example 12-17. Options that affect file properties


destination d_micklog { file("/var/log/micklog" owner(mick) group(wheel) perm(0640));
};

The other file( ) option we'll
cover here is sync( ), which can be used to limit
the frequency with which logfiles are synchronized. This is analogous
to syslog's "-"
prefix, but much more granular: whereas the
"-" merely turns off
synchronization, file( ) accepts a numeric value
that delays synchronization to as many or as few messages as you
like.

The higher the value, the more messages that are cached prior to
filesystem synchronization and, therefore, the fewer
"open for read" actions that take
place on the filesystem. The lower the number, the lower the chances
of data loss and the lower the delay between a message being
processed and written to disk.

By default, sync( ) is set to zero, meaning
"synchronize after each message."
In general, the default or a low sync( ) value is
preferable for low-volume scenarios, but numbers in the 100s or even
1,000s may be necessary in high-volume situations. A good rule of
thumb is to set this value to the approximate number of log-message
lines per second your system must handle at peak loads.


If you use a log monitor such as
Swatch (described later in this chapter)
to be alerted of attacks in progress, don't set
sync( ) too high. If an intruder deletes a
logfile, all of Syslog-ng's cached messages will be
lost without having been parsed by the log monitor. (Log monitors
parse messages as they are written, not while they are cached.)

12.2.4.4 Filters


And now we come to some of the serious magic in
Syslog-ng: message filters. Filters,
while strictly optional, allow you to route messages based not only
on priority/level and facility (which syslog can do), but also on the
name of the program that sent the message, the name of the host that
forwarded it over the network, a regular expression evaluated against
the message itself, or even the name of another filter.

A filter{} statement consists of a label (the
filter's name) and one or more criteria connected by
operators (and, or, and
not are supported). Table 12-11
lists the different types of criteria that a
filter{} statement may contain.

Table 12-11. filter{} functions

Function (criterion)

Description

facility( facility-name )

Facility to which the message was logged (see Table 12-1 for facility names).


priority( priority-name )
priority( priority-name1,
priority-name2, etc. )
priority( priority-name1 ..
priority-name2 )

Priority assigned to the message (see Table 12-2
for priority-names); a list of priorities separated by commas may be
specified, or a range of priorities expressed as two priorities
(upper and lower limits) separated by two periods.


level( priority-name )

Same as priority( ).


program( program-name )

Program that created the message.


host( hostname )

Host from which message was received.


match( regular-expression )

Regular expression to evaluate against the message's
body.


filter( filter-name )

Other filter to evaluate.

Example 12-18 shows several
filter{} statements taken from the default
syslog-ng.conf file included in Debian
2.2's Syslog-ng package.

Example 12-18. Filters


filter f_mail { facility(mail); };
filter f_debug { not facility(auth, authpriv, news, mail); };
filter f_messages { level(info .. warn) and not facility(auth, authpriv,
cron, daemon, mail, news); };
filter f_cother { level(debug, info, notice, warn) or facility(daemon, mail); };

The first line in Example 12-18, filter
f_mail
, matches all messages logged to the
mail facility. The second filter,
f_debug, matches all messages not logged to the
auth, authpriv,
news, and mail facilities.

The third filter, f_messages, matches messages
of priority levels info through
warn, except those logged to the
auth, authpriv,
cron, daemon,
mail, and news facilities.
The last filter, called f_cother, matches all
messages of priority levels debug,
info, notice, and
warn, and also all messages logged to the
daemon and mail facilities.

When you create your own filters, be sure to test them using the
logger command. See the section entitled
"Testing System Logging with
logger" later in this chapter.

12.2.4.5 Log statements


Now we combine the elements we've just defined
(sources, filters, and destinations) into
log{} statements. Arguably, these are
the simplest statements in syslog-ng.conf: each
consists only of a semicolon-delimited list of source(), destination( ), and, optionally,
filter( ) references. (Filters are optional
because a log{} statement containing only
source( ) and destination( )
references will send all messages from the specified sources to all
specified destinations.) Elements from several previous examples are combined in Example 12-19, which culminates in several
log{} statements.

Example 12-19. Another sample syslog-ng.conf file


source s_loc { unix-stream("/dev/log"); internal( ); };
source s_tcpmessages { tcp( ip(192.168.190.190); port(10514);); };
destination d_dailylog { file("/var/log/messages.$WEEKDAY"); };
destination d_micklog { file("/var/log/micklog" owner(mick) perm(0600)); };
filter f_mail { facility(mail); };
filter f_messages { level(info .. warn) and not facility(auth, authpriv,
cron, daemon, mail, news); };
log { source(s_tcpmessages); destination(d_micklog); };
log { source(s_loc); filter(f_mail); destination(d_micklog); };
log { source(s_loc); filter(f_messages); destination(d_dailylog); };

As you can see in this example, all messages from the host
192.168.190.190 are written to the logfile
/var/log/micklog, as are all local mail
messages. Messages that match the f_messages( )
filter are written to the logfile
/var/log/messages.$WEEKDAYe.g.,
/var/log/messages.Sun,
/var/log/messages.Mon, etc.

Example 12-19 isn't very realistic,
though: no nonmail messages with priority-level higher than
warn are dealt with. This raises the question,
"Can I get syslog-ng to filter
on `none of the
above'?" The answer is yes: to
match all messages that haven't yet matched filters
in previous log{} statements, you can use the
built-in filter DEFAULT. The following line, if
added to the bottom of Example 12-18, causes all
messages not processed by any of the prior three
log{} statements to be written to the daily
logfile:

log { source(s_loc); filter(DEFAULT); destination(d_dailylog); };

Syslog-ng 1.6 log{} statements now also support
the flags( ) option. If a log statement ends with
flags("final"), log processing ceases with that
statement. flags("fallback") causes the log
statement to match only if the message being evaluated
didn't match any previous log{}
statements. And flags("catchall") causes the
log{} statement's souce() definitions to be ignoredonly its filter(
)
and destination( ) definitions are
parsed.

See Syslog-ng's HTML documentation for more
information on flags( ).


12.2.5. Advanced Configurations


As you're hopefully convinced of by this point,
Syslog-ng is extremely flexible,
so much so that it isn't feasible to illustrate all
possible Syslog-ng configurations. I would be remiss, however, if I
didn't provide at least one advanced
syslog-ng.conf file.

Example 12-20 shows a setup that causes
syslog-ng to watch out for login failures and
access denials by matching messages against a regular expression and
then sending the messages to a shell script (listed in Example 12-21).


Example 12-20. Using syslog-ng as its own log watcher


# WARNING: while this syslog-ng.conf file is syntactically correct and complete, it is
# intended for illustrative purposes only -- entire categories of message
# are ignored!
source s_local { unix_stream("dev/log"); internal( ); };
filter f_denials { match("[Dd]enied|[Ff]ail"); };
destination d_mailtomick { program("/usr/local/sbin/mailtomick.sh"); };
log { source(s_local); filter(f_denials); destination(d_mailtomick); };

Example 12-21. Script for emailing log messages


#!/bin/bash
# mailtomick.sh
# Script which listens for standard input and emails each line to mick
#
while read line;
do
echo $line | mail -s "Weirdness on that Linux box" mick@pinheads-on-ice.net
done The most important lines in Example 12-20 are the
filter f_denials and the destination
d_mailtomick. The filter
uses a match( ) directive containing a regular
expression that matches the strings denied,
Denied, Fail, and
fail.[4] The destination
d_mailtomick sends messages via a
program( ) declaration to the standard input of a
script I wrote called
/usr/local/sbin/mailtomick.sh.

[4] If you're
completely new to regular expressions, I highly recommend
Mastering Regular Expressions
(O'Reilly).



Before we go further in the analysis, here's an
important caveat: program( ) opens the specified
program once and leaves it open until syslog-ng
is stopped or restarted. Keep this in mind when deciding whether to
use pipe( ) or program( )
(pipe( ) doesn't do this), and in
choosing what sort of applications you invoke with program().

In some cases, keeping a script open (actually a
bash process) is a waste of resources and even a
security risk (if you run syslog-ng as
root). Furthermore, the particular use of email
in Examples Example 12-19 and Example 12-20 introduces the possibility of Denial of
Service attacks (e.g., filling up the system
administrator's mailbox). But under the right
circumstances, such as on a non-Internet-accessible host that has a
few CPU cycles to spare, the program( ) driver is
a legitimate use of Syslog-ng.

The script itself,
/usr/local/sbin/mailtomick.sh, simply reads
lines from the standard input and emails each line to
official
(maintained) documentation for Syslog-ng is the Syslog-ng
Reference Manual. PostScript, SGML, HTML, and ASCII text
versions of this document are included in the
/doc directory of Syslog-ng's
source-code distribution.


For advanced or otherwise unaddressed issues, the best source of
Syslog-ng information is the Syslog-ng mailing list and its archives.
See http://lists.balabit.hu/mailman/listinfo/syslog-ng
for subscription information and archives.


/ 94