Contents:


About this document

5. A Central Log Server — syslog-ng

Sysadmins are far too busy (lazy) to monitor logs properly; intruders unhelpfully edit logs to hide their presence. Both issues can be addressed by setting up a log server: such a machine collects system logs from many client machines via UDP remote-logging.

5.1. An aside: NTP

For both forensic and legal reasons, date/timestamps of log messages must be accurate. To achieve this, all log clients and the log-server should use NTP (or an equivalent service) to keep system clocks set accurately.

5.2. Syslog NG

Syslog can be used to collect logs from client machines, but is ill-suited to the task — it's showing its age: it is not obvious, for example, how to separate logs from different machines into different directories; with dozens or even hundreds of clients this is a must. Syslog NG is a prime candidate to use instead.

5.2.1. Installation

Syslog-NG can be installed from source via the classic .configure, make, make install sequence; Debian packages are available.

5.2.2. Startup Options

Options which affect the security of the server include:

    -u <username>  }  after initialisation drop root privileges and run
    -g <group>     }  as <username>:<group>

    -C /chroot/path    after reading the config file, chroot to path given
Having Syslog-NG listening as root is a very bad idea, so set up a suitable username and group, for example:
    /etc/group
        syslogng:x:77:

    /etc/passwd
        syslogng:x:99:65534::/var/chroot/syslogng:/bin/false

5.2.3. Configuration of syslog-ng

The configuration file /etc/syslog-ng/syslog-ng.conf is divided into options, sources, destinations, filters and logs.

options affecting server security include:

    options {

        # -- resolve address of message sender?  show names of all hosts by 
        #    which the message has been handled?
        use_dns(no);
        chain_hostnames(no);
        ##dns_cache(yes);
            # ...syslog-ng blocks on DNS queries, so enabling DNS may lead 
            #    to a DOS, hence set both of the above to "no"...

        # -- enable or disable directory creation for destination files
        create_dirs(yes);
            # ...macros in the config file (see below) mean that new dirs  
            #    will be created as packets from new IP addresses are 
            #    encountered --- this could be an issue if packets are spoofed,
            #    but appropriate firewalling should resolve this issue...

        # default owner, group, and permissions for log files
        # (defaults are 0, 0, 0600)
        owner(syslogng);
        group(adm);
        perm(0640);

        # default owner, group, and permissions for created directories
        # (defaults are 0, 0, 0700)
        dir_owner(syslogng);
        dir_group(syslogng);
        dir_perm(0755);
  };

Here are couple of likely sources for a central log-server. First, we'll want to log our own messages plus standard stuff from our own host OS:

    source s_local {
        # -- messages generated by Syslog-NG :
        internal();

        # -- standard Linux log source (location to which syslog() function 
        #    sends messages by default) :
        unix-stream("/dev/log");

        # -- messages from the kernel :
        file("/proc/kmsg" log_prefix("kernel: "));
      };
Secondly, we want to listen for incoming UDP-based messages from our clients:
    source s_udp {
        # -- receive remote UDP logging messages (equivalent to the "-r" 
        #    syslogd flag)
        udp(ip(0.0.0.0) port(514));
      };

Here is a particularly simple treatment of our own local messages:

    destination df_auth    { file("/var/log/auth.log"); };
    destination df_syslog  { file("/var/log/syslog");   };

    filter f_auth   {     facility(auth, authpriv); };
    filter f_syslog { not facility(auth, authpriv); };

    # -- auth,authpriv.*                 /var/log/auth.log
    log {
        source(s_local);
        filter(f_auth);
        destination(df_auth);
      };

     # -- *.*;auth,authpriv.none          -/var/log/syslog
     log {
        source(s_local);
        filter(f_syslog);
        destination(df_syslog);
      };

Local boot-related messages:

    # -- local7.*                                            /var/log/boot.log

    destination df_boot     { file("/var/log/boot.log"); };
    filter      f_boot      { facility(local7); };

    log {
        source(s_local);
        filter(f_boot);
        destination(df_boot);
      };

We can use Syslog-NG macros to help us in dealing with messages from our clients. We don't want them all jumbled together. This way each client gets its own directory:

    destination hosts {
        file("/var/log_hosts_by_facility/$HOST/$FACILITY.log"
             owner(root) group(root) perm(0600) dir_perm(0700)
             create_dirs(yes));
      };

    log {
        source(s_udp);
        destination(hosts);
      };

5.3. Firewalling

