We help IT Professionals succeed at work.

Send all Apache logs to remote syslog server

Due to security needs, we need to send all Access and Error Apache logs from the Apache web server over to our remote Syslog-ng server. So far I have gotten the ErrorLog portion to work via "ErrorLog syslog:local1" entry in the nss.conf file to post at the remote syslog-ng server. However, when I try to pass the Access and TransferLog data to the local syslog server via a perl script, it seems to never get there. The perl-Sys-Syslog RPM has been installed on the client RHEL server.

This is what is seen in the nss.conf file:

LogFormat "%V %h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\"" vcombined
CustomLog |/etc/httpd/bin/apache_syslog vcombined
TransferLog "|/etc/httpd/bin/apache_syslog vcombined"


This is the example 'access' log data that is seen on the local server _which_ that needs to get recorded over on the remote syslog server:

10.153.13.96 - - [09/Jun/2010:14:50:58 -0400] "GET /assets/js/jquery-1.4.2.min.js HTTP/1.1" 200 72174

I have added the code snippet below of the actual 'logging' script I am using to capture the AccessLog and TransferLog data.


In the /etc/syslog.conf file, I have the following entry for accessing our remote syslog-ng server (it works for errors, just not the rest):

local1.* @10.153.13.117

#!/usr/bin/perl

use Sys::Syslog qw( :DEFAULT setlogsock );

setlogsock('unix');
openlog('apache-access', 'cons', 'pid', 'local1');

while ($log = <STDIN>) {
    syslog('notice', $log);
}
closelog

Open in new window

Comment
Watch Question

Top Expert 2009

Commented:
Hi
i know its not relevant with your questions but you can do another easy way

if you add this line in your virtualhost

CustomLog "|/usr/bin/logger -t 'domain.co.uk' -p local6.info" combined

and if you modify syslog-ng.conf file little bit, syslog-ng will sent log from remote host to central host without using any perl script .


only disadvantages is,.. those log will show on your /var/log/messages files aswell because of local6.info logger.

Michael WorshamCloud/Infrastructure Solutions Architect

Author

Commented:
The logger solution does not work as it adds a copy of the data to the /var/log/messages on the client RHEL server. That is what I am trying to avoid as it voids the security baselines.

As per our security base/guidelines, we are required to have the kernel/system (secure/messages), apache and weblogic data separated into separate directories based on their hostname along with a timestamp. See code snippet below for an example of our syslog-ng configuration.

1) All /var/log/messages, /var/log/secure client syslog.conf data comes in on 192.168.0.1 and directed to it's own directory structure.
2) All weblogic-related syslog messages data comes in on 192.168.0.2 and directed to it's own directory structure.
3) All /var/log/httpd/access_log and /var/log/httpd/error_log messages data comes in on 192.168.0.3 and directed to it's own directory structure.

So far, #1, #2 and #3 (error log) portions work as expected. It's just #3's (access log) is what is flaking out and not being sent to the remote syslog-ng server. If I enable the logger portion/script, then the access_log messages show up in the client's local /var/log/messages file thus come over the #1 data line to the syslog-ng server which is a big no-no.



options {
        sync (0);
        time_reopen (10);
        log_fifo_size (1000);
        long_hostnames (off);
        use_dns (yes);
        use_fqdn (yes);
        create_dirs (yes);
        keep_hostname (yes);
};

source s_localhost {
        file ("/proc/kmsg" log_prefix("kernel: "));
        unix-stream ("/dev/log");
        internal();
};

source s_general {
        udp(ip(192.168.0.1) port (514));
};

source s_weblogic {
        udp(ip(192.168.0.2) port (514));
};

source s_apache {
        udp(ip(192.168.0.3) port (514));
};

destination d_cons { file("/dev/console"); };
destination d_mesg { file("/var/log/messages"); };
destination d_auth { file("/var/log/secure"); };
destination d_mail { file("/var/log/maillog" sync(10)); };
destination d_spol { file("/var/log/spooler"); };
destination d_boot { file("/var/log/boot.log"); };
destination d_cron { file("/var/log/cron"); };
destination d_kern { file("/var/log/kern"); };
destination d_mlal { usertty("*"); };

filter f_kernel     { facility(kern); };
filter f_default    { level(info..emerg) and
                        not (facility(mail)
                        or facility(authpriv)
                        or facility(cron)); };

filter M_audit   { not match("Audit daemon rotating log files"); };
filter M_repeat  { not match("last message repeated"); };
filter M_queue   { not match("queue is full"); };
filter M_snmpd   { not match("from UDP"); };

