Linux – SUDO NOPASSWD not working on a specific command

linuxpermissionssudo

I have a tricky situation.
I need a user nagios to execute a specific command as another user jenkins — However this command only works if the jenkins environment is fully loaded. Otherwise the command I'm running won't work, so I need to do a su - user type command.

Command works fine when ran from root:

/bin/su - -c "pm2 show proxy" jenkins

(I get the expected output)

When ran from nagios user:

nagios@srv01:~$ sudo /bin/su -c "pm2 show proxy" jenkins
[sudo] password for nagios:

visudo entries I've tried:

nagios  ALL=(root) NOPASSWD: /bin/su - -c "pm2 show proxy" jenkins

nagios  ALL=(jenkins) NOPASSWD: /bin/su - -c "pm2 show proxy" jenkins

Neither of the above work, it still asks for password.

IT WORKS if I simply grant nagios user full su permissions:

nagios ALL=(root) NOPASSWD: /bin/su

^^ this works, but NO, not granting full su permissions to this user.

Since it works when globally allowing su I'm assuming it's somewhere in my syntax.

Edit – In order to get around this issue I just put the command I want to run in a script and granted sudo to the script. However this is not ideal and adds an extra step in this workflow. Would much rather be able to run the command directly with sudo.

Best Answer

If you need the login environment for jenkins then try to use the -i switch to sudo

-i [command] The -i (simulate initial login) option runs the shell specified by the password database entry of the target user as a login shell. This means that login-specific resource files such as .profile or .login will be read by the shell. If a command is specified, it is passed to the shell for execution via the shell's -c option. If no command is specified, an interactive shell is executed. sudo attempts to change to that user's home directory before running the shell. The security policy shall initialize the environment to a minimal set of variables, similar to what is present when a user logs in. The Command Environment section in the sudoers(5) manual documents how the -i option affects the environment in which a command is run when the sudoers policy is in use.

So something like

sudo -u jenkins -i pm2 show proxy

Should do what you want.