Linux-tips

Fork me on GitHub

I. Linux tips

2. Playing with sudoers file

This is "just" some explanations and examples about the sudoers file and how it works. For more information, don't hesitate to read the sudoers manual man sudoers.

Be very careful when you modify this file, it could create really BIG issues. To prevent most of them, it is very recommended to edit the sudoers file (located in /etc/sudoers) with the visudo command.

Let's start!

For these explanations, we'll test with insults parameter (when you enter an invalid password for sudo command, it'll display some "messages").

If you want to modify defaults for everyone:

Defaults insults

For one (or more) user:

Defaults:user1 insults # for one
Defaults:user1,user2,user3 insults # for more

When you run as an other user (for example, when you use 'sudo -u user1 bash'):

Defaults>user1 insults
Defaults>user1,user2,user3 insults

You can as well do it with an host list (with '@') and a command list (with '!'):

Defaults@localhost insults # /!\ if you connect from another computer (with ssh for example), this won't apply
Defaults!/bin/ls insults

Just like for hosts/users/commands/run as, you can set multiple parameters, separated by ',':

Defaults@localhost insults,targetpw

However you can't mix default types:

Defaults@localhost:user1 insults # doesn't work!

User specification

Now, if you want a more precise control over a specified user, you can use user specification. The base syntax is the following: who where = (as_whom) what. Example:

user1 ALL = (user2) /bin/ls

Here, the user user1 on/from every computer may run /bin/ls only as user2 (equivalent of sudo -u user2 /bin/ls).

You can also specify one (or more) group:

user1 ALL = (user2 : some_group, some_other_group) /bin/ls

Which means that the command can be run with either user1 current group or some_group or some_other_group. So the following commands are all correct:

sudo -u user2 /bin/ls
sudo -u user2 -g some_group /bin/ls
sudo -g some_group /bin/ls
sudo -u user2 -g some_other_group /bin/ls

Just like groups, you can set multiple users and multiple commands at once:

user1 ALL = (user2, user3 : some_group, some_other_group) /bin/ls, /bin/grep

Or just one group without specifying a user:

user1 ALL = (: some_group, some_other_group) /bin/ls, /bin/grep

And you can also set specific commands for differents users/groups:

user1 ALL = (user2 : some_group) /bin/ls, (user3) /bin/grep

/bin/ls may be launched as user2 or some_group and /bin/grep may be launched as user3.

And also, you can set those parameters for a group, a "run as" or a host:

%sudo ALL=(ALL) ALL # so every member of the sudo group has root access

Tags

From the man: "A command may have zero or more tags associated with it. There are ten possible tag values: NOPASSWD, PASSWD, NOEXEC, EXEC, SETENV, NOSETENV, LOG_INPUT, NOLOG_INPUT, LOG_OUTPUT and NOLOG_OUTPUT. Once a tag is set on a Cmnd, subsequent Cmnds in the Cmnd_Spec_List, inherit the tag unless it is overridden by the opposite tag (in other words, PASSWD overrides NOPASSWD and NOEXEC overrides EXEC)."

I'll let you read the manual to know what each tag does. Now let's take some examples:

user1 ALL = NOPASSWD: /bin/ls, /bin/grep

In here, user1 on/from any computer will be able to run /bin/ls and /bin/grep as root without authenticating himself.

Just like user specification, you can set multiple tags on one line:

user1 ALL = NOPASSWD: /bin/ls, PASSWD: /bin/grep

Alias

You can declare four types of alias:

  • User alias (wrote User_Alias)
  • Run as alias (wrote Runas_Alias)
  • Host alias (wrote Host_Alias)
  • Command alias (wrote Cmnd_Alias)

An example will better than a speech:

User_Alias PEOPLE = user1, user2, user3

Defaults:PEOPLE insults
PEOPLE ALL = NOPASSWD: ALL # however, you'd better avoid to write this

Now, I guess you could easily give rights for user1 to log as root, no?

user1 ALL=(ALL) ALL

The '!' operator

Adding '!' before a command/variable/tag/whatever means it'll revert its effets. So !ALL means no one. You can put more than one, of course (so '!!' will very likely do nothing whereas '!!!' will certainly do the same as '!'). Example:

!PEOPLE ALL=(ALL) ALL # so all people not in PEOPLE will be able to log as root

Mixup

This part will be short. You can mix tags and user specifications. Example:

user1 ALL=NOPASSWD: /bin/ls, (root)

However, be careful. In some cases, I had to do it in two steps (each operation on its own line) because visudo didn't recognized it (why? the mystery remains complete!).

Add external files/directories

You can add other files and/or directory with #include and #includedir. It can be quite convenient if you don't want to modify original sudoers file. Example:

#include /etc/sudoers.local # include the sudoers.local file
#includedir /etc/sudoers.d # all files in this folder will be added

Warning!!: for #includedir, every files which end with '~' or contain a '.' character will be ignored. They also need to have 0440 rights.

For more details, read man sudoers, "Including other files from within sudoers" part.

Check your sudoers files

Once you have finish to modify it (without visudo), you can check it with the following command:

sudo visudo -cf path/to/sudoers

Or you could use sudo -l.

Enjoy!