I think it is expected to work this way, sometimes it is quite useful to post log messages from a script. It was certainly not intended for users to pollute the system logs. The solution in my opinion is having a well configured logging system, which will prevent users from polluting the logs, or faking system messages, allowing you to identify users who are in the habit of doing so.
I use rsyslogd
, so I'm using that for examples.
First of all, you need to configure rsyslogd
to store certain variables from the socket it opens:
module (load="imuxsock"
SysSock.Annotate="on"
SysSock.ParseTrusted="on"
)
With this, you can access the following variables:
pid
: the PID of the logging process.
uid
and gid
: the UID and GID the logging process runs as.
appname
: the name of the logging process
cmd
: the full command line of the logging process
In the case of logger
, pid
will be the PID of systemd-journald
, and appname
will always be systemd-journal
.
With these, you can do a few things:
Simply log these
You can use a template which includes these variables, so you can see if there is a discrepancy between the message and the obtained parameters. In a template, you can access these variables like %$!pid%
. So for example, of you use a template like this:
$template SomeLogFormat,"%TIMESTAMP:::date-rfc3339% <%pri-text%> %syslogtag%%msg% (logged by pid=%$!pid% running as %$!uid%)\n"
daemon.* /var/log/daemon.log;SomeLogFormat
will yield the following entry:
2021-10-27T18:27:54.638759+02:00 <daemon.info> sshd[986]: Accepted publickey from 127.0.0.19.8 port 65537 sha2: RSA 2e:45:25:54:6o:34:3a:z3:55:07:04 (just a fake) (logged by pid=540 running as 1000)
From it, you can see if the message is legit, and if not, you get the UID of the user who is in a funny mood. Note that instead of supplying the parameters one by one, you can use the %$!%
template, which will log the above values in JSON format.
Reroute user logs
You can place logs written by users to a separate file (perhaps on a separate file system, so that users can't fill the root filesystem). You can reroute all logs originating from users with the following config:
if $!uid > 999 then /opt/log/user.log;SomeLogFormat
& stop
The usage of the template (the ;SomeLogFormat
part) is optional. This way, everything originating from anything with an UID of 1000+ will be written to /opt/log/user.log
. You can even separate the user logs by UID like this:
$template userLogFile,"/opt/log/userlog_%$!uid%.log"
if $!uid > 999 then ?userLogFile;SomeLogFormat
& stop
This way, every user will have their own userlog_xxxx.log
file.