HowTO: Sudoers Configuration
For reference on how to setup your sudoers, I suggest you have a skim through this guide: https://help.ubuntu.com/community/Sudoers
It may need a little work here or there (I should know, I wrote some bits of it), but should give you enough information to get some small things started.
This guide is aimed at giving a beginners transition into configuring sudo, and builds up the knowledge enough to tailor permissions for a basic multi-user system (ie: Family Computer).
Once you have a working understanding, it is always a good thing to get acquainted with the sudoers manual on the home site, which goes more indepth and more into the advanced and sometimes unneeded features of how to tweak the sudoers configuration.
The Scenario
Rather than just writing a listed guide or a sudoers cheatsheet, I thought it may be best if I'd use a practical element that most people will benefit from, and others will adapt to their own needs.
So here is the scenario. I use the following applications frequently that require my password in order to carry out administrative tasks:
- apt-get update
- apt-get upgrade
- gmount-iso
- gnome-format
- truecrypt
- unetbootin
- update-manager
and with the somewhat persistent use of them, it can get very dia at times having to type out my password constantly in order to get my usual work done in them. So it would be nice if I could configure sudo to allow me to use these with less of a hassle. Well, fortunately you can!
Enter /etc/sudoers
Everyone knows sudo, everyone knows how it works and when and where to use it. But there seems to be an unspoken art of configuring and setting it up for a multiuser domain, or for a single-user workstation.
But to give you the dropdown basics. Sudo's configuration file is located in /etc/sudoers. But due to the powerness of the program, we don't want to edit it directly in the event of a type error in file; so we use the program visudo instead. visudo is a program which makes a temporary copy of the sudoers file, and sanity checks it after you've finished editing it. If any errors are found, it then prompts you about it, and allows you to go back to fix that misconfigured line.
Opening Sudoers
visudo, as of Intrepid, uses the sensible-editor to edit the sudoers file. So to ensure that sensible-editor is setup on your computer run:
And you'll be given a list of programs to choose from. In most cases, you'll want to choose nano. But other people prefer other editors such as vi, or emacs.
With that set, we are all ready to go, launch visudo.
and you are in.
Before we begin
There are some things that need explaining first before we start playing about with configuration:
1) The sudo binary is setuid root. This means that when any user runs sudo, they are instantly granted root permissions. The only thing stopping a user from using those root permissions for any use is the sudo application itself, which locks down very hard on access. From a security point of view, a sloppy configuration file that grants everything from everywhere root access can be seen as - and is - a major risk to your system.
2) Sudo reads the sudoers file and applies permissions in order from top to bottom. So the last line in the file will overwrite any previous conflict with the config settings. So it is best to put new configuration lines at the bottom.
3) Sudo has a sizeable list of Defaults that you can tweak/set. These are shown by running the following command
By all means, you can look into them, but the only three I recommend you use are:
- env_reset - Reset the environment to a default set of variables
- tty_tickets - Use a separate timestamp for each user/tty combo
- timestamp_timeout - Authentication timestamp timeout
The only one requiring arguments being timestamp_timeout:
Code:
Defaults:ALL timestamp_timeout=0
Which means that ALL users sudo permissions timeout immediately, meaning that they must enter their password every time they use sudo.
A softer usage would be:
Code:
Defaults:ALL timestamp_timeout=15
Where instead the timestamp is 15 minutes.
Note: Active timestamps can be removed at any time by running:
This is can especially useful if you leave your computer without locking it!
Although I can't stress enough the enforcement of common practice, it is safer to deny intruders root access than it is to leave your workstation unlocked for anyone to walk up to/use.
4) For a huge multi-user system, it can sometimes be difficult to know just exactly what commands you have sudo access to, or whether or not your recent sudo tweak took effect in the way that you hoped.
To find out just exactly what sudo permissions you have on your computer, you would run the following
That is "sudo" and a lowercase L as the argument.
OK! Now, with that out the way, lets look at our first line in the sudo configuration file.
Hello Configuration!
For example purposes, lets tweak the sudo permissions for apt-get.
Now, scroll to the bottom, and we can insert our line:
Code:
%admin ALL=(ALL)NOPASSWD:/usr/bin/apt-get
To break it down:
- %admin - All users of the admin group
- ALL= - from any Host/IP
- (ALL) - can run as any user
- NOPASSWD - with no password required
- :/usr/bin/apt-get - the list of comma, separated, applications.
Fine Graining Permissions
Now, as quick and efficient this may be in most cases, it's not the best thing to do from a security point of view for a number of reasons:
1. Any connected computer can run the command, so long as they are logged in as one of the administrators. From a paranoid perspective, ideally we would rather only computers within our local host/network/subnet.
2. They can run the given command as any user. Which apt-get isn't intended for. (Although the argument is weak in this case, in some scenarios and with certain applications, you could be quite literally giving a key for a user to invade another user's private account if not careful).
3. Sometimes, we want the user only to be able to perform "certain" tasks of the application, and not all features.
4. In some circumstances, we only want one user to run a command, rather than all the users in the admin group.
Considering this list, you can make the following changes to it.
Restrict Computers/Hosts
Note: This applies to computers running application services. If you connect to a machine via ssh, this does not apply.
There are two ways you can tackle this:
The first way is by using hostnames.
Note: This is my recommended way.
If you don't know what a hostname is, it is the name of a computer that identifies it on the network. You can find out what the hostname of your machine is by reading the name after the @ symbol in the bash prompt.
ie: my prompt looks like this, 'jaunty' is my hostname.
Alternately, if your prompt doesn't show it, you can run in a terminal:
To obtain the same information.
We can now change our resultant line so it now looks like this:
Code:
%admin jaunty=(ALL)NOPASSWD:/usr/bin/apt-get
So, as long as your hostname remains as 'jaunty', then you can run the sudo command from only your computer.
The second way is by using IP addresses.
Note: This requires for you to be connected to a network! Else you will be denied access
Code:
%admin 192.168.1.0/255.255.255.0=(ALL)NOPASSWD:/usr/bin/apt-get
192.168.1.0 is the IP of your local network.
255.255.255.0 is the subnet of your local network.
So, in this instance, you are restricting the use of sudo only to users with an IP address of 192.168.1.1 through to 192.168.1.254
Restricting User Switching
To run commands as another user (other than root), you would run the following:
To prevent this from happening, you can restrict it by using:
Code:
%admin jaunty=(root)NOPASSWD:/usr/bin/apt-get
So now members of the admin group can only run the given commands without a password as root. Doesn't matter how hard they try otherwise. ![Wink](images/smilies/icon_wink.gif)
Note: if a previous permission is set so the user can run the command as any user.
More specifically this line that is the default in Ubuntu:
Code:
%admin ALL=(ALL) ALL
Then they will have to provide their own password to continue.
A more secure method:
Code:
%admin ALL=(root) ALL
Where they will be instead denied if they try to run an application as another user.
Restricting Application Usage
As well, as limiting the applications a user can run using sudo, you can limit the arguments of those applications that the user can use also, for apps that do more than one job.
To limit apt-get usage to just 'update' and 'upgrade', we can have something like this:
Code:
%admin jaunty=(root)NOPASSWD:/usr/bin/apt-get update,/usr/bin/apt-get upgrade
And now everything other apt-get argument (install, remove, dist-upgrade) is denied!
Alternately, we can also use the glob match '*'.
Code:
%admin jaunty=(root)NOPASSWD:/usr/bin/apt-get up*
The '*' match is very powerful, and can apply to anything in the command listing part of the configuration line, ie:
Code:
%admin jaunty=(root)NOPASSWD:/*/sbin/*
This could match anything from all the files in '/usr/sbin/' to '/usr/local/sbin/' and even places such as '/home/user/sbin/' fall into the match. As such, it is advised that you use it wisely.
Restricting use of sudo to Single Users
As well as specifying groups, we can hand out sudo permissions on a 'per-user' basis too. For example, to only allow the user 'iain' (me) to run 'apt-get update' and 'apt-get upgrade', we use the following:
Code:
iain jaunty=(root)NOPASSWD:/usr/bin/apt-get update,/usr/bin/apt-get upgrade
Note: The difference between a user and a group. Groups have the '%' symbol prefixed against their name. So, to change this so only users in the group 'iain' can run 'apt-get', we simply add the '%' symbol:
Code:
%iain jaunty=(root)NOPASSWD:/usr/bin/apt-get update,/usr/bin/apt-get upgrade
Restrict Applications
There is a hidden 5th that I forgot to mention. In some cases, you want to restrict the application once it has been given root powers.
ie: vim, less and some other similar applications can allow you to 'shell out' of the application and run commands using the ! operator, as an example:
The risk? If given the permissions to running vim as root, you can carry out any administrative task on the system. Which isn't very good if you just want certain users to run vim as root, but not any other command.
For this, we have the NOEXEC option, with will prevent the command from shelling out.
Code:
%admin ALL=(root)NOEXEC:/usr/bin/vim
Although, bare in mind that for the majority of applications, this isn't the best option for usability, since programs such as 'apt-get' do indeed fork a shell to run applications such as dpkg and wget.
Hello Aliases!
Thus far, I have only been concentrating on one application, as from the above line, you can see that bare word configuration can get rather lengthy.
Luckily, the sudoers configuration file can handle variables, or aliases as they are called. There are four types, all to which will be covered in brief.
Host Alias Specification
The host alias, are aliases for the addresses of the host computers to which the commands are ran from.
Host aliases are declared as so, to use my hostname as an example:
Code:
Host_Alias HOST = jaunty
If I were to alias the local network:
Code:
Host_Alias LAN = 192.168.1.0/255.255.255.0
User Alias Specification
The user alias, are aliases for the usernames, or group names, this allows you to create a new group within the sudoers file, but not on the system.
Now, as an owner of a single user system, there is no need for me to go into this. But if you are interested, it works likes so:
Code:
User_Alias FUSE_USERS = andy,ellz,matt,jamie
The users andy, ellz, matt and jamie are - in this example - unprivileged users who are not in the fuse group, and as such, cannot mount/unmount loopback devices. But using the sudo configuration, you can allow them to grant root privileges to use an application that handles the loopback devices. So they have at least some control, but not full control.
A rudimentary line that would show this:
Code:
FUSE_USERS ALL=(root):/usr/bin/the-application
RunAs Alias Specification
The runas alias, are aliases for the users you can sudo as, via the 'sudo -u' command. Again, I won't go into this, but it works like so:
Code:
Runas_Alias USERS = root,andy,ellz,matt,jamie
And put in the following context:
Code:
%admin ALL=(USERS) ALL
Members of the admin group can run any command as any of the users enlisted in USERS.
Command Alias Specification
And lastly, the command alias, as you may have guessed, are aliases for the command names. To skip any brief talk about them, lets first fufil what my original scenario intended.
Code:
Cmnd_Alias CRYPT = /usr/bin/truecrypt
Cmnd_Alias USBDEV = /usr/bin/unetbootin,/usr/bin/gnome-format
Cmnd_Alias APT = /usr/bin/apt-get update,/usr/bin/apt-get upgrade
Cmnd_Alias UPDATES = /usr/bin/update-manager
Cmnd_Alias FUSE = /usr/bin/Gmount-iso
Cmnd_Alias MYPROGS = CRYPT,USBDEV,APT,UPDATES,FUSE
Woah, that is alot. Infact, what I've done is split the applications into sub-groups, and shuffled those groups into one, MYPROGS.
Gelling it together
With the above in place, we can now write out lines such as this:
Code:
iain HOME=(root)NOPASSWD:MYPROGS
Which result in a much cleaner, easier to maintain configuration.
The Result
Put that all together, and we have something that looks like this:
Code:
Defaults env_reset,tty_tickets
# Host alias specification
Host_Alias HOST = jaunty
Host_Alias LAN = 192.168.1.0/255.255.255.0
Host_Alias HOME = HOST,LAN
# User alias specification
# Cmnd alias specification
Cmnd_Alias CRYPT = /usr/bin/truecrypt
Cmnd_Alias USBDEV = /usr/bin/unetbootin,/usr/bin/gnome-format
Cmnd_Alias APT = /usr/bin/apt-get update,/usr/bin/apt-get upgrade
Cmnd_Alias UPDATES = /usr/bin/update-manager
Cmnd_Alias FUSE = /usr/bin/Gmount-iso
Cmnd_Alias MYPROGS = CRYPT,USBDEV,APT,UPDATES,FUSE
# User privilege specification
root ALL=(ALL) ALL
# Members of the admin group may gain root privileges
%admin HOME=(root) ALL
%admin HOME=(root) NOEXEC:/usr/bin/vim
iain HOME=(root) NOPASSWD:MYPROGS
Conclusion
My resultant visudo file is fine as is to build/work on. But it may not be for everyone.
If you connect to your computer from outside your network, I recommend:
Code:
%admin ALL=(root)NOPASSWD:MYPROGS
But, if your company's/workstation's IP address is static, then you can set it as a Host_Alias to be more restrictive.
If you are - like me - on a machine where you are the only admin, and never login from remote. It's probably better to prevent all external computers from running sudo commands, and to specify your username instead.
For the paranoid:
Code:
iain HOST=(root)NOPASSWD:MYPROGS
NOTE: Use your username in place of 'iain', you don't want to give me access to your system. ![Twisted Evil](images/smilies/icon_twisted.gif)
Remember, as the user of your own system, you are advised to use your powers responsibly.
Regards
Iain