Instructions on running syslog-ng as non-root, in a chroot, writing logs to /var/spool/syslog-ng/$HOST/$YYYY/$MM/$DD/$PROGRAM.
Install syslog-ng, create user and setup filesystem:
$ sudo apt-get install syslog-ng
...
$ sudo adduser --system --home /var/log/syslog-ng --gecos 'syslog-ng' --group syslogng
Adding system user `syslogng'...
Adding new group `syslogng' (114).
Adding new user `syslogng' (114) with group `syslogng'.
Creating home directory `/var/log/syslog-ng'.
$ sudo install -d -m0750 -o syslogng -g syslogng /var/log/syslog-ng
Disable rotation of the old log files (or you will get error mail from cron every day):
$ sudo perl -pe 's/^/#/' -i /etc/logrotate.d/syslog-ng
Edit /etc/syslog-ng/syslog-ng.conf:
options { use_fqdn(yes); use_dns(no); chain_hostnames(yes); use_time_recvd(no); # sync(10); perm(0640); owner("syslogng"); group("syslogng"); create_dirs(yes); dir_perm(0750); dir_owner("syslogng"); dir_group("syslogng"); }; source syslog { unix-stream("/dev/log"); }; source kernel { file("/proc/kmsg"); }; source syslog-ng { internal(); }; destination firewall { file("/spool/$HOST/$YEAR/$MONTH/$DAY/firewall"); }; destination kernel { file("/spool/$HOST/$YEAR/$MONTH/$DAY/kernel"); }; destination invalid { file("/spool/unknown/$YEAR/$MONTH/$DAY/invalid"); }; destination postfix { file("/spool/$HOST/$YEAR/$MONTH/$DAY/postfix"); }; destination cron { file("/spool/$HOST/$YEAR/$MONTH/$DAY/cron"); }; destination generic { file("/spool/$HOST/$YEAR/$MONTH/$DAY/$PROGRAM"); }; destination syslog-ng { file("/spool/$HOST/$YEAR/$MONTH/$DAY/syslog-ng"); }; destination misc { file("/spool/$HOST/$YEAR/$MONTH/$DAY/misc"); }; ## kernel filter firewall { match("^firewall:") or match("^NAT:"); }; filter notfirewall { not match("^firewall:") and not match("^NAT:"); }; log { source(kernel); filter(firewall); destination(firewall); }; log { source(kernel); filter(notfirewall); destination(kernel); }; ## internal log { source(syslog-ng); destination(syslog-ng); }; ## syslog filter invalid { not host("^syslog@[a-z][a-z0-9-]*$"); }; filter postfix { host("^syslog@[a-z][a-z0-9-]*$") and program("^postfix/"); }; filter cron { host("^syslog@[a-z][a-z0-9-]*$") and program("^(/USR/SBIN/CRON|/usr/sbin/cron|CRON|cron)$"); }; filter generic { host("^syslog@[a-z][a-z0-9-]*$") and program("^([a-z][a-z0-9._-]*)$"); }; log { source(syslog); filter(invalid); destination(invalid); }; log { source(syslog); filter(postfix); destination(postfix); }; log { source(syslog); filter(cron); destination(cron); }; log { source(syslog); filter(generic); destination(generic); }; log { source(syslog); destination(misc); flags(fallback); };
Edit /etc/init.d/syslog-ng:
Add options -C /var/log/syslog-ng -u syslogng -g syslogng to where ever you see --start:
syslogng_start() {
echo -n "Starting system logging: syslog-ng"
start-stop-daemon --start --quiet --exec "$SYSLOGNG" --pidfile "$PIDFILE" -- -p "$PIDFILE" \
-C /var/log/syslog-ng -u syslogng -g syslogng \
|| { echo " start failed."; return 1; }
echo "."
return 0
}
Note
Linux 2.6 won't let you run a kernel message logger as non-root
Linux 2.6 checks the relevant access permissions on every read from /proc/kmsg, as opposed to just on open, as Linux 2.4 used to do. There is no easy way to work around this -- the proper solution is likely either to fix the kernel or drop root but retain a specific capability.
For now, drop the -u and -g options, like this:
syslogng_start() {
echo -n "Starting system logging: syslog-ng"
start-stop-daemon --start --quiet --exec "$SYSLOGNG" --pidfile "$PIDFILE" -- -p "$PIDFILE" \
-C /var/log/syslog-ng \
|| { echo " start failed."; return 1; }
echo "."
return 0
}
Restart syslog-ng to make the changes take effect:
$ sudo /etc/init.d/syslog-ng restart
Give admin accounts read access to logs:
$ sudo gpasswd -a <replaceable>youruseraccount</replaceable> syslogng
Log out or use newgrp to make the added group take effect.