sudoers 文件中使用的语法、参数、别名

sudoers 文件中任何不正确的语法都会阻止我们访问服务器,并且可能非常危险。
“visudo”将不允许我们以文件中的错误语法退出编辑器。
强烈建议使用“visudo”来编辑 sudoers 文件,而不是使用普通编辑器直接修改原始文件 /etc/sudoers ,因为这样我们将无法进行任何语法检查。

最常用的语法可以概括为

USER_SPACE  HOST=RunAs(User)  COMMANDS

或者

USER_SPACE  HOST=RunAs(User:Group)  COMMANDS

如果我们不希望 sudo 在执行分配的任务时提示输入密码,我们也可以使用 NOPASSWD 变量

这里的语法是:

USER_SPACE  HOST=RunAs(User)  NOPASSWD:COMMANDS

或者

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

不同字段的含义:

USER_SPACE :这是语法的第一列,可以包含用户名、%group 或者 User_Alias
HOST :这将包含 sudo 将在其上执行分配任务的主机名详细信息
RunAs :此可选子句控制目标用户(和组)sudo 将运行命令的身份。
COMMAND :给出我们希望用户执行的命令列表

sudoers 文件中的别名

sudoers 文件中定义的各种别名,这些是我们在脚本中使用的变量,可以包含适合同一域(用户、主机、命令)的多个条目。
在 sudoers 中的别名如下

User_Alias
Host_Alias
Cmnd_Alias

User

我们可以使用以下语法为单个用户分配基于 sudo 的权限

user HOST=RunAs COMMAND

例如,我希望允许用户“jack”重新启动crond服务,因此下面是我将使用的语法

jack ALL=(ALL) /usr/bin/systemctl restart crond.service

如果我想让他运行更多命令,那么使用visudo在您的sudoers文件中添加以下内容

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

检查确认

[jack@onitroad ~]$sudo systemctl status crond.service
 [sudo] password for jack:
 ● crond.service - Command Scheduler
    Loaded: loaded (/usr/lib/systemd/system/crond.service; enabled; vendor preset: enabled)
    Active: active (running) since Sat 2015-12-30 19:04:36 IST; 4min 18s ago
  Main PID: 1768 (crond)
    CGroup: /system.slice/crond.service
            └─1768 /usr/sbin/crond -n

用户别名 (User_Alias)

如果我们有多个用户列表,我们希望允许使用 sudo 的特定命令列表,那么我们可以使用“User_Alias”,它是 sudoers 文件的内部变量。

语法:

User_Alias  ALIAS_NAME = user1, user2, ...
ALIAS_NAME  HOST = RunAs COMMAND

例如:
我有一个用户“jack”和“bill”,我想允许他们使用systemctl执行crond服务相关的重启和状态命令,然后我的语法如下所示:

(使用 visudo 查看 sudoers 文件)

## 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 = jack, bill

注意:本节下面没有创建新规则的硬性规定,尽管这有助于将每个变量保持在其各自的节下,因此看起来整洁干净,这总是好的

最后,在sudoers文件的末尾添加一个新行

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

正如您所看到的,我创建了一个变量CROND_user,并添加了我希望为其提供公共sudo访问权限的所有用户列表,而不是给出单个用户的名称

%Group

假设我们已经有一个系统组,其中包含我们希望为其允许某些命令或者任务的用户列表,那么我们可以使用以下语法使用 group 参数,而不是使用 User_Alias

%groupname  HOST=RunAs COMMAND

例如,我有一个组“mycompany”,其成员是用户“jack”和“bill”,我想再次为他们授予执行重启和检查crond服务状态的权限
使用visudo在sudoers文件/etc/sudoers中添加以下行

%mycompany ALL=(ALL) /usr/bin/systemctl restart crond.service, /usr/bin/systemctl status crond.service

NOPASSWD

默认情况下,sudo 要求用户在运行命令之前对其进行身份验证。
可以通过 NOPASSWD 标签修改此行为

单个用户的语法:

User  HOST=RunAs NOPASSWD:COMMAND

单个组的语法:

%group  HOST=RunAs NOPASSWD:COMMAND

User_Alias语法

ALIAS_VARIABLE  HOST=RunAs NOPASSWD:COMMAND

例如,我有一个用户jack,我想给他重新启动和检查crond服务状态的权限
使用visudo在sudoers文件的行末添加以下内容

jack ALL=(ALL) NOPASSWD:/usr/bin/systemctl restart crond.service, /usr/bin/systemctl status crond.service

假设我有一组命令,其中我想让jack只运行一些无密码命令,而对于某些命令,我想使用密码提示,那么在这种情况下,我们将使用下面的规则

jack ALL=(ALL) NOPASSWD:/usr/bin/systemctl restart crond.service, PASSWD:/usr/bin/systemctl status crond.service

所以这里“jack”将被允许在没有密码的情况下重新启动crond服务,但在检查crond服务的状态时会提示他输入密码

HOST

我是在我的机器上运行时,为什么我们需要“HOST”?

没错,如果是单台服务器,确实没必要,但是如果你有一个包含 1000 台服务器的大型网络,其中每组服务器都有自己的角色,例如有些可以是 DNS 服务器,有些可以是 apache 服务器,我们必须分配 sudo 角色根据各自的用户。

现在,我们不希望作为域管理员的用户“jack”对域服务器具有 sudo 访问权限,也可以对其他服务器进行 sudo 访问?

因此,我将使用sudo中的“Host”部分,并确保允许用户jack作为root用户运行所有需要的命令,但只能在“Domain Server”上运行
语法:

User  HOST=RunAs COMMAND

例如,如果我的域服务器主机名是“onitroad”,那么我的sudoers有类似这样的:

jack  onitroad=(ALL) <List of commands>

那么,使用此用户“jack”可以在“onitroad”上运行所有允许的命令,但不能在其他服务器上运行

例如,我希望“jack”允许重新启动crond服务,但仅限于onitroad服务器

jack onitroad=(ALL) /usr/bin/systemctl restart crond.service

如果我允许他在所有主机上重新启动此服务器,那么这将变成:

jack ALL=(ALL) /usr/bin/systemctl restart crond.service

Host_Alias

如果我们想允许用户在多个主机上使用 sudo 权限执行某些任务,那么我们可以使用 Host_Alias 变量,它是一个基于 sudoers 的内部变量。

语法:

Host_Alias  MAILSERVERS = smtp, smtp2, ...

使用visudo查看sudoers文件中的以下部分,并添加一行新行,为您的需求创建一个新变量

例如,我希望“jack”在dnsserver和dhcpserver上运行一些命令

## 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 jack_SERVER = dnsserver, dhcpserver
 jack  Host_Alias=(ALL) /usr/bin/systemctl restart crond.service

这里,dnsserver和dhcpserver是我的服务器的主机名,您可以根据设置将其替换为主机名

RunAs(User:Group)

  • Runas_Spec 确定可以运行命令的用户和/或者组。
  • 完全指定的 Runas_Spec 由两个 Runas_Lists(如上定义)组成,由冒号 (‘:’) 分隔并括在一组括号中。
  • 第一个 Runas_List 指示可以通过 sudo 的 -u 选项运行命令的用户。
  • 第二个定义了可以通过 sudo 的 -g 选项指定的组列表。
  • 如果指定了两个 Runas_Lists,则可以使用在其各自的 Runas_Lists 中列出的用户和组的任意组合运行该命令。
  • 如果只指定了第一个,则可以以列表中的任何用户身份运行该命令,但不能指定 -g 选项。
  • 如果第一个 Runas_List 为空但指定了第二个,则该命令可以作为调用用户运行,并将组设置为 Runas_List 中列出的任何一个。
  • 如果两个 Runas_Lists 都为空,则该命令只能作为调用用户运行。

