25

I am using Zabbix for monitoring my environment and zabbix_agentd executes as user zabbix one custom script every 60 seconds; it uses sudo to run this script as root.

In /var/log/auth.log I see every 60 seconds:

Aug 11 17:40:32 my-server sudo: pam_unix(sudo:session): session opened for user root by (uid=0)
Aug 11 17:40:32 my-server sudo: pam_unix(sudo:session): session closed for user root

I want to stop this message from flooding my log. I added the following line to /etc/pam.d/sudo file, immediately before session required pam_unix.so:

session [success=1 default=ignore] pam_succeed_if.so service in sudo quiet uid = 0

and the message disappeared.

But the problem is that this way I have suppressed every PAM message when someone is executing a script with sudo as root.

I want to stop the message only for user zabbix (not all other users). sudo knows that zabbix user wants to execute the script with root privileges and is there any way to tell PAM that? How can I tell PAM not to log for a specific user when using sudo?

Note: I tried filtering the messages in syslog; although this works, it has the same problem as the above, namely that it is too indiscriminate, as the log message does not indicate which user is becoming root.

Toby Speight
  • 8,678
  • It supports filtering and with filtering it works. I tried that but I do not like it, because filtering is not a universal way. One day some character in the message will change or something will change and my filter will fail. I am searching for a solution with configuration parameter, directive or something similar to be sure that this will be stopped in all cases. And the message says session closed for user root and if I filter it in fact I am filtering all messages. I want for a specific user who is not mentioned in the message and I cannot filter by its name... –  Aug 20 '15 at 14:22

5 Answers5

16

You seem pretty close with your PAM conf line:

session [success=1 default=ignore] pam_succeed_if.so service in sudo quiet uid = 0

Looking at the manual page for pam_succeed_if, I think you want to test that the requesting user (ruser) is zabbix.

So I suggest:

session [success=1 default=ignore] pam_succeed_if.so quiet uid = 0 ruser = zabbix

That will suppress the next test when user zabbix becomes root (but no other transitions). I've tested this with a pair of my own users.

Remove the uid = 0 test in the above if you want to keep quiet about zabbix becoming any user, rather than just root.

I removed the service in sudo test: it's redundant given that this line is in /etc/pam.d/sudo.

Toby Speight
  • 8,678
  • 1
    Thank you! That is what I am looking for. Perfect! And thanks for the suggestion to remove service in sudo. –  Aug 20 '15 at 15:09
  • 1
    If you also want to remove the [user] : TTY=unknown ; PWD=... ; USER=root ; COMMAND=... line from the log as well, you can add this to a sudoers.d/ file: Defaults:[user] !logfile, !syslog (replace [user] where appropriate) – thom_nic Apr 17 '18 at 16:51
  • @thom_nic What is the path to that file? – not2qubit May 11 '18 at 08:45
  • Any file under /etc/sudoers.d/ - I prefer to use the name of the user, group or application to which this applies. See https://www.sudo.ws/man/1.8.15/sudoers.man.html – thom_nic May 11 '18 at 13:16
  • @thom_nic Could you please post this as an answer a bit more expanded? I don't see the format you propose above. In addition I don't think there is a : in there. And are the logfiles explicit or something that should be replaced? – not2qubit May 11 '18 at 15:21
  • This worked for me after changing success=1 to success=done. success=1 is nowhere to be found in man pam.d – MarcH Jul 05 '21 at 00:51
  • 1
    @MarchH, those are completely different actions. success=1 skips only the next test (the pam_unix.so one), whereas success=done will skip all the following tests. On Debian, man pam.d says "The action can take one of the following forms:" ⋯ "done: equivalent to ok with the side effect of terminating the module stack and PAM immediately returning to the application." ⋯ "N (an unsigned integer): jump over the next N modules in the stack.". – Toby Speight Jul 05 '21 at 06:36
9

Based on Toby's answer, I found a way to configure this in a slightly different way on Debian/Ubuntu. For context, see:

So Debian/Ubuntu have this pam-auth-update command and when you look at /etc/pam.d/sudo it looks like this:

#%PAM-1.0

@include common-auth
@include common-account
@include common-session-noninteractive

and /etc/pam.d/common-session-noninteractive looks like this:

#
# /etc/pam.d/common-session-noninteractive - session-related modules
# common to all non-interactive services
#
# This file is included from other service-specific PAM config files,
# and should contain a list of modules that define tasks to be performed
# at the start and end of all non-interactive sessions.
#
# As of pam 1.0.1-6, this file is managed by pam-auth-update by default.
# To take advantage of this, it is recommended that you configure any
# local modules either before or after the default block, and use
# pam-auth-update to manage selection of other modules.  See
# pam-auth-update(8) for details.

