目前,我们的 Puppet 服务器有一个 /etc/sudoers 文件,其中定义了网络中每台机器上每个用户的权限。此文件均匀分布到每台主机以提供权限。虽然很方便,但它允许任何具有本地管理员权限的参与者枚举整个网络中的用户及其权限,尽管与本地机器无关。
我的解决方案是利用 saz-sudo 模块,该模块根据 puppet 代理调用传递的主机名分配权限。我能够通过将所有这些信息添加到清单文件来获得一个功能版本。我被要求将这些信息移动到 yaml 格式,以便由 Hiera 管理,希望使信息更易于管理并最大限度地缩短清单文件的长度。不幸的是,我很难用这种方法取得多大成功。
笔记:我对 Puppet 的专业知识仅限于我在尝试解决此问题时通过阅读文档学到的知识。如果您对以下部分代码感到困惑或反感,请记住这一点。
实际的清单实现如下:
class { 'sudo':
}
node default {
}
node 'host1.com' {
sudo::conf { 'host1_permissions':
content => "user1 ALL=(ALL) ALL\nuser2 ALL=(ALL) ALL",
}
}
...
由于环境中有数百台主机,您可以想象这是一个非常大的清单文件。是的,我编写了格式化脚本。以下是我的 Hiera 实现:
datadir: data
data_hash: yaml_data
hierarchy:
- name: "Per-OS defaults"
paths:
- "%{facts.kernel}.yaml"
- name: "Sudo permissions"
path: "sudo_permissions.yaml"
- name: "Other sudoers settings"
path: "sudo_settings.yaml"
在数据文件夹中,我获得了两个 yaml 文件,分别包含用户 sudo 权限和来自 sudoers 文件的附加信息。sudo 权限文件如下所示:
host1.com:
sudoers::rules:
- user1 ALL=(ALL) ALL
- user2 ALL=(ALL) ALL
将所有这些包含在内后,我修改了清单,如下所示:
node default {
include sudo
$node_name = $trusted['certname']
$sudo_rules = lookup("${node_name}.sudoers::rules", Array[String], 'unique', [])
if $sudo_rules {
sudo::conf { "${node_name}_permissions":
content => join($sudo_rules, "\n"),
}
}
}
class sudo_config {
lookup('classes', Array[String], 'unique').each |String $class| {
if $class =~ /^sudo::conf::/ {
$name = regsubst($class, '^sudo::conf::', '')
$content = lookup("${class}::content")
sudo::conf { $name:
content => $content,
}
}
}
}
class { 'sudo':
}
虽然这个实现没有技术上导致任何错误,权限不适用于我测试过的主机。我想这只是默认为空数组的查询,因为萨兹-须都找不到所需内容。此时我发现我的 yaml 格式和可能的清单格式对于我想要做的事情来说不是很准确,但我看不到应该如何纠正它们的明确途径。您可能已经注意到,我发现通过内容字段在一个主机上定义多个用户权限的最佳解决方案是换行符分隔符,我被要求使用此 Hiera 解决方案来解决这个问题。
任何有关此问题的建议都将不胜感激。由于此研究环境在不断变化,因此有很多“临时”解决方案。如果通过 Puppet 进行权限管理的方式很愚蠢,并且通过其他服务处理会更好,请随时告诉我。我不会伤心。我发现它就是这样的。
我还没有提供来自其他 sudoers yaml 文件的信息的详细信息,因为在首先弄清楚这些权限之前,这些信息并不相关。
答案1
看起来您的思路是对的,但需要进行一些调整。在 Hiera YAML 文件中,尝试更改 sudo 权限的格式以符合 saz-sudo 模块的期望。不要使用名为 sudoers::rules 的键,而是直接使用 sudo::conf_content:
host1.com:
sudo::conf_content:
- 'user1 ALL=(ALL) ALL'
- 'user2 ALL=(ALL) ALL'
然后,修改您的 Puppet 清单来处理此结构:
node default {
include sudo
$node_name = $trusted['certname']
$sudo_rules = lookup("${node_name}.sudo::conf_content", Array[String], 'unique', [])
if $sudo_rules {
sudo::conf { "${node_name}_permissions":
content => join($sudo_rules, "\n"),
}
}
}
class sudo_config {
lookup('classes', Array[String], 'unique').each |String $class| {
if $class =~ /^sudo::conf::/ {
$name = regsubst($class, '^sudo::conf::', '')
$content = lookup("${class}::content")
sudo::conf { $name:
content => $content,
}
}
}
}
class { 'sudo':
}
这使得 Hiera 结构与 saz-sudo 预期的格式一致,并且有助于正确应用 sudo 权限。请确保相应地调整其他主机的 Hiera 文件内容。
此外,您可能希望简化 Hiera 配置以直接包含 sudo_permissions.yaml 文件:
datadir: data
data_hash: yaml_data
hierarchy:
- name: "Per-OS defaults"
paths:
- "%{facts.kernel}.yaml"
- name: "Sudo permissions"
path: "sudo_permissions.yaml"