通过这个参数,我们告诉 sudo 接受“-u”和“-g”选项,其中“-u”将作为各自的用户运行命令/脚本,而“-g”将作为各自的组执行相同的操作。

仅使用“用户”部分时的语法:

USER_SPACE  HOST = RunAs(User) COMMAND

仅使用“组”部分时的语法:

USER_SPACE  HOST = RunAs(:Group) COMMAND

如果同时使用“用户”和“组”部分,则使用以下语法:

USER_SPACE  HOST = RunAs(User:Group) COMMAND

让我们看一看一些例子

“jack”用户有一个测试脚本

[root@golinuxhub ~]# ls -l /tmp/jack_script.sh
-rwxr-xr--. 1 jack jack 47 Dec 30 17:14 /tmp/jack_script.sh

如我们所见,此脚本的用户和组均为“jack:jack”,并且都具有此脚本的可执行权限

如果我以用户“jack”身份运行这个脚本

[jack@golinuxhub ~]$/tmp/jack_script.sh
Hello This is jack's fIle

可以正确执行的。
让我们尝试以其他用户比如“bill”的身份运行它

[bill@golinuxhub ~]$/tmp/jack_script.sh
-bash: /tmp/jack_script.sh: Permission denied

权限被拒绝。

现在 bill 尝试使用 sudo 访问运行脚本,看行不行:

[bill@golinuxhub ~]$sudo /tmp/jack_script.sh
[sudo] password for bill:
bill is not in the sudoers file.  This incident will be reported.

还是不行。

让我们使用 visudo 在 sudoers 文件中给 bill 添加 “sudo” 权限来执行 jack 的脚本

bill  onitroad=(jack) /tmp/jack_script.sh

现在,我们授予 RunAs “jack”的权限,这意味着如果用户“bill”以“jack”身份运行脚本,那么他将被允许运行脚本。

让我们试一下:

[bill@onitroad ~]$sudo /tmp/jack_script.sh
 [sudo] password for bill:
 Sorry, user bill is not allowed to execute '/tmp/jack_script.sh' as root on onitroad.lab.

由于bill试图以root用户身份运行jack的脚本(如果没有指定-u,则sudo作为root用户),因此权限被拒绝,让我们使用“-u jack”重试

[bill@onitroad ~]$sudo -u jack /tmp/jack_script.sh
 [sudo] password for bill:
 Hello This is jack's file

这一次,成功了。

与此类似,我们也可以授予 RunAs “Group”级别的权限
例如,如果我在sudoers文件中给出以下参数

bill  onitroad=(jack:jack) /tmp/jack_script.sh

我为User:jack和Group:jack提供了访问权限,
他可以作为用户和组运行脚本

[bill@onitroad ~]$sudo -g jack /tmp/jack_script.sh
 Hello This is jack's file

[bill@onitroad ~]$sudo -u jack -g jack /tmp/jack_script.sh
 Hello This is jack's fIle

COMMANDS

在 sudoers 语法的最后一列,是允许用户/组使用的命令列表。

语法:

USER_SPACE   HOST=RunAs COMMANDS

例如,允许“jack”重新启动crond服务

jack ALL=(ALL) /usr/bin/systemctl restart crond.service

您可以给出多个命令,这些命令之间用逗号“,”分隔,后跟空格。

Cmnd_Alias

如果我们有一组要为其提供访问权限的命令,那么将它们添加到单个变量中是有意义的,例如:Cmn_Alias,它是一个内部 sudoers 拥有的变量。

语法:

Cmnd_Alias VARIABLE_NAME = /path/to/command1, /path/to/command2, /path/to/command3, ...

请在sudoers文件中查找下面的部分,并使用visudo在sudoers文件中添加一个新行,为您的需求创建一个新变量

例如,我希望“jack”使用变量 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
jack ALL = (ALL) CROND_SERVICE

如果要禁用命令集的密码提示,请使用下面的行

jack ALL = (ALL) NO_PASSWD:CROND_SERVICE
日期:2020-06-02 22:18:42 来源:oir作者:oir