chrysocome.netChrysocome Logo

HOWTO make syslogd listen on multiple ports

What is this page about

At out site, all the linux boxes use remote logging so we can collate the logs on a central server. This works well for a small number of machines but now we want to separate into groups of machines (servers, staff & students). Unfortunately the syslogd from sysklogd reads a port number only from /etc/services and we can't control the interface which it binds to.

One solution would be to modify the code to solve one or both of these issues but I was looking for a way which did not require source modification. The solution was to use a chroot environment.

Setting up the chroot

First I will present the commands required for setting this up on Red Hat Enterprise Linux 2.1 or CentOS-2, then I will list some techniques for working out any steps for yourself. There is also a script which you can download which works for Red Hat Enterprise Linux 4 and CentOS-4. In the sample below, the # indicates a root shell prompt which you should not type in. Everything after the # should be entered on a single line even if the line is wrapped below.

# mkdir -p /var/log/virtual/student
# cd /var/log/virtual/student
# mkdir -p dev etc lib sbin var/log var/run
# cp /sbin/syslogd sbin
# cp /lib/ lib
# cp /lib/ lib
# cp /lib/ /lib/ /lib/ lib
# cp /etc/syslog.conf etc
# cp /etc/host.conf /etc/nsswitch.conf /etc/resolv.conf etc
# cp /etc/localtime etc
# grep syslog /etc/services > etc/services

The daemon can then be started with this command

# chroot /var/log/virtual/student /sbin/syslogd -r

You can control the port that syslogd will use by editing etc/services and modifying the syslog port number. You should probably use debug mode to make sure that things are working. To do that, start stunnel with the -d parameter

# chroot /var/log/virtual/student /sbin/syslogd -d -r

If you get errors about missing libraries or file not found errors, your syslogd binary might be linked against different libraries than mine (this is quite possible if you are not running RHEL21). If so you can get a list of libraries by using the ldd command

# ldd /sbin/syslogd => /lib/i686/ (0x40029000) /lib/ => /lib/ (0x40000000)

For each library listed, copy it into the lib directory. Don't worry about using subdirectories like i686 unless you are really anal and want to set up the symlinks.

Because parts of libc are dynamically loaded at run time, you may require libraries which are not listed by ldd. The easy way to find out what you need it to use strace. Install strace in your chroot and then run syslogd

# mkdir -p usr/bin
# cp /usr/bin/strace usr/bin
# chroot /var/log/virtual/student /usr/sbin/strace /sbin/syslogd -d -r

Library loads will be shown like this

open("/lib/", O_RDONLY) = 3

If the file can't be found then you will get errors like this

open("/lib/mmx/", O_RDONLY) = -1 ENOENT (No such file or directory)

Some errors are OK, others indicate problems.

You will also see requests to open config files like /etc/hosts etc. Again, some are required and others are not necessary. You just have to play around till you get the right ones (or RTFM/use the source/ask your local Guru etc.).

Once you have everything set up, write an init script to start everything up the way you want it and your server side is done.

The client side is quite simple, just edit the syslog port number in /etc/services. You can do this with a simple (?) perl command. This command will change the port number to 1234.

# /usr/bin/perl -pi -e "s|^syslog[[:space:]].*/udp$|syslog 1234/udp|" /etc/services
Downloads for syslog family
Program Version Content Format Platform Download
syslog 0.2 Source .tgz linux syslog-0.2.tar.gz

Other things to do


You probably want to rotate the virtual logs too. In /etc/logrotate.d make a copy of syslog called syslog_<virtual name> for each of your virtual hosts. Edit the file and prepend the /var/log/<virtual name> to each of the log file names and the .pid file name

init script

# cp syslog-virtual /etc/rc.d/init.d/
# chkconfig --add syslog-virtual
# service syslog-virtual start
Starting system logger in /var/log/virtual/esr [ OK ] Starting system logger in /var/log/virtual/staff [ OK ] Starting system logger in /var/log/virtual/student [ OK ]