为什么系统有/etc/sudoers.d?我应该如何编辑它?

aob*_*aob 59 sudo httpd ubuntu sudoers

上次,我询问了这些(在/etc/sudoers中)的风险:

    user_name ALL=(ALL) /usr/bin/vim /etc/httpd/confs/httpd.conf
    %group_name ALL=(ALL) /usr/bin/vim /etc/httpd/confs/httpd.conf
Run Code Online (Sandbox Code Playgroud)

在思考这个问题的时候,我找到了/etc/sudoers.d目录。目录下的文件应该和/etc/sudoers有类似的功能(也就是说上面的脚本在/etc/sudoers.d里还是有问题的),但是有一篇文章说我们不应该使用这个目录,因为我们不能用它visudo来编辑文件它。也就是说,sudo如果我们在目录中出错,我们将失去使用权。

如果这是真的,为什么我们有/etc/sudoers.d?或者我们有没有好的方法来编辑/etc/sudoers.d 中的文件?

Joh*_*024 72

是的,您可以visudo用来编辑这些文件。您所要做的就是使用该-f选项指定要编辑的文件的名称。例如:

visudo -f /etc/sudoers.d/somefilename
Run Code Online (Sandbox Code Playgroud)

或者,如果需要:

sudo visudo -f /etc/sudoers.d/somefilename
Run Code Online (Sandbox Code Playgroud)

文档

来自man visudo

-f sudoers
指定和备用 sudoers 文件位置。使用此选项 visudo 将编辑(或检查)您选择的 sudoers 文件,而不是默认的 /etc/sudoers.conf 文件。使用的锁定文件是指定的 sudoers 文件,其中附加了“.tmp”。仅在仅检查模式下,-f 的参数可能是“-”,表示将从标准输入读取 sudoers。

总之:

  1. 语法:无论visudovisudo -f 执行相同的语法检查

  2. 权限/所有权: 作为为协助管理大型系统而添加的一项功能,visudo -f不检查在其下编辑的文件的所有权或权限:这允许离线检查文件或作为修订控制系统的一部分进行语法检查。

为什么使用 /etc/sudoers.d/

通常/etc/sudoers由您的发行版的包管理器控制。如果您对该文件进行了更改并且包管理器想要升级它,您将必须手动检查更改并批准它们如何合并到新版本中。通过将您的本地更改放入/etc/sudoers.d/目录中的文件中,您可以避免此手动步骤并且升级可以自动进行。

什么时候sudo忽略文件/etc/sudoers

如果您的/etc/sudoers文件包含以下行:

#includedir /etc/sudoers.d
Run Code Online (Sandbox Code Playgroud)

然后sudo将读取目录中的文件/etc/sudoers.d

例外情况是:

  1. 文件名以 ~
  2. 名称包含.字符的文件

这样做是为了 (a) 包管理器的方便以及 (b) 以便忽略来自编辑器的备份文件。

  • 感谢您的例外部分。我将我的文件命名为“/etc/sudoers.d/mysudorules.sudo”,但在阅读您的答案之前,我无法弄清楚为什么其中的规则没有应用。 (6认同)
  • @Arun你是对的,它看起来逻辑上不一致。然而,从“man sudoers”开始,规则是“#”开始注释,除非“#”后面紧跟着“include”或“includedir”。 “sudo”的作者可能选择这种方法,因为他们熟悉“C”,并且 C 预处理器也有一个“#include”指令。 (6认同)
  • 是的,`visudo -f` 以安全的方式编辑,就像普通的 `visudo` 一样。这就是为什么我们有 `visudo` 以及为什么它提供了 `-f` 选项。 (5认同)
  • 精彩的答案,我有一个小问题“#includedir /etc/sudoers.d”,为什么“#”不被视为“注释行” (4认同)
  • *感谢您提及例外情况。*我在`/sudoers.d/mysite.co.uk`下的文件不起作用,重命名为`mysite`后它起作用了!:) (2认同)

Bil*_*hor 54

/etc/sudoers.d如果升级系统,对文件所做的更改将保留。这可以防止用户在系统升级时锁定。Ubuntu 倾向于喜欢这种行为。其他发行版也在使用这种布局。

根据我的经验,此目录中文件的规则比/etc/sudoers. 这包括:

  • 文件中的错误不会导致sudo失败。但是,该文件被忽略了。
  • 权限规则似乎不那么严格。它允许适用的组或其他人读取文件。我不相信这是可能的/etc/sudoers。必须限制写入权限root以维护安全性。当前 Ubuntu 版本的 sudo 允许对组或其他人的读取权限。(此功能允许使用 sudo 访问进行审核,而无需 root 访问。)

