Secure Remote Logging with syslog-ng and stunnel HOWTO Author: farking (last update 15 Sept 2003) Based on RH 7.3 1. Download all the packages libol-0.3.9-1.i386.rpm (http://www.balabit.com/downloads/ & rpmfind) libol-devel-0.3.9-1.i386.rpm (http://www.balabit.com/downloads/ & rpmfind) syslog-ng-1.5.26-1.i386.rpm (http://www.balabit.com/downloads/ & rpmfind) stunnel-3.26.tar.gz (http://www.stunnel.org/download/stunnel/src/stunnel-3.26.tar.gz / http://www.stunnel.org/download/stunnel/src/stunnel-4.04.tar.gz) logcheck-1.1.1.tar.gz (http://www.linux-sxs.org/files/psionic) stunnel3-converter: http://www.stunnel.org/download/stunnel/contrib/stunnel3_convert 2. Make sure sendmail and crond run on level 2345 #chkconfig --level 2345 sendmail on #chkconfig --level 2345 crond on #/etc/rc.d/init.d sendmail start #/etc/rc.d/init.d crond start 3. Install the packages 3.1 Syslog-ng 3.1a. Configure syslog to not boot at startup to avoid a conflict #chkconfig --level 2345 syslog off 3.1b. Install dependencies: libol & libol devel #rpm -Uvh libol-0.3.9-1.i386.rpm libol-devel-0.3.9-1.i386.rpm 3.1c. Install syslog-ng #rpm -Uvh syslog-ng-1.5.26-1.i386.rpm 3.1d. Configure the system #chkconfig --level 2345 syslog-ng on 3.1e. Configuration ------------------- start syslog-ng.conf for client ------------------- options { use_fqdn(yes); keep_hostname(yes); use_dns(yes); long_hostnames(off); sync(0); log_fifo_size(300); }; # # This is the default behavior of sysklogd package # Logs may come from unix stream, but not from another machine. # source src { unix-stream("/dev/log"); internal(); }; # After that set destinations. # First some standard logfile # destination d_all { usertty("*"); }; destination d_boot { file("/var/log/bootlog"); }; destination d_console { file("/dev/console"); }; destination d_cron { file("/var/log/cron"); }; destination d_mail { file("/var/log/maillog"); }; destination d_messages { file("/var/log/messages"); }; destination d_news_crit { file("/var/log/news/news.crit"); }; destination d_news_err { file("/var/log/news/news.err"); }; destination d_news_notice { file("/var/log/news/news.notice"); }; destination d_secure { file("/var/log/secure"); }; destination d_spooler { file("/var/log/spooler"); }; # The root's console. # destination console { usertty("root"); }; # Virtual console. # #destination console_all { file("/dev/tty8"); }; # Here's come the filter options. With this rules, we can set which # message go where. filter f_authpriv { facility(authpriv); }; filter f_boot { facility(local7); }; filter f_cron { facility(cron); }; filter f_kern { facility(kern); }; filter f_mail { facility(mail); }; filter f_messages { priority(info..emerg) and not facility(mail, news, authpriv, cron, local1, local2, local3, local4, local5, local6); }; filter f_news { facility(news); }; # priority filters # filter f_crit { priority(crit..emerg); }; filter f_crit_only { priority(crit); }; filter f_emerg { priority(emerg); }; filter f_err { priority(err..emerg); }; filter f_err_only { priority(err); }; filter f_info { priority(info..emerg); }; filter f_notice { priority(notice..emerg); }; filter f_warn { priority(warning..emerg); }; ############################################################### log { source(src); filter(f_emerg); destination(d_all); }; log { source(src); filter(f_messages); destination(d_messages); }; log { source(src); filter(f_authpriv); destination(d_secure); }; log { source(src); filter(f_mail); destination(d_mail); }; log { source(src); filter(f_cron); destination(d_cron); }; log { source(src); filter(f_boot); destination(d_boot); }; ############################################################### ## set up logging to a loghost forwarded from localhost via stunnel destination loghost {tcp("192.168.0.231" port(1723));}; # send everything to loghost, too log { source(src); destination(loghost); }; ############################################################### ------------------- end syslog-ng.conf for client ------------------- ------------------- start syslog-ng.conf for loghost ------------------- # This file should be compatible with the out-of-the-box # /etc/syslog.conf on Red Hat Linux (loghost) # global options # options { use_fqdn(yes); keep_hostname(yes); use_dns(yes); long_hostnames(off); use_time_recvd(no); chain_hostnames(no); log_fifo_size(300); mark(0); sync(0); }; source s_local { internal(); unix-stream("/dev/log" keep-alive(yes) max-connections(10)); file("/proc/kmsg"); }; source remote { tcp(ip("0.0.0.0") port(1723) keep-alive(yes)); }; # facility filters # filter f_authpriv { facility(authpriv); }; filter f_boot { facility(local7); }; filter f_cron { facility(cron); }; filter f_kern { facility(kern); }; filter f_mail { facility(mail); }; filter f_messages { priority(info..emerg) and not facility(mail, news, authpriv, cron, local1, local2, local3, local4, local5, local6); }; filter f_news { facility(news); }; # priority filters # filter f_crit { priority(crit..emerg); }; filter f_crit_only { priority(crit); }; filter f_emerg { priority(emerg); }; filter f_err { priority(err..emerg); }; filter f_err_only { priority(err); }; filter f_info { priority(info..emerg); }; filter f_notice { priority(notice..emerg); }; filter f_warn { priority(warning..emerg); }; destination d_all { usertty("*"); }; destination d_boot { file("/var/log/bootlog"); }; destination d_console { file("/dev/console"); }; destination d_cron { file("/var/log/cron"); }; destination d_mail { file("/var/log/maillog"); }; destination d_messages { file("/var/log/messages"); }; destination d_news_crit { file("/var/log/news/news.crit"); }; destination d_news_err { file("/var/log/news/news.err"); }; destination d_news_notice { file("/var/log/news/news.notice"); }; destination d_secure { file("/var/log/secure"); }; destination d_spooler { file("/var/log/spooler"); }; # Everybody gets emergency messages log { source(s_local); filter(f_emerg); destination(d_all); }; # Log anything (except mail) of level info or higher. # Don't log private authentication messages! log { source(s_local); filter(f_messages); destination(d_messages); }; # The authpriv file has restricted access. log { source(s_local); filter(f_authpriv); destination(d_secure); }; # Log all the mail messages in one place. log { source(s_local); filter(f_mail); destination(d_mail); }; # Log cron stuff log { source(s_local); filter(f_cron); destination(d_cron); }; # Save boot messages also to boot.log log { source(s_local); filter(f_boot); destination(d_boot); }; # # INN # log { source(s_local); filter(f_news); filter(f_crit_only); destination(d_news_crit); }; log { source(s_local); filter(f_news); filter(f_err_only); destination(d_news_err); }; log { source(s_local); filter(f_news); filter(f_notice); destination(d_news_notice); }; ############################################################### # automatic host sorting # set it up destination hosts { file("/var/log/HOSTS/$HOST/$FACILITY" owner(root) group(root) perm(0600) dir_perm(0700) create_dirs(yes)); }; # log by host log { source(remote); destination(hosts); }; ############################################################### ------------------- end syslog-ng.conf for loghost ------------------- 1a. Remove "syslog" from "/etc/logrotate.d/" and replace with "syslog-ng". # rm /etc/logrotate.d/syslog 3a. Add this entries into "/etc/services", both port numbers are arbitrary, just make sure they match between the syslog-ng.conf file and the stunnel command syslog-ng 1723/tcp syslog-ngs 1724/tcp 3.1f. Make syslog-ng start on runlevel 2345 #chkconfig --level 2345 syslog-ng on 3.1g. Test initial configuration #/etc/rc.d/init.d/syslog stop #/etc/rc.d/init.d/syslog-ng start 3.2 Stunnel 4.2a Unpack stunnel from tarball package and compile it #tar zxvf stunnel-3.26.tar.gz #cd stunnel-3.26 #./configure #make;make install #cp stunnel.pem /usr/share/ssl/certs/stunnel.pem #chmod 600 /usr/share/ssl/certs/stunnel.pem Create manual stunnel cert #cd stunnel-3.26 #openssl req -new -x509 -days 365 -nodes -config stunnel.cnf -out stunnel.pem -keyout stunnel.pem #cp stunnel.pem /usr/share/ssl/certs/stunnel.pem #chmod 600 /usr/share/ssl/certs/stunnel.pem 4.2b Run the following from a script, possibly "/etc/rc.local" client: #stunnel -c -d 127.0.0.1:syslog-ng -r 192.168.0.231:syslog-ngs -N syslogng server: #stunnel -p /usr/share/ssl/certs/stunnel.pem -d syslog-ngs -r 127.0.0.1:syslog-ng -N syslogng version 4 3.3 Logcheck 3.3a Unpack logcheck tarball package #tar zxvf logcheck-1.1.1.tar.gz #cd logcheck-1.1.1 #make linux 3.3b Put this entries to cron to run logcheck. It will run every 5 minutes. 0-59/5 * * * * root /bin/sh /usr/local/etc/logcheck.sh #vi /etc/crontab 4. Security 4a. Tcpwrappers Place the following in "/etc/hosts.allow" and "/etc/hosts.deny" respectively. ----- start hosts.allow for client ---- syslogng : ALL@192.168.0.231 127.0.0.1 ----- end hosts.allow for client ---- ----- start hosts.allow for loghost ---- syslogng : ALL@192.168.0.232 127.0.0.1 ----- end hosts.allow for loghost ---- ----- start hosts.deny for client and loghost ---- ALL : ALL ----- end hosts.deny for client and loghost ---- 4b. Iptables The only connection made between the client and log host is on the syslog-ngs port which was given above as port 1724. Use the following commands from the server machine to reject all traffic not from the client. #iptables -A INPUT -i eth0 -s 192.168.0.232/32 -p tcp --dport 1724 -j ACCEPT #iptables -A INPUT -i eth0 -s 0.0.0.0/0 -p tcp --dport 1724 -j REJECT 5. Done. Check whether there is log file in the directory /var/log/HOSTS/somedomain.com on loghost. 6. References - http://venus.ece.ndsu.nodak.edu/~jezerr/linux/secure-remote-logging.html - http://campin.net/syslog-ng/faq.html - http://englanders.cc/~jason/howtos.php?howto=stunnel - http://www.stunnel.org/faq/certs.html - http://home.hiwaay.net/~hmug/HowTos/logcheck.html