# here are the per-package modules (the "Primary" block)
session [default=1]         pam_permit.so
# here's the fallback if no module succeeds
session requisite           pam_deny.so
# prime the stack with a positive return value if there isn't one already;
# this avoids us returning an error just because nothing sets a success code
# since the modules above will each just jump around
session required            pam_permit.so
# and here are more per-package modules (the "Additional" block)
session required    pam_unix.so
# end of pam-auth-update config

So sure, I could edit either of the above files but clearly there's some "higher power" at work here. How to get my changes to play nice with other packages that might want to add pam rules? To top it off, it seemed I couldn't just add a line in /etc/pam.d/sudo in between the two @includes like this..

##### THIS DIDN'T WORK :( ######
@include common-auth
@include common-account
session [default=ignore] pam_succeed_if.so quiet_success service = sudo uid = 0 ruser = myappuser
@include common-session-noninteractive

After reading the above links as well as other examples (see /usr/share/pam-configs/unix) I came up with this, in /usr/share/pam-configs/myapp:

# Don't log "session opened" messages for myapp user
# See: https://wiki.ubuntu.com/PAMConfigFrameworkSpec
#      https://manpages.debian.org/stretch/libpam-modules/pam_succeed_if.8.en.html
Name: myapp disable session logging
Default: yes
Priority: 300
Session-Type: Additional
Session:
    [default=ignore] pam_succeed_if.so quiet_success service = sudo uid = 0 ruser = myappuser

Session and Session-Type control which files are edited and Priority defines what order they go in. After adding that file and running pam-auth-update, /etc/pam.d/common-session-noninteractive looks like this (at the bottom:)

#... omitted
session required            pam_permit.so
# and here are more per-package modules (the "Additional" block)
session [default=ignore] pam_succeed_if.so quiet_success service = sudo uid = 0 ruser = myappuser
session required pam_unix.so 
# end of pam-auth-update config

... which is what we want because our pam_succeed_if line needs to come before session required pam_unix.so. (That line comes from /use/share/pam-configs/unix and has a Priority: 256 so it ends up second.) Note also that I left the service = sudo predicate since common-session-noninteractive might also be included in other configs besides sudo.

In my case, I had already packaged my code as a .deb installer so I added the /usr/share/pam-configs/myapp file, and added pam-auth-update --package to my postinst and prerm scripts and I'm good to go!

Caveat...

If you read the PAMConfigFrameworkSpec article that I linked above, it defines a Session-Interactive-Only option, but does not have a way to specify only noninteractive rules. So /etc/pam.d/common-session was also updated. I don't think there's a way around this. If you're ok with interactive sessions not being logged for that user (it IS a service account, right?) then you should be all set!

Bonus: how to also remove sudo log output

In addition to the session openened|closed lines that PAM emits, sudo logs additional information about the command that's run. It looks like this:

[user] : TTY=unknown ; PWD=... ; USER=root ; COMMAND=...

If you also want to remove that, open this link then continue below...

So... you're probably familiar with typical /etc/sudoers.d/___ setup which might do something like this for a service account which needs superuser privs for a some actions:

myuser ALL=(ALL) NOPASSWD: /bin/ping

that might go in /etc/sudoers.d/10_myuser. Well, among other things you can also specify Defaults. Note specifically this syntax 'Defaults' ':' User_List

Now, look at the SUDOERS OPTIONS section. Interesting bits include log_input, log_output but (probably) more importantly, syslog and logfile. It appears to me that in recent versions of Debian, either rsyslog or sudo log to stdout or stderr by default. So for me this was showing up in the journald log for my service, and not e.g. /var/log/auth.log where it wouldn't get mixed into my application logs. To remove the sudo logging, I added the following to /etc/sudoers.d/10_myuser so it looks like:

Defaults:myuser !logfile, !syslog
myuser ALL=(ALL) NOPASSWD: /bin/ping

YMMV, if you feel disabling logging creates issues with security audits you might also try to solve this via rsyslog filters.

thom_nic
  • 547
  • 2
    The way you implemented the "session opened/closed" stuff didn't work for me. There are two reasons: (1) You didn't specify to use success=1, (which skips the next clause), and (2) Because how you specified service = sudo, any running CRON jobs, results in requirement "service = sudo" not met by user "root". (And possibly other side effects.) However, your Bonus stuff worked great! Thank you. – not2qubit May 12 '18 at 07:09
  • How does your postinst and prerm scripts look? – not2qubit May 12 '18 at 08:54
  • 1
    @not2qubit re: success=1 - I'd rather not skip pam_unix altogether. I only want to stop logging the output which [default=ignore] seems to achieve just fine without skipping pam_unix. – thom_nic May 14 '18 at 13:47
  • re: cron jobs and service = sudo: Is it possible that your cron jobs are running as an unpriv user, but you're not calling sudo as part of the cron jobs? – thom_nic May 14 '18 at 13:54
  • 1
    You probably want !log_allowed instead of the broader that !syslog that hides security incidents. – MarcH Jul 05 '21 at 00:38