visudo命令仅默认为/etc/sudoers. 它将编辑和验证您使用该-f选项指定的任何文件。我用这个能力,它会自动安装编辑文件/etc/sudoers或进入/etc/sudoders.d。但是,可能找不到来自其他文件的定义。最好使文件独立。

拥有独立文件的能力使应用程序sudo在安装时启用功能并在卸载时删除它们变得简单。自动化配置工具也可以使用此功能。

我已使用此功能来隔离授予对特定系统上特定用户组的访问权限所需的更改。

  • 强烈不同意“文件中的错误并未导致 `sudo` 失败”的说法。我在来自 /etc/sudoers.d 的文件中使用不正确的语法在 RHEL 上破坏了 sudo。这需要付出很大的努力来纠正,我认为建议应该始终使用 `visudo -f` 来编辑这些文件。 (3认同)

Rog*_*mbe 22

为什么我们有/etc/sudoers.d?

因为自动化工具(例如 Chef 或 Puppet)更容易将单个文件放入此目录中,而不是对 进行更改/etc/sudoers,这可能很脆弱。

中的文件/etc/sudoers.d(实际上)是连接在一起的。您将在 中看到此模式的其他几个实例/etc,例如/etc/cron.d/etc/logrotate.d


dra*_*788 17

使用visudo -f某些答案中提到的另一个好处是有一个相应的选项,-c或者--check可以验证您在 sudoers.d 文件或您可能想要放入 sudoers.d 的任何其他文件中没有无效信息。这在自动化工具提到的情况下非常方便,因为您可以运行例如

sudo visudo -c -q -f /home/myuser/mysudoers && \
sudo chmod 600 /home/myuser/mysudoers && \
sudo cp /home/myuser/mysudoers /etc/sudoers.d/mysudoers
Run Code Online (Sandbox Code Playgroud)

这会以静默方式检查文件(由于 -q 没有输出),并且只有在不返回错误(退出 1 表示无效的 sudoers 文件)时才会将文件复制到 sudoers.d 中,这样您就可以创建文件并处理它而不必第一次做对(使用sudo visudo -f /etc/sudoers.d/myfile必须成功,否则如果不修复它就会丢弃内容)。

另外,请注意其他答案中的这些陈述。

根据我的经验,此目录中文件的规则比 /etc/sudoers 宽松。这包括:

文件中的错误不会导致 sudo 失败。但是,该文件被忽略了。权限规则似乎不那么严格。我允许适用的组读取文件。我不相信 /etc/sudo 是可能的。

/etc/sudoers.d 中的文件需要遵守与 /etc/sudoers 相同的语法,因为在幕后,如果有多个相同的条目,系统会简单地将所有文件与“获胜”中的最后一个文件连接在一起单一设定。

如果 /etc/sudoers.d/ 中的文件的权限非常不正确(世界可写),那么它们将被忽略,这可能是导致无效文件被忽略的原因,否则您可能会sudo因使用无效的 sudoers 而严重破坏命令。 d 文件具有正确的权限。

您可以允许 sudoers 文件是世界可读的,如果您不小心允许“其他”写入权限,您需要以其他用户身份或从 root 终端运行此命令。如果文件的所有者不是 root:root,这也可能会中断。

sudo chmod 644 /etc/sudoers.d/mysudoers
sudo chown root:root /etc/sudoers.d/mysudoers
Run Code Online (Sandbox Code Playgroud)

我刚刚确认,如果我运行,chmod o+w /etc/sudoers.d/vagrant我不能再以 vagrant 用户身份 sudo,它会提示我输入密码,然后失败。

当我sudo -l以另一个有效的 sudo 用户身份运行查看应用的命令权限时,我还收到了有关文件权限的警告。这与我用来确认“vagrant”用户在将o+w权限应用于授予该用户 sudo 权限的文件时丢失 sudo 的命令相同。

  • 这些权限是错误的。 sudoers.d 文件上的值应该是 440 (2认同)

Pet*_*ter 6

只是任何一般答案的简短插件......其他答案都没有解决我的问题,这就是顺序很重要。

如果您的行在 sudoers 中工作但在 sudoers.d 中无效,请尝试移动 #include,或更改 sudoers.d 文件的顺序(通过添加数字前缀)。似乎最具体的东西应该在文件中的第一个。

我有这样的事情:

somebody ALL=(ALL): somecommand
somebody ALL=(someoneelse) NOPASSWD: somecommand
Run Code Online (Sandbox Code Playgroud)

第二个没有效果,因为第一个已经匹配。NOPASSWD 不是条件,而是修改动作的某种方式。

由于 sudoers.d 目录,它并不明显,因为它不在单个文件中。