sudo – bane or benefit?

The commonly requested tool sudo is often maligned by younger administrators and venerated by older administrators.

But how much security does sudo actually provide? How useful is it really?

Running sudo gives you some benefits – so one hears:

  • Using sudo records everything someone does as root.
  • Using sudo prevents a user from running continually as root, preventing errors.
  • Using sudo prevents a user from having to know the root password.
  • Using sudo prevents a user from executing anything they are not permitted to.

The problem is that sudo does none of these things very well.

Sudo does indeed record everything one does as root. How does this increase our security? How does this prevent a hacker from compromising a system?

The answer is it doesn’t; recording what someone is doing through this method provides no security at all. A hacker will not use sudo; a regular admin who is using sudo can just use sudo ksh to get a shell that will do what they want. In this way, sudo is merely security through obscurity: if you don’t know how to bypass it, you’ll be recorded. Sudo is like a security camera, watching what you are doing.

Certainly, if you are using sudo, you are not continually running as root – and this is indeed a benefit – and perhaps the primary one. However, there are many things that must be done that cannot be done with sudo. Changing into a restricted directory is just one of them.

It is also true that a user using sudo does not have to know the root password; this also can be a benefit. However, ssh should already be in use and can serve this purpose even better: using an individual’s key, that individual can be granted rights to the root account without knowing the root password – and revoked at will.

The last item is the most dangerous: that using sudo, users can be completely limited in what they can do. The best example of how this can be abused is the attempt of some to prevent the running of a shell by a sudo user. No matter what the sudo file says, one can always do this:

$ cd /bin
$ cp ksh ~/bugbear
$ chmod 700 ~/bugbear
$ sudo ~/bugbear

Instant root shell for anyone with sudo access, regardless of the restrictions in the sudo file. This can be done for any program, as long as the user can read the file it can be changed to a different name and run elsewhere – and if the file can’t be read it can’t be run.

So what are the answers? There are several that, when taken together, will do what sudo wants to do but better:

  • Use SSH. Using ssh one can limit a user to a specific command, and prevent the user from knowing the root password.
  • Use rksh. This may be too restrictive, but can permit users to execute only certain commands appointed by the administrator.
  • Use a chroot jail (or better yet, a BSD jail). Again, this may be too restrictive for most, but will permit a user to only do what is allowed – on a much more restrictive basis than rksh.
  • Use an auditing shell. Ksh93 provides this capability – though there may be a reason that this specific capability is not in the standard ksh supported on today’s system. Using an auditing shell, every command from every user, including system administrators, is logged and retained – possibly to another system on the network. Here is a good article on ksh93 auditing. I would posit, however, that if you can’t trust your system administrators then they shouldn’t be your system administrators: often auditing like this merely provides “a throat to choke.”

In particular, if you utilize the ssh public key encryption capabilities to their fullest with a logging ksh93 shell – and with a “captive” menu perhaps – you can provide the capabilities of sudo without the drawbacks. If you do use sudo, realize how serious its shortcomings are and be aware of them to increase your security elsewhere.

Assorted Tips and Tricks

First, there is one that I learned recently myself. This trick is ingenious!

One of the most challenging things to explain is why this doesn’t work (when the outfile is write-restricted to root):

sudo command > outfile

This will fail because when the shell tries to open outfile, it is not running as root – and thus does not have access. Solving this problem is not simple because of the shell’s quoting mechanisms and when it opens (and doesn’t) the file in question.

However, there is a simple solution that I’d never considered before:

sudo command | sudo tee outfile

This takes care of all the problems involved – and if the command itself is not restricted to root, then the first sudo isn’t necessray either.

Another thing that can be seen often in shell scripts is something like the following:

cmd >> $logfile
cmd2 >> $logfile
cmd3 >> $logfile
print "New stuff...." >> $logfile

This entire section can be replaced like this:

( cmd
cmd2
cmd3
print "New stuff...." ) >> $logfile

In the first example, the $logfile is opened four times – and many situations would include many more than just that. The last only opens $logfile once.

Another tip – this time in the find command. A sequence like this:

find dir1 -mtime +1 -type f
find dir2 -mtime +1 -type f
find dir3 -mtime +1 -type f

…can be replaced by a much more succinct command, like so:

find dir1 dir2 dir3 -mtime +1 -type f

Thus, instead of three process invocations, there is just one.

One more tip: if you find yourself with a .tar.gz file (or whatever) and want to unpack it somewhere else, you don’t have to move the file at all. If you utilize this general sequence, the archive can be anywhere and the unpacked data can go anywhere. Assume that the working directory contains the archive, and the unpacking is to be done in another directory (such as /tmp):

gunzip -c myfile.tar.gz | ( cd /tmp ; tar xvf - )

Using the parenthesis allows you to change the working directory temporarily, and thus to utilize the tar command in a different directory. Inversely, if you were in this same situation but were located in the /tmp directory (and unpacking the archive located in your home directory) – you can do this:

( cd $HOME; gunzip -c myfile.tar.gz ) | tar xvf -

Why not: yet one more tip. Let’s say you want to go to this directory:

/etc/supercalifragilistic/expialidocious/atrocious!/

Rather than having to type that in (and try and get the spelling right!) use something like this to get there:

cd /etc/super*/expi*/atro*/

First, these will match the appropriate directories (assuming there is only one that matches all wildcards). However, with the final slash character in place, that means that only directories that begin with “atro” will be matched – files will not. Nifty, eh?

What’s more, once you’ve gotten to that directory with the nasty name – you can switch to another then back simply:

cd /etc/foo
cd -

That last command switches back to the previous directory – the very long-named directory mentioned before, all compressed down to a single character.

Locking out root!

This is not as far fetched as it sounds; every Macintosh OS X system comes configured in this way: it is impossible to log in as root.

How does one do things as root then? I shall reveal the secret…

First of all, one needs to make sure that the program sudo is available and correctly configured. It must be configured to allow you (or the system owner) to switch to root. Best to test this directly before doing anything to the root account.

Once you have verified that you can switch to root using sudo, then it is time to actually lock the root account. Before doing so, open a root shell using sudo or a direct log in as root. Then execute:

# passwd -l root

There! Now no one can log in as root – don’t you feel much better? Well…. you can become root (by using sudo) but logging in directly as root is impossible.

If passwd does not recognize the -l option, then just put an asterisk (*) into the password field, wherever it is. HP-UX, Linux, and Solaris all recognize the -l option; FreeBSD uses the -l option for a different purpose.

For FreeBSD (and quite probably, OpenBSD and NetBSD as well), use the vipw command to lock out not only the root account, but the toor account as well. The toor account is identical to the root account (including userid) but allows user customization.

When combined with the wheel group, this will lock down your root account quite effectively. Just don’t stop there: remember to use multiple defenses. However, that’s a topic for another day.

Update: This is most useful in situations where a normal user will always have access (workstations come to mind).  If your normal users are authenticated via NIS, or Active Directory, or LDAP, don’t do this! If root logins are locked out, and none of the users can log in…….. then what?  Uh oh….