10

I am setting up Nagios on some of my Linux servers and have run into a bit of an issue. The check_ide_smart plugin requires root access to the system to run. To run it, I use the check_by_ssh plugin to ssh into the nagios account on the remote host, then run check_ide_smart using sudo.

I initially added the following lines to /etc/sudoers to allow the program to work:

nagios  ALL=NOPASSWD: /usr/lib/nagios/plugins/check_ide_smart

While this worked just fine when run locally, I was getting an issue when it was run from Nagios: no TTY was being spawned, which prevented the plugin from working.

I dug in the man page for sudo and found the -s option, which spawns a shell and executes the program in there. When I tried using sudo -s, I ran into permission issues since the -s apparently changes the command into /bin/bash -c /usr/lib/nagios/plugins/check_ide_smart, which is not allowed by the sudoers file. I tried changing the sudoers file to use that command instead, but that didn't work, and using quotation marks is a syntax error.

I eventually got it to work by using the following line in /etc/sudoers:

nagios ALL=/bin/bash

This feels really wrong to me since I'm allowing the nagios user to spawn a root shell, with which they can do anything.

At this point, I though that maybe, by putting the command in a shell script that the nagios user has read-only privileges on would work, so I created a shell script:

#!/bin/sh
/bin/bash -c /usr/lib/nagios/plugins/check_ide_plugin $@

Unfortunately, I could never get the passed parameters ($@) to correctly work with the plugin, so I don't know if this would work. Edit: I needed to quote the $@ for it to work. Thanks @derobert and @pjz. I still don't know if it would work since I got it to work using @Mike Arthur's solution.

Is there a way that I can get sudo -s to work while not allowing the spawning of a root shell?

Answer:

Added the following line to /etc/sudoers:

nagios ALL=NOPASSWD: /bin/bash -c /usr/lib/nagios/plugins/check_ide_smart *

Note the trailing asterisk; without it, this does not work. Thanks @Mike McQuaid for the answer.

Mike McQuaid
  • 315
  • 2
  • 7
Chris Lieb
  • 315
  • 5
  • 10
  • WARNING: the accepted solution allows arbitrary code execution as root. It actually allows the `nagios` user run **any command**, because of the use of `bash -c` combined with the utterly broken way that `sudo` matches `*` (the whole line is compared as if the arguments have been catenated into one string, losing critical distinctions like whether or not something was one argument with spaces or multiple arguments): the sudoers entry of `/usr/bin/bash -c safe-command *` will also allow `/usr/bin/bash -c 'safe-command ; echo pwned'`. – mtraceur Jul 28 '23 at 03:56

5 Answers5

7

nagios ALL=NOPASSWD: /bin/bash -c /usr/lib/nagios/plugins/check_ide_smart *

This should work and allow arguments.

Mike McQuaid
  • 315
  • 2
  • 7
  • That didn't work. See my edit for details. – Chris Lieb May 07 '09 at 15:51
  • @Chris Lieb: you'll have to change your call from "sudo -s ..." to "sudo /bin/bash -c ...". Then it should work. I have a similar setup working here (not nagios, but similar). – Martin C. May 07 '09 at 15:58
  • I've fixed it, try it now (with the asterisk for wildcards). – Mike McQuaid May 07 '09 at 16:14
  • Pretty sure this opens up an arbitrary execution (as root) vulnerability - same as if you just allowed running any root commands without password, but now it looks+feels deceptively like it's actually secure, thanks to `sudo`'s utterly braindead implementation of `*` in `sudoers` matching (and of course thanks to using `bash`). `sudo` matches on *the whole command as one string*, so for example, this rule will allow `sudo /bin/bash -c '/usr/lib/nagious/plugins/check_ide_smark ; echo pwned'`. – mtraceur Jul 27 '23 at 18:48
  • The safe but inconvenient rule would be to just drop the `bash -c` from the line: `nagios ALL=NOPASSWD: /usr/lib/nagios/plugins/check_ide_smart *`. We can make this convenient by (for example) symlinking `/usr/lib/nagios/plugins/check_ide_smart` into `/usr/local/sbin`. – mtraceur Jul 27 '23 at 18:59
  • Yeah, WARNING, this opens up arbitrary execution as root. (Sorry but I have to -1 this because of that. It's not your fault, it's the fault of whoever designed `sudo`'s `*` match to smudge arguments together, which is intrinsically unfit-for-purpose precisely because it non-obviously turns the intuitive way of saying "allow all arguments" into "allow any arguments which, when joined with spaces into one string, match this prefix", which is a difference which allows anything up to arbitrary code execution depending on what the allowed command is.) – mtraceur Jul 27 '23 at 19:15
3

Instead of using sudo -s and launching a root shell, just allow your nagios user to use sudo without a tty using !requiretty. Your /etc/sudoers should have the following:

# Allow Nagios extra privs
Defaults:nagios !requiretty
nagios ALL=NOPASSWD: /usr/lib/nagios/plugins/check_ide_plugin

... which will allow direct sudo access, without a password, and without a tty. You can leave the "check_ide_plugin" off if you want sudo access to all the plugins.

We also use NRPE, which seems a little safer than check_by_ssh, but it requires a little more setup. Same idea in /etc/sudoers tho, just swap nagios with nrpe. :)

~tommy

TommyTheKid
  • 166
  • 9
3

FYI, you need to quote $@ in your shell script for it to work right:

#!/bin/sh
/bin/bash -c /usr/lib/nagios/plugins/check_ide_plugin "$@"

$@ is magic. From the bash manpage,

@ Expands to the positional parameters, starting from one. When the expansion occurs within double quotes, each parameter expands to a separate word. That is, "$@" is equivalent to "$1" "$2" ... If the double-quoted expansion occurs within a word, the expansion of the first parameter is joined with the beginning part of the original word, and the expansion of the last parameter is joined with the last part of the original word. When there are no positional parameters, "$@" and $@ expand to nothing (i.e., they are removed).

Also, starting bash won't spawn a pty; though I'm perplexed as to why your nagios plugin needs a terminal to run. It shouldn't. Maybe the actual problem is sudo's environment sanitization?

derobert
  • 1,308
  • 12
  • 22
  • This plugin is the only one that has caused any problems. None of the others that I have set up so far require root access, so I didn't need to use sudo for them. Because of this, I am not sure if the problem is caused by sudo not spawning a shell or by the check_ide_smart plugin requiring a shell to run. – Chris Lieb May 07 '09 at 17:08
1

Try the script again but put doublequotes around your $@:

#!/bin/sh
/bin/bash -c /usr/lib/nagios/plugins/check_ide_plugin "$@"
pjz
  • 10,595
  • 1
  • 32
  • 40
-1

I don't think it's possible to use -s without spawning a root shell (assuming you need root privileges). The -s option is specifically there to spawn a shell. That's what -s means. From sudo(8):

-s [command]
    The -s (shell) option runs the shell specified by the SHELL
    environment variable if it is set or the shell as specified
    in passwd(5).  If a command is specified, it is passed to
    the shell for execution.  Otherwise, an interactive shell
    is executed.
Christopher Cashell
  • 9,128
  • 2
  • 32
  • 44
  • 1
    A shell is executed, but his current is to allow any call to `/bin/bash`, which also allows the spawning of an interactive shell without any limitations and without any restrictions on what commands can be called. – Martin C. May 07 '09 at 16:21