The sudo (superuser do) command is a very useful and powerful part of the OS X unix underpinnings. It gives the ability for certain users to execute some or all commands as root while logging these activities providing a clear bread-trail of who did what to the machine.
By default only an administrative user can use sudo on any OS X machine, but with some modification of the sudoers file, you can grant specific machines and/or users access to sudo some or all of their commands.
Read on for more…I’m sure as an OS X user you’ve probably used sudo once or twice in the past, and realize how useful it is. If you’ve never modified the sudoers file before, and have some users that you feel comfortable giving just a little bit more power to, you’re about to see just how useful it really can be.
Before going any further however, something I can’t stress enough is to make sure you have a backup of the /etc/sudoers file, I like to keep a backup of every file I modify, and rather than just appending .bak onto the file, I also like to know when that backup was from, hense the following command to create my backup:
<code> [email protected]: sudo cp /etc/sudoers /etc/sudoers.`date +%Y%m%d_%H%M%S` </code>
This will create a file name like this /etc/sudoers.20051025_115428 which has not only the date of when you backed up this file, but also the time – useful if you’re doing many revisions on one file in a day!
Editing the sudoers file should be done with visudo – as the name suggests, this uses the vi editor, and also creates a safe environment by locking the file against multiple simultaneous edits, provides basic sanity checks, and checks for parse errors. The vi (‘vee-eye’, not six) editor may be rather new for some mac systems administrators, however, Arek has a very useful vi crash course that will get you up and running with vi in no time, and for posting to the wall of your office, this is a handy vi PDF.
The man page gives a very good description of how visudo works, the two specific command line options I’m going to touch on are the -c and -f options. visudo -c is a checkmode only, you can try this now on any machine, it’s non-destructive, and should look like this:
<code> [email protected]: sudo visudo -c /private/etc/sudoers file parsed OK </code>
The -f option is used to specify an alternate sudoers file location, very useful for editing the file while not affecting a live system, for instance, after creating your backup of the sudoers file, you could create another file as your ‘working’ file and modify it with visudo:
<code> [email protected]: sudo visudo -f /etc/sudoers.working </code>
Before making changes refer to the existing sudoers file keep in mind how the following variables are used as to not to cause any confusion when making changes and/or additions.
What I’m going to show you now, is a very simple set up, of how to allow certain users to use sudo for some mail commands with no password.
Defining user groups, this can be a user, or a system/LDAP group:
<code>User_Alias <name> = < %LDAP GROUP> and/or < %SYSTEM GROUP > and/or < USER ></code>
<code> User_Alias ADMIN = %admin, %root, andrina </code>
The Runas_Alias allows you to define the daemon or user the command can run as, again, this can be a group or an individual user:
<code>Runas_Alias <name> = < %GROUP></code>
<code>MAILERS = %mailman, %postfix, cyrus</code>
Defining machine groups, this allows you to define a group of hosts, this can be by name, IP and including matching patterns:
<code>Host_Alias <name> = < MACHINE or *Pattern*></code>
<code>Host_Alias SERVERS = 192.168.1.1, server*</code>
(Where you have your machines unimiginatively named server1, server2, server3, server* encompasses them all)
Defining commands, which allows you to define which commands are in a group, do note that the path to these commands must be the full path:
<code>Cmnd_Alias <name> = <full path to command/script></code>
<code>Cmnd_Alias MAIL = /usr/bin/cyrus/tools/amsmailtool, /usr/bin/cyrus/tools/mkimap, \ /usr/sbin/postfix-watch, /usr/sbin/postfix, \ /usr/bin/cyrus/bin/ctl_cyrusdb</code>
Note the \ at the end of a line, this indicates that there is more to this command continued on the next line – if you forget these your sudoers file will parse with an error.
Defining Access, this is where the actual work is done – everything we’ve done up until now has been preparing for this moment (much like the first 85 minutes of a Rocky movie) – it should be fairly self explanatory, but essentially here we have the group of specified users that are going to be allowed on our specified machines to run sudo commands as if they belonged to our specified group and run our allocated commands.
<code><user_alias> <host_alias> = (<runas_alias>) <cmnd_alias></code>
<code>ADMIN SERVERS = (MAILERS) NOPASSWD: MAIL</code>
Granted, this is a slightly contrived example of how you’d use the sudoers file, but there are some very specific items that many people would find this useful for – for example, if you had support staff that you’d like to give permission to reboot machines from the command line, but nothing else, here is an idea of how that would look:
<code> User_Alias SUPPORT = %support_staff Host_Alias LABS = lab1-*, lab2-*, lab3-*, \ lab4-*, lab5-* Cmnd_Alias REBOOT = /sbin/reboot SUPPORT LABS = (root) NOPASSWD: REBOOT </code>
In this example, you’ll notice I didn’t specify a Runas_Alias – as I was really only needed the support staff to be able to sudo as root, and no other user/group/daemon, I was able to specify the short name of root – this can be any user short name, or “ALL”. ALL can be used in any of the specifications, as you’ll see in the original file for the root user:
<code> root ALL=(ALL) ALL </code>
This line in the sudoers file is essentially what makes root the super-user that it is.
Something else I haven’t mentioned up until now it the NOPASSWD flag, which does exactly what it sounds like, when a user who is allowed via your sudoers file to run a sudo command, they will not be prompted for a password – which does make some things, like script writing, much simpler. Do be careful with this though, especially if you have users who have been granted some powerful commands – sometimes the time it takes to be prompted for a password is just long enough for someone to realize what they’ve typed isn’t exactly what they wanted to do!
Now you’ve got your perfectly crafted and tested sudoers file, you can push this one file out to all of your workstations and servers with ARD or some other remote shell – it’s generally good practice to keep a copy of the previous or original file, and this is an example of how that could be done, do notice that all the permissions and ownership is checked on the new sudoers file before replacing the old one:
<code> #!/bin/bash sudo cp -i /etc/sudoers /etc/sudoers.`date +%Y%m%d_%H%M%S` sudo cp /path/to/remote/sudoers.new /etc sudo chmod 440 /etc/sudoers.new sudo chown root:wheel /etc/sudoers.new sudo mv /etc/sudoers.new /etc/sudoers </code>
Hopefully this shows how useful, and powerful a sudoers file is, guard this file wisely, and be careful with your modifications. You do have the ability to remove sudo access for all users on a given machine if misconfigured.