To help prevent a DOS attack on the server, suitable firewalling is essential. Here is the most basic:

$IPTABLES -t filter -A INPUT -p udp -s server.umist.ac.uk --dport 514 -j ACCEPT
$IPTABLES -t filter -A INPUT -p udp -s host.umist.ac.uk --dport 514 -j ACCEPT

$IPTABLES -t filter -P INPUT  DROP

5.4. Chrooting Syslog-NG

Ideally all services on a server which listen on a publicly accessible port chroot should be chrooted for security reasons. Syslog-NG is no exception.

Syslog-NG has a built-in option to chroot itself after binding to port 514. This means that the chroot environment to be built can be greatly simplified (which means less for a potential intruder to play with if they can get into the jail, and less for us to maintain): we do not need a shell and its supporting libraries, or many of the files syslog-ng opens on startup, before it chroots (use lsof to see that there are quite a few of these).

Mick Bauer has written a HOW-TO. The words below are based on that: this version is simplified — since all DNS look-ups are turned off in our configuration (to eliminate a possible DOS attack), none of /etc/resolv.conf, /etc/nsswitch.conf and libnss*.so.* are required.

5.4.1. Building the chroot Environment

  1. First, make necessary directories:
            $LOGJAIL/etc/syslog-ng
            $LOGJAIL/dev/
            $LOGJAIL/var/log
    where e.g. $LOGJAIL=/var/chroot/syslog-ng.

  2. Next, ensure that you have a suitable — unprivileged — user/group for Syslog-NG to run as, so add lines something like this
            syslogng:x:99:65534::/var/chroot/syslogng:/bin/false
            syslogng:x:77:
    to $LOGJAIL/etc/passwd and $LOGJAIL/etc/group, respectively — these can be the only entries in these files.

  3. Move the Syslog-NG configuration file, /etc/syslog-ng/syslog-ng.conf to the jail and turn its old location in to a symlink:
            cd /etc/syslog-ng
            mv syslog-ng.conf $LOGJAIL/etc/syslog-ng
            ln -s $LOGJAIL/etc/syslog-ng/syslog-ng.conf /etc/syslog-ng/syslog-ng.conf


  4. Create a couple of required devices (actually these are necessary only if required by the destinations in syslog-ng.conf):
            cd $LOGJAIL/dev
            mknod -m 0660 xconsole p
            mknod -m 0660 tty10 c 4 10
            chgrp syslogng ./xconsole ./tty10
    (xconsole is a pipe and is used as a destination — see syslog-ng.conf; tty10 is a character device with major and minor numbers 4 and 10, respectively: it seems traditional to send syslog output to tty10 — you can watch it using CTRL-ALT-F10 locally, or using ttysnoop.)

  5. Copy /etc/localtime to $LOGJAIL/etc.
Simple!

5.4.2. Starting Syslog-NG: an init Script

The following simple init script is all that's necessary to start syslog-ng and have it chroot itself:

    /etc/init.d/syslog-ng

      #! /bin/sh

      case "$1" in
        start)
          /sbin/syslog-ng -C /var/chroot/syslogng -u syslogng -g syslogng || ex\
it 1
          ;;
        *)
          echo "Usage: /etc/init.d/syslog-ng start" >&2
          exit 1
          ;;
      esac

      exit 0

5.4.3. Stopping Syslog-NG

    pkill syslog-ng

5.4.4. Restarting Syslog-NG — Not kill -HUP

The usual way to restart syslog-ng after a configuration change (or after a log rotation) is to kill -HUP the process. This will not work in the above jail as the already-chrooted process will not be able to bind to port 514 (a privileged port, as there is not root user in the jail), not are many required files available, e.g., /dev/kmesg and a bunch of shared-object libraries (use lsof to see which).

Assuming this actually presented a problem, one could build a more complex jail in which one could "manually" start syslog-ng (and in which it would therefore be restartable), like this:

    chroot /var/chroot/syslog-ng bash
    /sbin/syslog-ng -u syslogng -g syslogng    
        # ...that's /var/chroot/syslog-ng/sbin/syslog-ng now...

5.5. Log Rotation: logrotate

Since syslog-ng cannot be restarted within its jail (see above), we have to use the copytruncate option when using logrotate, for example:

    /var/chroot/syslogng/var/log_hosts_by_facility/130.88.*/*.log {
        rotate 28
        daily
        copytruncate
        missingok
        notifempty
        compress
  }


...previousup (conts)next...