• VMware

    Learn about VMware virtualization for its products like vsphere ESX and ESXi, vCenter Server, VMware View, VMware P2V and many more

  • Linux

    Step by step configuration tutorials for many of the Linux services like DNS, DHCP, FTP, Samba4 etc including many tips and tricks in Red Hat Linux.

  • Database

    Learn installation and configuration of databases like Oracle, My SQL, Postgresql, etc including many other related tutorials in Linux.

  • Understanding syntax, arguments, aliases used in sudoers file with examples (visudo)

    This article contains overview on the various syntax and aliases which are used in sudoers file

    IMPORTANT POINT: It is strongly recommended to use "visudo" to edit the sudoers file rather than using normal editor and directly modifying the original file /etc/sudoers as that way you will not be able to do any syntax check.
    Any incorrect syntax in the sudoers file can block you for accessing your node and can be very risky.
    "visudo" will not allow you to exit the editor with an incorrect syntax in the file.
    The most commonly used syntax used can be summarised as
    USER_SPACE  HOST=RunAs(User)  COMMANDS

    OR

    USER_SPACE  HOST=RunAs(User:Group)  COMMANDS

    You can also use NOPASSWD variable if you do not want sudo to prompt for password while executing the assigned task

    The syntax here would be:
    USER_SPACE  HOST=RunAs(User)  NOPASSWD:COMMANDS

    OR

    USER_SPACE  HOST=RunAs(User:Group)  NOPASSWD:COMMANDS

    Let's understand the different fields here separately
    USER_SPACE : this is the first column of the syntax which can contain username, %group or User_Alias
    HOST : this will contain hostname detail on which the sudo will perform the assigned task
    RunAs : This optional clause controls the target user (and group) sudo will run the Command as.
    COMMAND : Give the list of command(s) which you want the user to execute

    Aliases in sudoers file

    Various Aliases defined in the sudoers files, these are sort of VARIABLES we use in scripts which can contain multiples entries that fit the same domain (users, hosts, commands). The aliases we have in sudoers are as below
    User_Alias
    Host_Alias
    Cmnd_Alias

    Let's go through each of the available options one by one with some examples to understand more on them.


    User

    You can assign sudo based permission for individual user by using the below syntax

    Syntax:
    user HOST=RunAs COMMAND
    For example I want user "deepak" to be allowed to restart crond service so below would be the syntax I would use
    deepak ALL=(ALL) /usr/bin/systemctl restart crond.service
    If I want to allow him to run more commands then add below content in your sudoers file using visudo
    deepak ALL=(ALL) /usr/bin/systemctl restart crond.service, /usr/bin/systemctl status crond.service
    Validate the same
    [deepak@golinuxhub ~]$ sudo systemctl status crond.service
    [sudo] password for deepak:
    ● crond.service - Command Scheduler
       Loaded: loaded (/usr/lib/systemd/system/crond.service; enabled; vendor preset: enabled)
       Active: active (running) since Sat 2017-12-30 19:04:36 IST; 4min 18s ago
     Main PID: 1768 (crond)
       CGroup: /system.slice/crond.service
               └─1768 /usr/sbin/crond -n

    Dec 30 19:04:36 golinuxhub.lab systemd[1]: Started Command Scheduler.
    Dec 30 19:04:36 golinuxhub.lab systemd[1]: Starting Command Scheduler...
    Dec 30 19:04:36 golinuxhub.lab crond[1768]: (CRON) INFO (RANDOM_DELAY will be scaled with factor 10% if used.)
    Dec 30 19:04:36 golinuxhub.lab crond[1768]: (CRON) INFO (running with inotify support)
    Dec 30 19:04:36 golinuxhub.lab crond[1768]: (CRON) INFO (@reboot jobs will be run at computer's startup.)



    User Alias (User_Alias)

    If we have multiple list of users for whom we want to allow certain list of commands with sudo then we can use "User_Alias" which is an internal variable of sudoers file.

    Syntax:
    User_Alias  ALIAS_NAME = user1, user2, ...

    ALIAS_NAME
      HOST = RunAs COMMAND

    For example:
    I have user "deepak" and "ankit" to whom I want to allow execute crond service related commands for restart and status using systemctl then my syntax would look like below





    Look out for below section in your sudoers file using visudo
    ## User Aliases
    ## These aren't often necessary, as you can use regular groups
    ## (ie, from files, LDAP, NIS, etc) in this file - just use %groupname
    ## rather than USERALIAS
    # User_Alias ADMINS = jsmith, mikem
    # The content may look little different based on your distribution, below this you can # create a new line add below content

    User_Alias CROND_USER = deepak, ankit

    NOTE: There is no hard and fast rule to create new rule below this section, although this helps keep every variable under its respective section so looks neat and clean which is always good

    Lastly add a new line at the end of sudoers file
    CROND_USER ALL = (ALL) /usr/bin/systemctl restart crond.service, /usr/bin/systemctl status crond.service
    here as you see instead of giving name of individual user I created a variable CROND_USER and added all the list of users for whom I want to give common sudo access



    %Group

    Assuming you already have a system group which has a list of users for whom you want to allow certain commands or tasks then instead of using User_Alias you can use the group argument using the below syntax

    Syntax:
    %groupname  HOST=RunAs COMMAND
    For example I have a group "mycompany" whose members are user "deepak" and "ankit" for whom again I want to give access to execute restart and check status of crond service

    Add the below line in the sudoers file /etc/sudoers using visudo
    %mycompany ALL=(ALL) /usr/bin/systemctl restart crond.service, /usr/bin/systemctl status crond.service


    NOPASSWD

    By default, sudo requires that a user authenticate him or herself before running a command.  This behavior can be modified via the NOPASSWD tag

    Syntax for individual user:
    User  HOST=RunAs NOPASSWD:COMMAND

    Syntax for individual group:
    %group  HOST=RunAs NOPASSWD:COMMAND

    Syntax for User_Alias:
    ALIAS_VARIABLE  HOST=RunAs NOPASSWD:COMMAND
    For example I have a user deepak for whom I want to give permission to restart and check status of crond service

    Add the below content at the end of the line in your sudoers file using visudo
    deepak ALL=(ALL) NOPASSWD:/usr/bin/systemctl restart crond.service, /usr/bin/systemctl status crond.service
    Suppose I have a set of commands out of which I want to allow deepak to run only few of the commands passwordless while for some I want the password prompt then in that case we will use below rule
    deepak ALL=(ALL) NOPASSWD:/usr/bin/systemctl restart crond.service, PASSWD:/usr/bin/systemctl status crond.service
    So here "deepak" will be allowed to restart crond service without password but he will be prompted for password while checking the status of the crond service

    HOST

    Why do we need "Host" when I know I am going to run from my machine?
    Well actually the question is absolutely correct but what if you have a big network with 1000s of servers wherein each group of server have their own role for eg some can be a DNS server, some can be an apache server and we have to assign sudo roles accordingly to respective users.
    Now you wouldn't want a user "deepak" who is a domain administrator having sudo access to domain server is also getting sudo access to other servers?

    So I will use the "Host" section in the sudo and will make sure that user deepak to allowed to run all the needed commands as root but only on the "Domain Server"

    Syntax:
    User  HOST=RunAs COMMAND
    For example if my domain server hostname is "golinuxhub" then my sudoers would have something like
    deepak  golinuxhub=(ALL) <List of commands>
    with this user "deepak" can run all the allowed commands on "golinuxhub" but not on other servers

    For example I want "deepak" to allow restart of crond service but only on golinuxhub server
    deepak golinuxhub=(ALL) /usr/bin/systemctl restart crond.service
    If I want him to allow restart this server on all the hosts then this would become
    deepak ALL=(ALL) /usr/bin/systemctl restart crond.service


    Host_Alias

    If you want to allow a user execute some tasks with sudo permission on multiple hosts then you can use the Host_Alias variable which is an sudoers based internal variable.

    Syntax:
    Host_Alias  MAILSERVERS = smtp, smtp2, ...
    Look out for below section in your sudoers file using visudo and append a new line to create a new variable for your  requirement

    For example I want "deepak" to run some command on dnsserver and dhcpserver then
    ## Host Aliases
    ## Groups of machines. You may prefer to use hostnames (perhaps using
    ## wildcards for entire domains) or IP addresses instead.
    # Host_Alias     FILESERVERS = fs1, fs2
    # Host_Alias     MAILSERVERS = smtp, smtp2
    Host_Alias DEEPAK_SERVER = dnsserver, dhcpserver
    deepak  Host_Alias=(ALL) /usr/bin/systemctl restart crond.service

    Here dnsserver and dhcpserver are the hostname of my servers, you can replace this with the hostname based on your setup

    NOTE: There is no hard and fast rule to create new rule below this section, although this helps keep every variable under its respective section so looks neat and clean which is always good


    RunAs(User:Group)

    • A Runas_Spec determines the user and/or the group that a command may be run as.  
    • A fully-specified Runas_Spec consists of two Runas_Lists (as defined above) separated by a colon (‘:’) and enclosed in a set of parentheses.  
    • The first Runas_List indicates which users the command may be run as via sudo's -u option.  
    • The second defines a list of groups that can be specified via sudo's -g option.  
    • If both Runas_Lists are specified, the command may be run with any combination of users and groups listed in their respective Runas_Lists. 
    • If only the first is specified, the command may be run as any user in the list but no -g option may be specified.  
    • If the first Runas_List is empty but the second is specified, the command may be run as the invoking user with the group set to any listed in the Runas_List.  
    • If both Runas_Lists are empty, the command may only be run as the invoking user.  

    With this argument we tell sudo to accept "-u" and "-g" option where "-u" will run the command/script as the respective user and "-g" will do the same as respective group.

    Syntax if only "user" section is used:
    USER_SPACE  HOST = RunAs(User) COMMAND
    Syntax if only "group" section is used:
    USER_SPACE  HOST = RunAs(:Group) COMMAND
    Syntax if both "user" and "group" sections are used:
    USER_SPACE  HOST = RunAs(User:Group) COMMAND
    Let's have a look at some 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 thos script as user "deepak"
    [deepak@golinuxhub ~]$ /tmp/deepak_script.sh
    Hello This is Deepak's fIle

    So this was properly executed. Let's try to run this as some other user "ankit"
    [ankit@golinuxhub ~]$ /tmp/deepak_script.sh
    -bash: /tmp/deepak_script.sh: Permission denied

    First thing it says is permission denied, well why not buddy since deepak is smart as he has not given executable permission to this script so there is no way so gonna mesh with his script

    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.

    Oops that also didn't worked.

    But for the sake of this article let's give Ankit "sudo" permission to execute Deepak's script (I hope he doesn't get mad!!) in the sudoers file using visudo
    ankit  golinuxhub=(deepak) /tmp/deepak_script.sh
    Save and exit the file.

    Now if you notice here I have given RunAs access to "deepak" which means if user "ankit" runs the script as "deepak" then he will be allowed to run the script.

    Now let's try to execute the same file as Ankit but with sudo permission
    [ankit@golinuxhub ~]$ sudo /tmp/deepak_script.sh
    [sudo] password for ankit:
    Sorry, user ankit is not allowed to execute '/tmp/deepak_script.sh' as root on golinuxhub.lab.

    Since here ankit is trying to run deepak's script as root (if there is no -u specified then the sudo works as root user) hence the permission was denied, let's try again with "-u deepak"
    [ankit@golinuxhub ~]$ sudo -u deepak /tmp/deepak_script.sh
    [sudo] password for ankit:
    Hello This is Deepak's fIle

    So it worked this time.

    Similar to this we can also give RunAs "Group" level permission

    For example if I give below arguments in the sudoers file
    ankit  golinuxhub=(deepak:deepak) /tmp/deepak_script.sh
    If you observe I have given access for both User:deepak and Group:deepak so using either Ankit can run the script
    [ankit@golinuxhub ~]$ sudo -g deepak /tmp/deepak_script.sh
    Hello This is Deepak's fIle

    OR he can run the script as either user and group
    [ankit@golinuxhub ~]$ sudo -u deepak -g deepak /tmp/deepak_script.sh
    Hello This is Deepak's fIle



    COMMANDS

    I think I have already been giving multiple examples for this in the above sections. In the last column of sudoers syntax we provide the list of commands which we want to be allowed for a user/group.

    Syntax:
    USER_SPACE   HOST=RunAs COMMANDS
    For example I want "deepak" to allow restart of crond service
    deepak ALL=(ALL) /usr/bin/systemctl restart crond.service
    You can give multiple commands separated by a comma "," and followed by a whitespace.


    Cmnd_Alias

    If you have a set of commands for which you want to provide access so it makes sense to add them into a single variable i.e. Cmn_Alias which is an internal sudoers owned variable.

    Syntax:
    Cmnd_Alias VARIABLE_NAME = /path/to/command1, /path/to/command2, /path/to/command3, ...
    Look out for below section in your sudoers file and append a new line to create a new variable for your requirement in the sudoers file using visudo

    For example I want "deepak" to run some set of commands using a variable CROND_SERVICE
    ## Command Aliases
    ## These are groups of related commands...
    Cmnd_Alias  CROND_SERVICE = /usr/bin/systemctl restart crond.service, /usr/bin/systemctl status crond.service

    deepak ALL = (ALL) CROND_SERVICE

    If you want to disable password prompt for the set of commands then use below line
    deepak ALL = (ALL) NO_PASSWD:CROND_SERVICE

    I will write a separate article with more possible examples and scenarios for sudo use case on ground zero.

    I hope this article was helpful.


    Deepak Prasad

    is a techie and an author who is still trying to survive in this IT generation with very little knowledge he has on Linux/Unix, VMware, SAN Storage, Automation, networking etc

    You can follow him on Facebook or Google+

    Do you also have something to share here?

    Become an author and be a part of our GoLinuxHub Team, Click here for more information
    Understanding syntax, arguments, aliases used in sudoers file with examples (visudo) Understanding syntax, arguments, aliases used in sudoers file with examples (visudo) Reviewed by Deepak Prasad on Tuesday, January 02, 2018 Rating: 5

    No comments:

    Powered by Blogger.