filter f_auth       { facility(authpriv); };
filter f_mail       { facility(mail); };
filter f_emergency  { level(emerg); };
filter f_news       { facility(uucp) or
                        (facility(news)
                        and level(crit..emerg)); };
filter f_boot   { facility(local7); };
filter f_cron   { facility(cron); };

#log { source(s_localhost); filter(f_kernel); destination(d_cons); };
log { source(s_localhost); filter(f_kernel); destination(d_kern); };
log { source(s_localhost); filter(f_default); destination(d_mesg); };
log { source(s_localhost); filter(f_auth); destination(d_auth); };
log { source(s_localhost); filter(f_mail); destination(d_mail); };
log { source(s_localhost); filter(f_emergency); destination(d_mlal); };
log { source(s_localhost); filter(f_news); destination(d_spol); };
log { source(s_localhost); filter(f_boot); destination(d_boot); };
log { source(s_localhost); filter(f_cron); destination(d_cron); };

# vim:ft=syslog-ng:ai:si:ts=4:sw=4:et:

destination d_localhost {
           file ("/var/syslog/general/$HOST/$FULLHOST-$MONTH.$DAY.$YEAR.log");
};

destination d_general {
          file ("/var/syslog/general/$HOST/$FULLHOST-$MONTH.$DAY.$YEAR.log");
};

destination d_weblogic {
          file ("/var/syslog/weblogic/$HOST/$FULLHOST-$MONTH.$DAY.$YEAR.log");
};

destination d_apache {
          file ("/var/syslog/apache/$HOST/$FULLHOST-$MONTH.$DAY.$YEAR.log");
};

log { source(s_localhost);
      filter(M_audit);
      filter(M_repeat);
      filter(M_queue);
      filter(M_snmpd);
      destination(d_general);
};

log { source(s_general);
       filter(M_audit);
       filter(M_repeat);
       filter(M_queue);
       filter(M_snmpd);
       destination(d_general);
};

log { source(s_weblogic);
       destination(d_weblogic);
};

log { source(s_apache);
       destination(d_apache);
};

Open in new window

Michael WorshamCloud/Infrastructure Solutions Architect

Author

Commented:
Just to clarify the original question to how the syslog-ng.conf is configured, rewrite the following:

local1.* @10.153.13.117

to

local1.* @192.168.0.3
Top Expert 2010
Commented:
Probably irrelevant but have you tested the script, as the Apache / HTTP user-id e.g.

su apache -c 'echo "10.153.13.96 - - [09/Jun/2010:14:50:58 -0400] \"GET /assets/js/jquery-1.4.2.min.js HTTP/1.1\" 200 72174" |/etc/httpd/bin/apache_syslog'

May be a PATH / permission issue.

Alternitively have you seen: https://www.sit.auckland.ac.nz/Logging_to_syslog_with_Apache
Top Expert 2010

Commented:
Oh also check that your apache user-id has a real shell e.g.

finger apache

# if you have s nologin or false shell, just:

usermod -s /bin/bash apache

# and fully bounce (stop + start) the apache.
Michael WorshamCloud/Infrastructure Solutions Architect

Author

Commented:
@arober11: Actually that link you had (https://www.sit.auckland.ac.nz/Logging_to_syslog_with_Apache) might be the trick I am looking for, but before I can accept it as the solution, I am letting the development team hammer away at a couple of test VMs I setup replicating the issue I ran into in their production environment.

The thing I hate is rather than using the standard CommonLog and ErrorLog, the developers are also using something called TransferLog and it's rather fickle when using a 3rd party application/interface to talk to syslog-ng. If I have the CommonLog and ErrorLog enabled, the TransferLog seems to override the ErrorLog socket call, thus never see those 'error' messages appearing at the remote syslog-ng server (see code snippet below for configuration).

 CustomLog "|/usr/bin/logger -s -t 'syslogclt-access' -p info -u /var/run/apache_log.socket" combined
 ErrorLog "|/usr/bin/logger -s -t 'syslogclt-error' -p err -u /var/run/apache_log.socket"
 TransferLog "|/usr/bin/logger -s -t 'syslogclt-transfer' -p info -u /var/run/apache_log.socket"

Open in new window

Michael WorshamCloud/Infrastructure Solutions Architect

Author

Commented:
The link was the solution.

After a bit of code hacking, I am using a UNIX socket passed through the Apache/logger to the RHEL client version of syslog-ng which is then forwarded to the central syslog-ng server.