Although logging events to files stored locally allows us to organise our logs, and keep historic records for auditing purposes, it rapidly becomes impractical to manage the storage and analysis of log files spread over anything other than a very small number of hosts.
Another good reason to keep security related logs on a central server is that the first thing a competent attacker would usually do after gaining access to a compromised machine is delete any trace of their attack from the log files. This, fairly obviously, helps prevent either the system administrator or automated log analysis software from spotting the intrusion. If these logs are stored on a centralised server this task will be much more difficult to accomplish.
As if the previous two reasons were not enough in themselves keeping all the logs files on a central system makes their analysis considerably easier as the log analysis software only needs to be installed on a single machine.
Like many network capable services which use the IP protocol for network communications the syslog-ng daemon is capable of communicating over either the connection oriented TCP protocol or the connectionless UDP protocol. Each of these protocols has advantages and disadvantages which may encourage, or in some cases even force, you to use one over the other, or even both.
The TCP protocol is usually the best choice for clients which are also running the syslog-ng logging daemon. It offers a connection oriented service which guarantees that no log messages will be lost in transit and allows the client to detect any failure of the connection and attempt to re-establish it.
A log source to receive log messages sent over the network using the TCP protocol can be declared in the configuration file as shown below.
source s_network_tcp { tcp(); }
While this will create a socket which listens on the default TCP port for the syslog service, which is 514, using the default options, which allow for a maximum of 10 simultaneous connections which will not be closed in response to a SIGHUP, these defaults can be overridden by specifying the new options as arguments to the tcp source driver as shown below.
source s_network_tcp { tcp( port(5014) keep-alive(no) max-connections(100) ); }
As UDP offers no guarantee that messages will be delivered some log messages may be lost when logging over this protocol. The UDP protocol should, therefore, probably only be used when backward compatibility with the original syslog daemon is required or if connection reliability is already ensured by the underlying network transport such as an IP over IP tunnel.
A log source to receive log messages sent over the network using the UDP protocol can be declared in the configuration file as shown below.
source s_network_udp { udp(); }
As with the tcp log source we examined in the previous section the udp source can have additional parameters configured as shown in the example declaration below.
source s_network_udp { udp( port(5014) ); }
As the UDP protocol is connectionless it does not support the keep-alive or max-connections options.
We mentioned in the installation instructions that the syslog-ng service could be installed with support for TCP wrappers. If you enabled this use-flag when installing be sure to add entries to the appropriate files as shown below remembering to also change the IP addresses as needed.
The entries shown above will allow access to the syslog-ng service to any machines on the 10.x.x.x network and the loopback interface while denying access to all other systems.
The syslog-ng daemon provides some options which can be applied globally that are applicable to a network server configuration. These are described below.
A set of reasonable example options is given below. They should be combined with the options which we examined in previous sections.
options
{
chain_hostnames(no);
keep_hostname(yes);
check_hostname(yes);
use_dns(no);
dns_cache(no);
use_fqdn(no);
use_time_recvd(no);
}
In the previous sections we described how to configure syslog-ng to receive log messages from remote systems. If we combine this with the configuration which we have developed so far we will be able to log these messages to files categorised using their facility and level. In this section we shall examine some of the other macros which the syslog-ng daemon provides to allow us to organise our log files.
With the current configuration, rather unfortunately, all the log entries from our client machines will be stored in the same sets of files when what we probably want is to add another level of directories to the hierarchy so that these logs are further categorised by the name of the originating host. Fortunately the syslog-ng daemon provides macros called $HOST, which is expanded to the short host name, and $FULLHOST, which is expanded to the fully qualified domain name, which can be used for exactly this purpose.
The example below shows how the $HOST macro can be used to store logs in a directory structure based on the name of the remote log host as well as the date of the log entry.
destination d_mailerr { file("/var/log/remote/$HOST/mail/$DATE/error.log"); };
Earlier in this chapter we briefly mentioned that there were some security implications attached to assuming the veracity of any information we receive from a remote log host. For that reason the syslog-ng daemon provides an additional set of macros which can be used to prevent this kind of attack.
When working with dates and times these macros have the same name as normal simply prefixed with R_ and result in the current time of the log server being used at the moment of receipt. If you wish to force syslog-ng to use the time contained in the log message then you can use the macros prefixed with S_ instead.
The example below shows how the previous example could be rewritten using these macros to ensure that the correct time is used when rotating the files.
destination d_mailerr { file("/var/log/remote/$HOST/mail/$R_DATE/error.log"); };
When we work with host names we also have to take care that they only contain values which we expect. The most effective method of achieving this is to use the use_dns option which we examined earlier. This will cause a reverse DNS lookup to be performed for every log message which is received and the result of that lookup to be used as the $HOST and $FULLHOST variables. You can obtain the host name that was sent by the log client by using the $HOST_FROM and $FULLHOST_FROM macros.