Why is everyone using sudo wrong? Or is it me?

While configuring OMD (yes, Orchestral Manoeuvers in the Dark, no, not really) I ran into a point at which apache was supposed to run as the OMD user for check_mk. Hard coded into the check_mk configuration is a call to

sudo su - <omduser> check_mk -c check_mk\ --automation\ *

I've seen this many times, sysadmins doing sudo su -, but why? It reminds me of an admin who would routinely do cat file | less, or my favourite cat file | grep something | wc -l when grep -c something file would be just about as nice. The other problem I have with getting su in the middle is that you could have much cleaner sudoer files. I might be in a minority of opinion though, the man page for sudo has examples with su in them, why, I don't know.

In the above code we are saying, sudo to root, run su as root, then tell su to drop to a specific user and run a command given with -c, we could have just as easily said:

apache ALL=(omduser) NOPASSWD:SETENV: ALL

Then changed the command run to this:
sudo -u omduser check_mk --automation --

This is fundamentally different, We aren't asking to run anything as root, we drop privs much sooner in the game and become the omduser to run the command instead of running su as root and relying on su to drop privs. Not only that, we have just allowed the apache user to run anything as omduser, so if we need to run some other omd command later, it's already covered. We should lock it down true, but I would feel a lot better about a wildcard in that last sudoers, the absolute worst case would be that apache could run an arbitrary command as omduser.

sudo su - I know I've typed it, but it's just wrong, I should be doing

sudo -i

It must be correct, it has less characters in it.

So I started looking and I couldn't find a best practices doc for using sudo. Until I find it, I thought I would start something here from what limited experience I have. I present my version of...

Best practices for sudo

  • Always edit sudoers with visudo
  • If your sudo supports sudoers.d, use it.
  • If UserA needs to run commands as UserB, use the Runas_Spec to allow UserA to run as UserB

     UserA ALL = (UserB) ALL
  • Use wildcards sparingly and only in arguments

    UserA ALL = (ALL) /opt/vendor/version-*/bin/something
    UserA ALL = (ALL) /opt/vendor/version-11.0.1/bin/something *

    The first rule is more dangerous than the second, the command
    sudo /opt/vendor/version-11.0.1/../../../usr/bin/vim

    Matches the wildcard and permits UserA to run vim as root. The second rule allows UserA to run /opt/vendora/version-11.0.1/bin/something with any arbitrary arguments, so provided we trust that the command 'something' doesn't have any shell escapes, we should be ok.
  • Only allow the use of sudoedit for editing files. Most editors provide shell escapes. If you permit a user to run vim for instance, they can execute any command using :!
  • Only allow users to run commands as root in paths in which they do not have write access. If UserA can edit '/opt/vendora/version-11.0.1/bin/something', then UserA cannot be allowed to execute 'something' as root.
  • If any user is allowed root access, then no other user should be allowed open access to that user. This is known as user hopping.
    UserB ALL = (UserA) NOPASSWD: ALL

    UserB can run any command as UserA, but UserA can run any command as root. So to get a root shell, all UserB has to do is sudo -u userA sudo bash
    UserB@host ~ $ sudo -u UserA sudo bash
    root@host /home/UserB $
  • Never forget that Runas_spec has a group component...
    UserA ALL = (:wheel) NOPASSWD: ALL

    root@host /etc/sudoers.d $ sudo -iu UserA
    UserA@host ~ $ touch hello
    UserA@host ~ $ sudo -g wheel touch there
    UserA@host ~ $ ls -l hello there
    -rw-rw-r--. 1 UserA UserA 0 Jan 28 22:35 hello
    -rw-r--r--. 1 UserA wheel 0 Jan 28 22:35 there
  • Teach your users to use sudo -l

I bet this is written down somewhere famous though...

Other run things I noticed...useradd UserA creates UserA, not usera, it's a distinctly different user...rabbithole approaching...

root@host $ id usera
id: usera: no such user
root@host $ id UserA
uid=1003(UserA) gid=1003(UserA) groups=1003(UserA)

Wordpress category: 


While I do agree with most of what you say, and it is good to keep configurations at a minimum level of required privileges, note that the sudo binary is setuid root, so from the kernel & SELinux perspective, the "correct" way and the "incorrect" way you describe are not really "fundamentally different". We aren't "asking" to run as root, but it happens anyway as a consequence of using the binary. Perhaps why the developers have no qualm with explicitly stating "sudo su -".

one less setuid app in the chain is never a bad thing.

sudo su -
instead of
sudo -i
is mostly a historical artifact, with earlier versions of sudo simply not having a -i option.

Add new comment


  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <blockquote> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.

Filtered HTML

  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <blockquote> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
Refresh Type the characters you see in this picture. Type the characters you see in the picture; if you can't read them, submit the form and a new image will be generated. Not case sensitive.  Switch to audio verification.