[syslog-ng]HOWTO GET SYSLOGS INTO POSTGRESQL SQL DATABASE

Russo, Ben [email protected]
Thu, 25 Apr 2002 18:27:44 -0400


HOWTO=20

HOW TO GET SYSLOGS INTO POSTGRESQL SQL DATABASE
	originally by Ben Russo 04/25/2002

		AUDIENCE

This document is intended to be read by a UNIX System Administrator
with at least a year or two of experience.  This document is heavily
biased towards RedHat LINUX because the author likes RedHat Linux. =20

If you want to do this on another UNIX platform, more power to you,=20
but I won't be writing a document about how to do it.

Feel free to use this document however you want. (My friends suggest
that it comes in handy in the toilet and next to the fireplace).
You can modify it and redistribute it however you want to, but=20
please (just a suggestion) leave my name as the *original*
author.

There are no guarantees or warrantees about the advice given here.
It is full of mispeellings and grammar mistakes for which I will
never make no apologiez.

		GOAL

The goal of this document is to provide a procedure for creating
a centralized SYSLOG sink that imports syslog messages into a=20
postgreSQL database and provides ODBC access to that database.
So that you can use PgAdmin or MS Access to generate Syslog Reports.

You could theoretically set up triggers in Postgres (based on inserts)
that would cause your system to kick off other jobs (like paging the
sysadmin).
But that won't be covered here.

		CREDITS & THANKS

I would like to thank Open Source developers everywhere,
I hesitate to mention names because there are so many of them
and they all deserve great recognition.  However I will mention
a few that are relevant to this document, there are many more people
as well but you are going to skip this section anyway so why bother.

	 Bal=E1zs Scheidler  (author & maintainer of syslog-ng)
		Thanks for all your hard work!

	 Bruce Momjian (author of the PostgreSQL Book from which
			     I learned much about databases, and=20
				a major contributor to the PostgreSQL
				 database project)

I would dedicate this document to open source developers, but
it sucks so much I don't want to embarress them.


	HOWTO....

Set up a PC with the latest version of Linux and all the patches.
	(You could use any UNIX, but I like Linux, and I wrote this.)
You can set it up however you like best but make sure that you at least
install the following:

	ssh/scp
	bind
	cacheing-nameserver config
	ntp
	postgreSQL
	syslog-ng

After installing your box, make sure that it is on the network.
If I were you I would disable everything else on the box that is=20
network accessible.

Set up bind to be started at boot time and set forwarders to your
default name servers and set up forward only. =20
Set the /etc/resolv.conf to point at 127.0.0.1

This setup is designed to create a forwarding only caching DNS server
that will increase the performance of the syslog-ng server when doing
NS-LOOKUPS

Set up and configure ntp to be started at boot time.
Make sure that the systems default time zone is set for UCT
(Universal Coordinated Time).  This is important for this=20
box because all our syslogs will be coming from different zones.
Even the Neutral Zone.

Get the latest tarball for libol and syslog-ng from the balabit
website (where syslog-ng is from). use "rpm -tb " on the tarballs=20
(you will need all the development tools and compilers and devel libs=20
and rpm-build installed, as well as the kernel headers) =20
     (****USE RPMS THEY ARE GOOD FOR YOU****)
The rpm -tb command will create i386.rpm binary install packages
for libol and syslog-ng and put them in /usr/src/redhat/RPMS/i386

use "rpm -Uvh" on the newly created rpms to install them.

Then "cd /usr/etc" and=20
"mkdir /etc/syslog-ng; ln -s ../../etc/syslog-ng syslog-ng"

in the /etc/syslog-ng directory place the following=20
into syslog-ng.conf



*******************************BEGIN FILE /etc/syslog-ng/syslog-ng.conf

# syslog-ng configuration file for RedHat 7.2
#
# See syslog-ng(8) and syslog-ng.conf(5) for more information.
#
# Originall:  20000925 [email protected]
# Modified:  20020424  [email protected]
#

