Sudo: sudo -iu without password

Configure sudo, TL/DR

We had a customer case where we would like to switch to a different user without typing in a password (ssh key login, no password available for the executing user).

sudo -iu other_user

We wanted to do that without allowing the user to do much else. It was not really easy to figure out how to configure sudo.

Do this: Add the following to the sudoers file:

my_user ALL:(other_user): NOPASSWD: /bin/bash

Dont do this: One way to do it, is to add the following sudoers config:

my_user ALL:(other_user): NOPASSWD: ALL

This is effectively the same thing as allowing my_user to run a shell, as I am basically allowing my_user to switch to a shell for other_user. In principle, this might even be the best solution, as one should not encourage working in a shell as other_user. Everything you would like to do as other_user can be done with sudo commands:

sudo -i -u other_user ls -la

# or

sudo -u other_user ls -la

Getting used to prefix your commands with sudo -u other_user helps a lot when you need to know “who did what” at a later point by looking through log files.

Long rant about sudo and ways to run shells

The configuration of sudo can be done in either the /etc/sudoers file, or in any file in the /etc/sudoers.d directory.

There is a major difference in switching to a different user in different ways:

  • sudo su
  • sudo su -
  • sudo su -s /bin/bash - nagios
  • sudo -iu other_user
  • sudo -u other_user /bin/bash

There is a long discussion to be done on which way is the best way, but the short answer is:

  • Use: sudo -iu other_user

Examples:

#--- run /bin/bash in a login shell as ops
sudo -iu ops

#--- run /bin/bash in a login shell as root
sudo -i

Amongst other reasons (as in getting a proper user environment in the shell), you benefit from the following:

  • You get the SUDO_* variables set by sudo
admin.mlue@com-graylog-l01:~$ sudo -iu ubuntu
ubuntu@com-graylog-l01:~$ env | grep SUDO
SUDO_GID=1103
SUDO_COMMAND=/bin/bash
SUDO_USER=admin.mlue
SUDO_UID=1103

These environment variables can of course be overwritten, but they are very useful for logging.

We are getting a bit away from the topic, though.

What does sudo sound like?

When you run sudo -i it will look into the target user’s shell field in /etc/passwd (or other user mechanism). Many users use /bin/bash as their shell. sudo will then start this shell as a “login shell”, which reads in your “dot files” like .bash_profile.

This is why the construct with /bin/bash works.

my_user ALL:(other_user): NOPASSWD: /bin/bash

If you run /bin/bash with sudo -iu other_user, sudo will ensure that you get the proper environment set. If you run /bin/bash with sudo -u other_user /bin/bash it will not be started as a login shell, and you will just “be” other_user, but the whole environment is untouched. Your HOME variable will still point to your own home directory, not the other_user home directory.

Conclusion

There are many ways to skin this cat. For us, it was hard to find a good explanation why /bin/bash was the command to allow in the sudoers file to get sudo -iu other_user to work.

References: