Tutorial / Cheatsheet:12 practical examples for different sudo access based scenarios in RHEL 7 / CentOS 7

Below are some of the scenarios I can think of where sudoers file can be used, if you have any more

questions for which you want any help of post us here in the comment section and I can try to update the article with more example scenarios

To understand more on every syntax used in the sudoers file follow the below link

Understanding various syntax and arguments used in the sudoers file

1. Allow a non-root user access to execute systemctl command

In this example we assume that you know the command for which you want to give sudo access to the user
deepak ALL=(ALL) /usr/bin/systemctl restart crond.service

2. Allow a non root-user to run multiple commands

Here either we can give the list of commands separated by a comma as shown below

deepak ALL=(ALL) /usr/bin/systemctl restart crond.service, /usr/bin/systemctl status crond.service, /usr/bin/systemctl reload crond.service

Or we can create a Cmnd_Alias and add those commands in a Cmnd_Alias variable as shown below

Cmnd_Alias  CROND_SERVICE  = /usr/bin/systemctl restart crond.service, /usr/bin/systemctl status crond.service, /usr/bin/systemctl reload crond.service

3. Allow a non-root user access to run all the systemctl commands

We can use asterisk (*) wildcard after giving the path of systemctl which would mean anything after systemctl is allowed, as shown below
deepak ALL=(ALL) /usr/bin/systemctl *
sudo allows shell-style wildcards (aka meta or glob characters) to be used in host names, path names and command line arguments in the sudoers file.  Wildcard matching is done via the 
     *         Matches any set of zero or more characters (including white space).
     ?         Matches any single character (including white space).
     [...]     Matches any character in the specified range.
     [!...]    Matches any character not in the specified range.
     x        For any character ‘x’, evaluates to ‘x’.  This is used to escape                               special characters such as: ‘*’, ‘?’, ‘[’, and ‘]’.

4. Allow a non root user access to run all the systemctl commands except one single command

Here we can use asterisk (*) to allow all the systemctl related commands and use (!) infront of the command which you wish not to be allowed as shown below

deepak  ALL=(ALL)  /usr/bin/systemctl *, !/usr/bin/systemctl restart crond.service
Lets validate our syntax

So here we are alowed to execute network.service related command
[deepak@golinuxhub ~]$ sudo systemctl status network.service
● network.service - LSB: Bring up/down networking
   Loaded: loaded (/etc/rc.d/init.d/network; bad; vendor preset: disabled)
active (exited) since Sat 2017-12-30 18:43:08 IST; 3h 7min ago
     Docs: man:systemd-sysv-generator(8)
  Process: 786 ExecStart=/etc/rc.d/init.d/network start (code=exited, status=0/SUCCESS)

Dec 30 18:43:07 golinuxhub.lab systemd[1]: Starting LSB: Bring up/down networking...
Dec 30 18:43:07 golinuxhub.lab network[786]: Bringing up loopback interface:  [  OK  ]
Dec 30 18:43:08 golinuxhub.lab network[786]: Bringing up interface eth0:  [  OK  ]
Dec 30 18:43:08 golinuxhub.lab systemd[1]: Started LSB: Bring up/down networking.
And as expected sudo didn't allowed me to restart crond service
[deepak@golinuxhub ~]$ sudo systemctl restart crond.service
Sorry, user deepak is not allowed to execute '/bin/systemctl restart crond.service' as root on golinuxhub.lab.

5. Allow a system group to run some set of commands

Assuming we have system groups to whom to want to allow access of some scripts or commands then use below sytax
%groupname   ALL=(ALL)   /path/to/command1 /path/to/command2
For example I have administrator group to whom I want to allow to restart network and sshd service
%administrator  ALL=(ALL)  /usr/bin/systemctl * sshd.service, /usr/bin/systemctl * network.service

6. Allow multiple non-root users to execute same set of commands

