Various security measures apply to logging.
Each service generally has its own dedicated logging service, writing to its own dedicated logging area. (A few services, usually a group of strongly related or tightly coupled ones, share a single dedicated logging service among them.)
High volume services cannot swamp the log outputs of low volume services. One technique used by the nefarious to hide their tracks is to flood the system log so that logs of their subversion attempts are rotated off the top of the log. This is not possible with entirely separate log directories.
Log rotation settings are per logging service, and individually adjustable with that service's flags
service variable.
There is no fan-in and fan-back-out. The path between a service and its logs is direct. It does not cross that of other services' logs. Nor are log messages (which contain data supplied from the network or potentially untrustworthy users) parsed in order to determine a sorting bin to put them into. All log data are already sorted by dint of originating from an individual service, or small group, and go directly into a sorting bin dedicated to it.
There is no central point of failure.
There's no single central logging service that, if taken down, effectively takes down the rest of the system; and that when brought up requires most of the rest of the services to restart in order to reconnect to it.
Take down, say, the cyclog@cron
service and at most that backs up the log output of the cron
service in a kernel buffer for the pipe that connects the twain.
The pipe is kept open at both ends by the service manager, and when cylog@cron
is brought back up it is automatically reconnected to the output of the cron
service, with the latter not having to restart or being any the wiser that its log service was temporarily down.
All logging service bundles have a dedicated user account associated with them. These accounts are created by installing the "bundles" package. (They are not destroyed by deinstalling that package; because deinstallation, being possibly a prelude to reinstallation, does not remove log files.)
This account is unprivileged. Only the system-manager's own log dæmon runs as the superuser (because the user account database may be corrupt or nonexistent that early in the bootstrap process, and it is necessary that the system-manager's own log always be capable of running).
It owns only the log files in its service's log directory and their lock file. Importantly, it does not own the service's log directory itself, and so even if the log service is somehow subverted, the logger dæmon has no rights to grant other users access to the log directory. Rather, each dedicated logging service is given just create, delete, and search access to the log subdirectory by ACL entries on that subdirectory.
The service's log directory is always owned by the superuser, and only the dedicated log user account has create and delete access there. Unprivileged users cannot, say, write mischeivous symbolic links into the directory so that the unwitting log service ends up overwriting some other file(s) somewhere else.
Only the log service process runs under the aegis of that account. This protects it, using the normal kernel mechanisms, from other log service dæmon processes. If the "main" service also runs under the aegis of an unprivileged account, it also protects it from the "main" service's dæmon process(es). This means that if the main dæmon is subverted, it cannot affect its logger dæmon. Nor can it directly manipulate any of its own log files (although it can still of course flood them).
Logging services cannot eat into the disc space that is reserved to the superuser for emergencies.
This applies to cyclog
and to many of the alternatives one can use in place of it.
Because the program writing the log files is the same program that does the log rotation, it knows exactly when to perform rotation. There are no windows of opportunity to fill the log storage volume up before the next scheduled rotation, as in older architectures. Rotations are not scheduled, at all; they are triggered by the writer knowing that it would otherwise be about to exceed a size limit. The size caps on log files and on total log directory size are reliable. One can budget space on a log storage disc, by totalling up maximum configured log sizes, with confidence.
Nor does log rotation trigger one of the well known problems with GNU tail
and BSD tail
.
(If a log file is truncated and then quickly written to, neither tail
will output all log data.)
The log file writer never truncates, or indeed modifies, log files once it has written them up to the size limit.
Rather, it switches in a new file, with a fresh i-node.
Indeed, log files are only ever written to in strictly sequential, append-only, fashion. These behaviours can be relied upon if one wants to place log directories on storage devices that don't like it when one overrwites the same file(s) in place over and over.
(GNU tail
and BSD tail
have more than one problem, though.
For avoiding the other problems, one has to use something like follow-log-directories
which actually knows that it is looking at a log directory, rather than only knowing to look at a single file.)
Services that provide compatibility with the old "syslog" mechanism comprise a "main" log reading service and a "log" writer service, and posess several security measures.
The various services, for kernel log output, local "syslog" socket, local "privileged syslog" socket, and remote "syslog" via UDP, are all independent of one another. The services themselves are independent, as are their log streams. It is not possible for a remote client to flood the local logs, or vice versa. It is not possible for remote log data to masquerade as local data.
The log reading services themselves run as dedicated unprivileged users. They don't need superuser permissions at any point, don't parse client-supplied content (trusted or otherwise), and don't require ownership of or read/write access to any files or directories. The only things that they should write are their standard outputs to the connected log writing services; and the only things apart from that that they can write are publicly writable anyway.
Should the log reading services be compromised, which is hard(er) given the elimination of parsing, the attacker doesn't gain superuser privileges, or any ownership of or access to any (non-world-accessible) filesystem object.
The log reading services have fixed-size input buffers, and do not rely upon attacker-supplied length fields of any kind. They are not subject to attacks where clients specify over-large message sizes.
The log writing services run as different dedicated users, and are insulated from the log readers. They, too, do no parsing or conditional processing that depends from potentially attacker-supplied data.
cyclog
and many of the alternatives one can use in place of it are immune to malformed character encodings, control characters, and NUL
s.
There are some problems that are, however, inherent in the nature of log services that listen to the world, or even locally, receiving all messages sent to a particular socket endpoint to which multiple clients can connect.
The kernel provides no defences against forged messages being sent through the kernel logging mechanism, and has a mechanism whereby applications softwares can introduce messages into the kernel log stream.
There are no defences against flooding within a given transport mode.
A remote attacker can flood other remote log data; an unprivileged local attacker can flood other unprivileged local log data; and a privileged local attacker (i.e. one with access to the logpriv
socket) can flood other privileged local log data.
There is no client authentication in the UDP RSYSLOG transport. Whilst there could be client authentication in the local socket transports, this is not the norm nor what such clients expect.