options { sync (0);
          time_reopen (10);
          log_fifo_size (100);
          long_hostnames (on);
          use_dns (yes);
          use_fqdn (yes);
          create_dirs (yes);
          keep_hostname (yes);
          time_reap(12);
          gc_busy_threshold(768);
        };

########################################################################=
####
###

source s_sys { unix-stream ("/dev/log"); internal(); };
source s_udp { udp(); };

########################################################################=
####
###

# destination d_files { =
file("/var/log/syslog-ng/$HOST/$FACILITY.$LEVEL"
#                      template("$ISODATE $HOST $FACILITY $PRIORITY =
$PROCESS
$MSG\n"));
#                    };

destination d_msgs { file("/var/log/messages"
                      template("$FULLDATE $HOST $FACILITY.$PRIORITY
$MSG\n"));
                    };

destination d_mail { file("/var/log/maillog"
                      template("$FULLDATE $HOST mail.$PRIORITY =
$MSG\n"));
                    };

destination d_secure { file("/var/log/secure"
                      template("$FULLDATE $HOST authpriv.$PRIORITY
$MSG\n"));
                    };

destination d_cron { file("/var/log/cron"
                      template("$FULLDATE $HOST cron.$PRIORITY =
$MSG\n"));
                    };

destination d_bootlog { file("/var/log/boot.log"
                      template("$FULLDATE $HOST local7.$PRIORITY =
$MSG\n"));
                    };

destination d_tty12 { pipe("/dev/tty12"
                      template("$FULLDATE $FACILITY.$PRIORITY =
$MSG\n"));
                    };

destination d_postgres {
file("/var/lib/pgsql/syslog/datafiles/fulllog.$YEAR.$MONTH.$DAY.$HOUR.$M=
IN.$
SEC"
       template("INSERT INTO msg_table VALUES \( '$R_ISODATE', =
'$S_ISODATE',
'$HOST', '$FACILITY', '$PRIORITY', '$MSG'\)\;\n")
       template_escape(yes)
       owner(postgres));
                   };

########################################################################=
####
####
########################################################################=
####
####

filter f_msgs { host("syslog")
                and level(warning,err,crit,alert,emerg)
                and not facility(mail,authpriv,cron);
              };

filter f_mail { host("syslog")
                and facility(mail);
              };

filter f_cron { host("syslog")
                and facility(cron);
              };

filter f_secure { host("syslog")
                and facility(authpriv);
              };

filter f_bootlog { host("syslog")
                and facility(local7);
                 };

filter f_tty12 { host("syslog")
                and level(crit,alert,emerg);
               };

########################################################################=
####
######
########################################################################=
####
######

# log { source(s_sys); source(s_udp); destination(d_files); };
log { source(s_sys); source(s_udp); filter(f_msgs); =
destination(d_msgs); };
log { source(s_sys); source(s_udp); filter(f_mail); =
destination(d_mail); };
log { source(s_sys); source(s_udp); filter(f_secure); =
destination(d_secure);
};
log { source(s_sys); source(s_udp); filter(f_cron); =
destination(d_cron); };
log { source(s_sys); source(s_udp); filter(f_bootlog);
destination(d_bootlog); };
log { source(s_sys); source(s_udp); filter(f_tty12); =
destination(d_tty12);
};
        # This allows you to hit "ALT-F12" on a Linux console and get
        # all the important log messages scrolling up your screen.
log { source(s_sys); source(s_udp); destination(d_postgres); };

**************************END OF FILE /etc/syslog-ng/syslog-ng.conf

then set up your syslog-ng init script in /etc/rc.d/init.d
like so:

**************************BEGIN FILE /etc/rc.d/init.d/syslog-ng
#!/bin/bash
#
# syslog-ng       Starts syslog-ng/klogd.
#
#
# chkconfig: 2345 12 88
# description: Syslog-ng is the facility by which many daemons use to =
log \
# messages to various system log files.  It is a good idea to always \
# run syslog-ng.

# Source function library.
. /etc/init.d/functions
:

########################################################################=
####
####
# configuration
#
INIT_PROG=3D"/sbin/syslog-ng"    # Full path to daemon
INIT_OPTS=3D""                      # options passed to daemon

PATH=3D/bin:/sbin:/usr/bin:/usr/sbin

INIT_NAME=3D`basename "$INIT_PROG"`

# Uncomment this if you are on Redhat and think this is useful
#
# . /etc/sysconfig/network
#
# if [ ${NETWORKING} =3D "no" ]
# then
#       exit 0
# fi

RETVAL=3D0

umask 077
ulimit -c 0

# See how we were called.
case "$1" in
  start)
        export TZ=3DUCT
        echo -n "Starting $INIT_NAME: "
        daemon --check $INIT_PROG "$INIT_PROG $INIT_OPTS"
        RETVAL=3D$?
        echo -n "Starting Kernel Logger: "
        [ -x "/sbin/klogd" ] && daemon klogd
        echo
        [ $RETVAL -eq 0 ] && touch "/var/lock/subsys/${INIT_NAME}"
        ;;
  stop)
        echo -n "Stopping $INIT_NAME: "
        killproc $INIT_PROG
        RETVAL=3D$?
        echo -n "Stopping Kernel Logger: "
        [ -x "/sbin/klogd" ] && killproc klogd
        echo
        [ $RETVAL -eq 0 ] && rm -f "/var/lock/subsys/${INIT_NAME}"
        ;;
  status)
        status $INIT_PROG
        RETVAL=3D$?
        ;;
  restart|reload)
        $0 stop
        $0 start
        RETVAL=3D$?
        ;;
  *)
        echo "Usage: $0 {start|stop|status|restart|reload}"
        exit 1
esac

exit $RETVAL
********************************END OF FILE /etc/rc.d/init.d/syslog-ng

Disable the default syslog daemon installed by RedHat.
use chkconfig to get rid of it's sysVinit links
start up syslog-ng!

use chkconfig to make sure that the proper SysVinit links are created =
and
that syslog-ng is configured to be started when the box is.

Also use chkconfig to make sure that postgresql is configured to start
when the system is.

Copy /var/lib/pgsql/data/pg_hba.conf to =
/var/lib/pgsql/data/pg_hba.conf.orig
Edit /var/lib/pgsql/data/pg_hba.conf so that it contains the following
lines:

**************BEGIN**************
local   syslog-ng    trust admins
local   all     md5
host    all     172.16.0.0 255.240.0.0 md5
host    all     127.0.0.1 255.255.255.255 md5
*************END******************

echo "postgres" > /var/lib/pgsql/data/admins

Make sure that the following lines=20
are uncommented in /var/lib/pgsql/data/postgresql.conf

	port =3D 5432
	tcpip_socket =3D true
	fsync =3D false
	shared_buffers=3D256
=09
If you are not going to monitor the box to make sure that the log files
under /var/log and /var/lib/pgsql/syslog
don't grow too big then you should write some scripts to clean them up
automatically.

I plan on doing this eventually, but at this stage in the development =
of=20
the system I want to watch it manually until I figure out what is going =
on.


Now lets reboot the box and make sure of a few things.
	So far when the box boots only=20
		sshd
		ntpd
		bind
		postgresql (postmaster is the network listener)
		syslog-ng
	should be listening on the network

NTP should sync up with the time servers.
Bind should be forward only and the local system should resolv from =
itself.
SSH & SCP should be accessible from the network.
cron should be running.
postmaster should be accepting connections from other psql boxes.

Now, run "su - postgres" and run the command: "createdb syslog-ng"
Then run "psql -U postgres -d syslog-ng"
You should now be at an SQL terminal prompt,
and you need to run the following commands:

CREATE sequence msg_seq_num;
CREATE TABLE msg_table (
msg_rcv_time timestamp,
msg_sent_time timestamp,
hostname varchar(256),
msg_facility varchar(16),
msg_priority varchar(16),
msg_text text,
msg_id integer default nextval('msg_seq_num')
);

ALTER USER postgres with encrypted password 'enter password here'

\q


Now create the file called =
/var/lib/pgsql/syslog/run-syslog2pgsql-insert.sh
with the content:

**************************************BEGIN FILE
*****************************
#!/bin/bash
#
#       /var/lib/pgsql/run-syslog2pgsql-insert.sh
#       23-April-2002  by Ben Russo
#
#       This script is intended to be called by cron.
#       This script should never exit, it runs in a loop.
#       The first thing it should do is check to see that
#       if there is another instance already running.
#
#       running this script every minute should work pretty good.
#
#
LOGFILE=3D/var/lib/pgsql/syslog/syslog2pgsql-insert.log
export TZ=3DUCT
if [ -f /var/lib/pgsql/syslog/.insert.lockfile ]
  then
     OLDPID=3D`cat /var/lib/pgsql/syslog/.insert.lockfile`
     NUMPROCS=3D`ps -e | grep $OLDPID | grep run-syslog2pg | wc -l`
     if [ $NUMPROCS -eq 1 ]
        then
         exit 0
     fi
  fi

echo $$ > /var/lib/pgsql/syslog/.insert.lockfile

while true
  do
   FILELIST=3D`find $DATADIR -name
"fulllog.2[0-9][0-9][0-9].[0-1][0-9].[0-3][0-9].[0-2][0-9].[0-5][0-9].[0=
-6][
0-9]"`
   usleep 999997
   for i in $FILELIST
    do
     cat $i | psql -U postgres -d syslog-ng >> $LOGFILE 2>&1
     DATE=3D`date`
     echo "=3D=3D=3D=3D=3D=3D=3D=3D=3D $DATE finished $i" >> $LOGFILE
     rm -f $i
    done
   SLPID=3D`pidof syslog-ng`
   done
***************************************END
FILE*********************************

Make sure that everything under /var/lib/pgsql/ is owned by postgres.

Add the following line to the postgres users crontab:

	* * * * * /var/lib/pgsql/syslog/run-syslog2pgsql-insert.sh >>
/var/lib/pgsql/syslog/syslog2pgsql-insert.log 2>&1

Next, install the PsqlODBC driver on your windows desktop PC
and install the "pgadmin" utility.

Open your control panel
Open the ADMINISTRATIVE TOOLS sub-panel
Double click on the "DATA SOURCES (ODBC)"
	Icon
Select the System DSN tab from the window that appears.
Click on the "ADD" button.
Select PostgreSQL=20
Enter "syslog-ng" (or whatever the name of the database was
that you created)
Enter the host name of your database server
The port should be 5432

Your User name can be "postgres" if you are the admin
or "guest" (we will create that user soon enough).
and the database password for the account name you picked.
The password for "guest" should be "guest"

Click OK, click OK again, close your control panel windows.

Now you can run PGADMIN from the windows start menu ICON.
In this utility you can add users and groups and set=20
permissions for the tables and columns.
You can use the query wizard to generate and save queries
and direct their output to Excell, HTML, TXT or Screen.

Create the "guest" "guest" user after logging in as the
postgres user.  Also create the guest account.

Right click on your msg_table and select=20
properties, and on the Security tab give the guest group.

Give the guest group the ability to "SELECT" only.

Now open up MS Access,  open a blank database.
>From the FILE menu select GET EXTERNAL DATA, LINK TABLES
and in the filebrowser window that pops up you need to=20
scroll down in the "FILES OF TYPE" window to ODBC Databases()
Then in the "Select Data Sources" window that appears go
to the "Machine Data Source" window and scroll down=20
to PostgreSQL

Then select the msg_table and click "OK"
Then select the "oid" field (or the "msg_id" field)
as your Unique record Identifier and click OK.

Now you can use MS-Access to do queries and searches
and reports.