Introduction

This document outlines some of the things that you can do to make your life easier when needing to perform tasks as user root while still logged in as your normal self. Doubtless many people are su'ing to root to perform tasks. That's fine for single commands, but there are other means, which this article will look at. You may well be wondering why not just log in as user "root" all the time. The answer is simple. Unless one never makes a mistake in typing, and trusts everything running won't ever damage one's computer, then go right ahead.

The focus of this will look at how to add individual users to run programs as root, restricting users to run only certain applications, grouping users so that they can run programs, passwords, etc.

Sudo

"SUperuser DO". Better than su(1) in many respects because it allows a greater control over just what can be run (and by whom), and more importantly how a particular app gets run. Sudo can be setup to allow groups of users to run a subset of applications with root priviliges, or for a single user to run only one application.

Changing visudo's default editor

One should try not to edit sudo's configuration file directly, since sudo relies on locking of that file, and prevents more than one person trying to access it. There's a specific command: visudo. visudo makes sure that you haven't made any syntactical mistakes. By default it will try and launch vi as the default editor. If this is not desireable, you can do:

VISUAL=myeditor visudo

Or if you already have $EDITOR set then it'll use that value instead, and so typing visudo will use whatever EDITOR is set to.

Adding a user without a password to run any program

There, you'll see it is editing a file, which might look like this:

 1. Host alias specification
 1. User alias specification
 1. Cmnd alias specification
 1. User privilege specification
root ALL=(ALL) ALL

... and note the syntax. This says that the root user (via the "sudo" command, remember) has full control over what it can run. Of course, using "sudo" in that manner when one is the root user is superfluous anyway. Although this line is here to satisfy the fact that when one uses sudo, it's being run as effectively the root user, so it is needed.

So let's assume that your normal non-root account is called "david". And let's assume that via sudo, you want to allow that user to run any command as user root without specifying a password each time. This may or may not be a good idea. It depends in what conditions you'll be using sudo. Into that file, you'd add:

david ALL = NOPASSWD: ALL