4

After quite a bit of scary testing and research, I have found a working solution for the Debian Stretch (on Raspberry). There are surely more than one way to accomplish what OP ask for. But the PAM documentation is overwhelming, so most stuff is really TL;DR.

  1. You can add a custom string filter for rsyslog in: /etc/rsyslog.d/anyname.conf by using:
    :msg, contains, "session opened for user root by pi" stop
  2. You can directly edit /etc/pam.d/sudo
  3. You can do it the right way by creating a custom PAM config file in: /usr/share/pam-configs/
  4. You can do some by creating a custom sudoers file in: /etc/sudoers.d/020_pi

I'll show you how to do (2) and (4).

WARNING

Do not edit any files in /etc/pam.d/ without first changing their world write permissions. If you do not, and make a mistake, you can get locked out of any future use of sudo/su! So make sure you have tested the new settings before you change it back. (Default is 644)


To get rid of "session open/close":

We want to get rid of the following /var/log/auth.log spam:

May 10 11:28:03 xxx sudo[26437]: pam_unix(sudo:session): session opened for user root by (uid=0)
May 10 11:28:07 xxx sudo[26437]: pam_unix(sudo:session): session closed for user root

Do this:

# sudo chmod 666 /etc/pam.d/sudo
# sudo cat /etc/pam.d/sudo

#%PAM-1.0

@include common-auth
@include common-account
session [success=1 default=ignore] pam_succeed_if.so quiet_success uid = 0 ruser = pi
@include common-session-noninteractive

What is of crucial importance here, is that success=1, means to skip the next 1 clause (or in PAM lingo "jump over the next module in the stack"), if successful.

From man pam.conf:

ignore - when used with a stack of modules, the module's return status will not contribute to the return code the application obtains.

done - equivalent to ok with the side effect of terminating the module stack and PAM immediately returning to the application.

N - equivalent to ok with the side effect of jumping over the next N modules in the stack.

Next, reboot and let it run a few hours (to check cron jobs for example) to test that this works. Then make sure to re-instate the file permissions, otherwise you'll have a gaping security hole in your system. (sudo chmod 644 /etc/pam.d/sudo)


To get rid of repeated "TTY PWD COMMAND" messages:

We also want to get rid of messages like this:

May 11 18:23:20 xxx sudo:       pi : TTY=unknown ; PWD=... ; USER=root ; COMMAND=/usr/bin/arp-scan -q -l

In my case, this was generated by an IDS script that was running arp-scan every few minutes. To remove it from showing up in the logs, create the following file:

# sudo nano /etc/sudoers.d/020_pi
# sudo cat /etc/sudoers.d/020_pi

Defaults:pi     !logfile, !syslog
pi xxx = (root) NOPASSWD: /usr/bin/arp-scan

(Here xxx is your machine name, and pi is the username.)

not2qubit
  • 1,666
  • 1

    Do not edit any files in /etc/pam.d/ without first changing their world write permissions....

    Highly suggest running another terminal session as root instead e.g. sudo su - Then you don't have to set dangerous permissions and risk forgetting to change it back.

    – thom_nic May 15 '18 at 12:55
  • @thom_nic Have you tested this? My guess is that if you accidentally block sudo/su usage in PAM, then no matter what you do, will produce an error, even in a root shell. If it is not, then PAM is probably not working as it should. – not2qubit May 16 '18 at 15:49
0

Log in as root, edit the file /etc/pam.d/sudo and add

session [success=1 default=ignore] pam_succeed_if.so quiet uid = 0 ruser = alice

where alice is your username. This will prevent session open and close logs.

To prevent logging of commands, edit /etc/sudoers and add

Defaults:alice     !logfile, !syslog

just above this line alice ALL:(ALL) :ALL.

αғsнιη
  • 41,407
Sharky
  • 1
-2

You will get:

pam_succeed_if(sudo:session): unknown attribute "ruser"

with your answer.

#%PAM-1.0

@include common-auth
@include common-account
@include common-session-noninteractive
session     [success=1 default=ignore] pam_succeed_if.so service in zabbix quiet use_uid
session     [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid

works but you will still get a :

pam_unix(sudo:session): session opened for user root by (uid=0)

in your logs.

golfdq
  • 1