This can be done either by adding all these users to a single group and give permission to the group as explained in above step
or you can create a variable using User_Alias in the sudoers file as below
User_Alias ADMIN = deepak, ankit, rahul
Here I have created a variable ADMIN which contains three users, now I will assing sudo permission to these three users using the ADMIN variable
ADMIN ALL=(ALL)  /usr/bin/systemctl * network.service
So now all the three users will be able to execute systemctl commands for network.service

7. Allow a non root user to run all the commands as allowed to root

You can add this user to the %wheel group as for %wheel group we already have a rule in the sudoers file

## Allows people in group wheel to run all commands
%wheel  ALL=(ALL)       ALL
or else if it is just one user you can add a rule as below
deepak  ALL=(ALL)  ALL

8. Allow non root user to run all the commands on the system except some restricted commands

In the below example I allow "deepak" to run all the system level commands excpet all the systemctl commands for sshd service. You can replace this any other commands just make sure to add (!) in the beginning of the command/script.
deepak  ALL=(ALL)  ALL, !/usr/bin/systemctl * sshd.service

IMPORTANT NOTE: It is generally not effective to “subtract” commands from ALL using the ‘!’ operator.  A user can trivially circumvent this by copying the desired command to a different name and then execute the same since he already has ALL permission

9. All a user to run a command/script as different user or group

Assuming we have two users, user1 and user2 wherein we want user1 to execute some scripts which are actually owned by user2
This is possible by giving user1 RunAs permission in the sudoers file using the below rule

user1   ALL=(user2)   /path/to/script
For example I have a test script which is owned by "deepak" user
[root@golinuxhub ~]# ls -l /tmp/deepak_script.sh
-rwxr-xr--. 1 deepak deepak 47 Dec 30 17:14 /tmp/deepak_script.sh
As you see both user and group of this script is "deepak:deepak" and both have executable permission for this script

If I run this script as user "deepak"
[deepak@golinuxhub ~]$ /tmp/deepak_script.sh
Hello This is Deepak's fIle
Now ankit attempts to run the script with sudo access hoping that might work
[ankit@golinuxhub ~]$ sudo /tmp/deepak_script.sh

We trust you have received the usual lecture from the local System
Administrator. It usually boils down to these three things:

    #1) Respect the privacy of others.
    #2) Think before you type.
    #3) With great power comes great responsibility.

[sudo] password for ankit:
ankit is not in the sudoers file.  This incident will be reported.
So this didn't worked

Add below rule in the sudoers file
ankit  ALL=(deepak) /tmp/deepak_script.sh
Now try to run the script with "-u deepak" as shown below
[ankit@golinuxhub ~]$ sudo -u deepak /tmp/deepak_script.sh
[sudo] password for ankit:
Hello This is Deepak's fIle

10. Allow a non-root user execute a sudo command without being prompted for password

You can achieve this by using NOPASSWD using the below syntax
For example:
deepak ALL=(ALL)  NOPASSWD:/usr/bin/systemctl *
So here I allow user deepak to run all the systemctl commands without being prompted for the password

11. Which file sudo incidents are reported ?

When a non root user allows to run some command as sudo which they are not authorized to then an alarm is generated inside /var/log/secure

For example my user is not allowed to execute below command
[deepak@golinuxhub ~]$ sudo systemctl restart crond.service
[sudo] password for deepak:
Sorry, user deepak is not allowed to execute '/bin/systemctl restart crond.service' as root on golinuxhub.lab.
Immediately the incident was reported in /var/log/secure as below
Dec 30 22:27:34 golinuxhub sudo:  deepak : command not allowed ; TTY=pts/0 ; PWD=/home/deepak ; USER=root ; COMMAND=/bin/systemctl restart crond.service

12. Assign custom environmental variable to a sudo user

This can be achieved by using /etc/environment file where you can define the variable you want to pass on when sudo is executed for the respective user

Just for validating this file I mesh up with my HOME variable
by default my HOME variable is
[deepak@golinuxhub ~]$ echo $HOME
which I will change to /tmp
[root@golinuxhub ~]# cat /etc/environment
Now lets validate the above changes
[root@golinuxhub ~]# sudo -u deepak bash
bash-4.2$ echo $HOME
So this works..

I hope the article was helpful.