By default -- unless you tell sudo otherwise, it will prompt for a password. Of course, that entry assumes that you're OK with that. In its effective usage, it's almost as though you were root (I'll leave out the argument about whether or not using this means you should just login as root anyway). Of course, that might not be what you want.

For those of you that want to know how sudo achieves its goal, the sudo command is issued under user "david" in this example, but the command following it is run by changing the EUID (effective user-id) to root.

Adding a user without a password to run selected programs

You can restrict a user (or any number of users) to only run certain applications:

david ALL = NOPASSWD: /usr/sbin/foo, /usr/bin/gvim

(yes, the example programs are somewhat stupid, but they convey the meaning). Here, this says that user "dave" (via sudo) can only run the programs "/usr/bin/foo" and "/usr/bin/gvim" withouth specifying a password.

Specifying specific groups to run applications

But how would you specify that for more than one user? Well, you can also go by which group a particular user is in. "groups" (in the UNIX sense -- read: permissions) are useful where you need to, well, group users together so that they can perform a task. For instance, I have some numbers of users on this box that are allowed to run some commands. I'll call them "usera" and "userb". I could define them in /etc/sudoers thus:

usera ALL = NOPASSWD: /usr/bin/foo, /usr/bin/bar
userb ALL = NOPASSWD: /usr/bin/foo, /usr/bin/bar

But the list would get quite long if I needed it for, say, 500 users. So the way around this, would be to create a group -- say "admins", and add all the users to it. To do that, one would have to run (as root):

 1. groupadd admins

 1. useradd -G admins usera
 1. useradd -G admins userb

If you were on Debian, one would use:

 1. addgroup admins

 1. adduser usera admins
 1. adduser userb admins

(I'll leave automation out as another exercise -- but adding bulk users, en masse to a group is quite easy). Then, going back to our /etc/sudoers file, you can replace:

usera ALL = NOPASSWD: /usr/bin/foo, /usr/bin/bar
userb ALL = NOPASSWD: /usr/bin/foo, /usr/bin/bar

... with:

%admins ALL = NOPASSWD: /usr/bin/foo, /usr/bin/bar

... and that's it. Any members then of group "admins" can run the specified programs -- again supplying no password.

Then save the file, and test it:

sudo -u usera /usr/bin/foo

... it does have its uses. :)

Using passwords

So far, we've just looked at using sudo without ever needing to specify a password. There are a number of ways to achieve this. For instance, let's assume that user "dave" now has to specify a password. We might have an entry like this for him:

dave   ALL=(ALL)  ALL

This will ask for a password -- the password of user dave, and NOT of user root. Sudo will remember this password for five minutes. We can enforce a different timeout policy, say two minutes. Sudo recognises a specific directive: defaults. Hence the line:

Defaults:dave  timestamp_timeout=2

You can use any value. A value of -1 indicates that dave need only enter the password once. After that, sudo will remember it, even if he logs out, etc.

Now let's assume that we want to increase the number of password tries Dave has. By default sudo allows for three tries. Let's increase that to five. We can use:

Defaults:dave  timestamp_timeout=2, passwd_tries=5

One can have multiple 'Defaults' lines for users. Indeed, if one wanted to make it a global policy irrespective of users or groups, one can use:

Defaults  timestamp_timeout=2, passwd_tries=5

Limiting Commands

We've already seen how one can limit the commands a user or group can run. But this can be extended. So far, I've alluded to the fact of the structure of:

dave   ALL=(ALL)  ALL

The first ALL assumes that it is network-wide policy. You can restrict sudo to limit itself to a single host. Assume the hostname was 'Station':

dave  Station=  ALL

Or any number of commands:

dave  Station=  /usr/bin/foo, /usr/local/bin/bar

You can even tell sudo to only allow commands in a specific directory to be run:

dave  Station=  /usr/bin/foo, /usr/local/bin/bar, /usr/local/myprogs/

The "(ALL)" part lists users that other users can run commands as, so for instance. Let's now assume that we want user 'dave' to be able to run a selection of programs, but he also has access rights to run them as other users ('usera' and 'userb'):

dave  Station=(usera,userb)  /usr/bin/foo, /usr/local/bin/bar, /usr/local/myprogs/

As with an earlier example, this means that Dave can now, if he wants to, issue commands like:

sudo -u usera /usr/bin/foo

The final "ALL" simply means that any program can be run.

Running GUI programs

It was mentioned earlier that running GUI programs as root can be problematic. This is done for a reason. But there is also an underlying reason as well. X11 is a networking model, with all the inherent permissions you would expect. So if usera logs in to, say, KDE, only usera is allowed to run GUI programs on it. But what if you wanted to run a GUI program as user root (say, a package manager?). Well, you might see references to using:

$ xhost +
$ su -
...
 1. export DISPLAY=:0
 1. runMyCommand &
 1. exit

$ xhost -

But let me tell you now: USING XHOST IS THE WORST THING YOU CAN DO. A chocolate fireguard is more secure. "xhost" simply drops the security permissions http://hants.lug.org.uk/cgi-bin/wiki.pl?[[LinuxHints/PseudoRoot#1|1]]. Note that even with:

$ xhost localhost+

... that is still a bad thing. If you *must* run a GUI program as root, then:

$ su -
...

 1. xauth merge ~user_running_X/.Xauthority
 1. export DISPLAY=:0 && myapp &

... where "~user_running_X" is the username of the user running X. Note that this procedure is using something called a "mit-magic-cookie" -- something saved for another thread, if anyone cares.

But. If you have setup sudo then the mit-magic-cookie stuff is done for you. Hence if "myapp" were an actual GUI command, you can as a non-root user (that owns the Xserver connection) type:

$ sudo myapp

and it would launch instantaneously.

As a final note, there are several "wrappers" around su(1). In KDE, this is:

kdesu

and for others, the commands:

gksu
gksudo

can be used. All of them give a graphical prompt for you to enter root's password so that the application in question can be run as root. They're often used in menus.

Conclusion

There's a lot more to sudo than just the points raised here. Ultimately, the best reference is man 5 sudoers.


[#1] [1] It is slightly more complex than that, but for now it will suffice it to say this is the effect it has.

LinuxHints/PseudoRoot (last edited 2010-05-28 17:07:32 by AdamTrickett)