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 -
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
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
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.
UserA ALL = (ALL) NOPASSWD: ALL
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)