跳转到: 导航, 搜索

Rootwrap

架构

目的

root wrapper 的目标是允许服务特定的非特权用户以最安全的方式作为 root 用户运行一些操作。 历史上,Nova 使用了一个特定的 sudoers 文件,列出了 nova 用户允许运行的每个命令,并使用 sudoroot 身份运行该命令。 然而,这很难维护。 sudoers 文件是(及其格式取决于)特定打包的一部分。 它不允许对参数进行复杂的过滤(高级过滤器)。 rootwrap 被 设计用于解决这些问题。

一个 Oslo 孵化项目

Rootwrap 代码现在在 oslo-incubator 中维护。 它在多个 OpenStack 项目(Nova、Cinder、Neutron...)中被重用。 为了保持简单,本文档将讨论 nova 代码的副本(nova-rootwrap)。 要将本文档应用于 $PROJECT,只需将 'nova' 替换为 $PROJECT 在下面的每个提及中即可。

毕业孵化项目。 git log。(2013 年 12 月 2 日)

rootwrap 的工作原理

Nova 不只是调用 sudo make me a sandwich,而是调用 sudo nova-rootwrap /etc/nova/rootwrap.conf make me a sandwich。 一个通用的 sudoers 条目允许 nova 用户以 root 身份运行 nova-rootwrap。 nova-rootwrap 查找其配置文件中的过滤器定义目录,并从中加载 命令过滤器。 然后,它检查 Nova 请求的命令是否与这些过滤器中的一个匹配,在这种情况下,它将执行该命令(作为 root)。 如果没有过滤器匹配,则拒绝该请求。

安全模型

升级路径完全由 root 用户控制。 sudoers 条目(由 root 拥有)允许 nova 运行(作为 root)特定的 rootwrap 可执行文件,并且仅使用特定的配置文件(应由 root 拥有)。 nova-rootwrap 从清理后的(和系统默认的)PYTHONPATH 中导入所需的 Python 模块。 配置文件(也由 root 拥有)指向由 root 拥有的过滤器定义目录,其中包含由 root 拥有的过滤器定义文件。 这一链确保 nova 用户本身控制 nova-rootwrap 可执行文件使用的配置或模块。

最终用户文档

服务配置

您必须通过在 nova.conf 中设置以下内容,向 Nova 提供 rootwrap 配置文件的位置

rootwrap_config=/etc/nova/rootwrap.conf


此处使用的配置文件必须与 sudoers 条目中定义的配置文件匹配(如下所示),否则命令将被拒绝! 无需再指定 root_helper 参数。

分发包封装者文档

Sudoers 条目

封装者需要确保 Nova 节点包含一个 sudoers 条目,该条目允许 nova 用户以 root 身份运行 nova-rootwrap,指向由 root 拥有的 rootwrap.conf 配置文件,并允许在该条目之后使用任何参数

nova ALL = (root) NOPASSWD: /usr/bin/nova-rootwrap /etc/nova/rootwrap.conf *

过滤器路径

Nova 在 rootwrap.conf 中查找一个 filters_path,其中包含它应该从中加载过滤器定义文件的目录。 建议 Nova 提供的过滤器文件加载自 /usr/share/nova/rootwrap,额外的用户过滤器文件加载自 /etc/nova/rootwrap.d

[DEFAULT]
filters_path=/etc/nova/rootwrap.d,/usr/share/nova/rootwrap


该行中定义的目录都应存在,并且只能由 root 用户拥有和写入。

过滤器定义

最后,封装需要为每个节点安装与该节点对应的过滤器定义文件。 您不应该在该节点上安装任何其他过滤器文件,否则您将允许额外的未经需要命令以 nova 的身份作为 root 运行。

与节点对应的过滤器文件必须安装在 filters_path 目录之一中(最好是 /usr/share/nova/rootwrap)。 例如,在计算节点上,您应该只有 /usr/share/nova/rootwrap/compute.filters。 该文件应只能由 root 用户拥有和写入。

所有过滤器定义文件都可以在 Nova 源代码的 etc/nova/rootwrap.d 下找到。

插件编写者文档

添加新的以 root 身份运行的命令

插件编写者可能需要让 nova 用户以 root 身份运行额外的命令。 他们应该使用 nova.utils.execute(run_as_root=True) 来实现这一点。 他们应该创建自己的过滤器定义文件并将其安装(只能由 root 用户拥有和写入!)到 filters_path 目录之一(最好是 /etc/nova/rootwrap.d)。 例如,foobar 插件可以将额外的过滤器定义在 /etc/nova/rootwrap.d/foobar.filters 文件中。

过滤器文件的格式如下,在参考部分中定义。

项目开发者文档

添加新的以 root 身份运行的命令

核心开发者可能需要让 nova 用户以 root 身份运行额外的命令。 他们应该使用 nova.utils.execute(run_as_root=True) 来实现这一点,并在 Nova 源代码中的相应 /etc/nova/rootwrap.d/ .filters 文件中添加该命令的过滤器。 例如,要添加需要在计算节点上运行的命令,他们应该修改 /etc/nova/rootwrap.d/compute.filters 文件。

过滤器文件的格式如下,在参考部分中定义。

添加自己的过滤器类型

默认过滤器类型 CommandFilter 非常基础。 它仅检查调用的可执行文件是否匹配,它不会对命令参数执行高级检查。 还有许多其他更特定于命令的过滤器类型可用,请参阅参考部分了解详细信息。

也就是说,您可以轻松定义新的过滤器类型,以进一步控制您实际允许 nova 用户以 root 身份运行的命令。 请参阅 filters.py 代码了解详细信息。

参考资料

rootwrap.conf

rootwrap.conf 文件用于影响 nova-rootwrap 的工作方式。 由于它位于受信任的安全路径中,因此需要只能由 root 用户拥有和写入。 它的位置在 sudoers 条目和 Nova 配置文件中都指定了。

它使用带有以下部分和参数的 INI 文件格式

[DEFAULT]
filters_path 包含过滤器定义文件的目录的逗号分隔列表。 列出的所有目录都必须由 root 拥有且只能由 root 写入
filters_path=/etc/nova/rootwrap.d,/usr/share/nova/rootwrap
exec_dirs 如果过滤器没有显式指定完整路径,则要在其中搜索可执行文件的目录的逗号分隔列表。 如果未指定,则默认为系统 PATH 环境变量。 列出的所有目录都必须由 root 拥有且只能由 root 写入
exec_dirs=/sbin,/usr/sbin,/bin,/usr/bin
use_syslog 启用 syslog 记录。 默认值为 False
use_syslog=True
syslog_log_facility 用于 syslog 记录的 syslog facility。 有效值包括 auth、authpriv、syslog、user0、user1... 默认值为“syslog”
syslog_log_facility=syslog
syslog_log_level 要记录的消息。 INFO 表示记录所有用法,ERROR 表示仅记录未成功的尝试
syslog_log_level=ERROR

.filters 文件

过滤器定义文件包含 nova-rootwrap 将用于允许或拒绝特定命令的过滤器列表。 通常以 .filters 后缀结尾。 由于它们位于受信任的安全路径中,因此需要只能由 root 用户拥有和写入。 它们的位置在 rootwrap.conf 文件中指定。

它使用带有 [Filters] 部分和多行 INI 文件格式,每行都有一个唯一的参数名称(对于您定义的每个过滤器不同)

[Filters]
filter_name(对于每个过滤器不同) 逗号分隔的列表,首先是使用的 Filter 类,然后是该 Filter 的参数(根据所选 Filter 类而异)。
kpartx: CommandFilter, /sbin/kpartx, root


有关每个 Filter 类的参数,请参见下文。

可用的过滤器类

CommandFilter

基本过滤器,仅检查调用的可执行文件。 参数是

  1. 允许的可执行文件
  2. 运行命令的用户


示例:允许以 root 用户身份运行 kpartx,并使用任何参数:kpartx: CommandFilter, kpartx, root

RegExpFilter

通用过滤器,首先检查调用的可执行文件,然后使用正则表达式列表来检查所有后续参数。 参数是

  1. 允许的可执行文件
  2. 运行命令的用户
  3. (以及以下)用于匹配第一个(和后续)命令参数的正则表达式


示例:允许运行 /usr/sbin/tunctl,但仅使用三个参数,前两个参数为 -b 和 -t:tunctl: RegExpFilter, /usr/sbin/tunctl, root, tunctl, -b, -t, .*

PathFilter

通用过滤器,允许您检查作为参数提供的路径是否落入给定的目录中。 参数是

  1. 允许的可执行文件
  2. 运行命令的用户
  3. (以及以下)命令参数。


命令参数有三种类型:'pass' 将接受任何参数值,字符串将仅接受相应的字符串作为参数,除非该字符串以 '/' 开头,在这种情况下,它将接受解析为相应目录的任何路径。

示例:允许 chown 到 'nova' 用户,将任何文件 chown 到 /var/lib/images:chown: PathFilter, /bin/chown, root, nova, /var/lib/images

EnvFilter

允许调用代码设置额外环境变量的过滤器。 参数是

  1. 'env'
  2. 运行命令的用户
  3. (以及以下)可以设置的环境变量的名称,后跟 '='
  4. 允许的可执行文件


示例:允许以 root 身份运行 CONFIG_FILE=foo NETWORK_ID=bar dnsmasq ...:dnsmasq: EnvFilter, env, root, CONFIG_FILE=, NETWORK_ID=, dnsmasq

ReadFileFilter

特定过滤器,允许您使用 cat 以 root 身份读取文件。 参数是

  1. 您想要作为 root 用户读取的文件的路径。


示例:允许以 root 身份运行“cat /etc/iscsi/initiatorname.iscsi”:read_initiator: ReadFileFilter, /etc/iscsi/initiatorname.iscsi

KillFilter

特定于 kill 的过滤器,在允许该命令之前,会检查受影响的进程和发送的信号。 参数是

  1. 运行 kill 的用户
  2. 仅影响正在运行该可执行文件的进程
  3. (以及以下)您允许发送的信号


示例:允许发送 -9 或 -HUP 信号到 /usr/sbin/dnsmasq 进程:kill_dnsmasq: KillFilter, root, /usr/sbin/dnsmasq, -9, -HUP

IpFilter

特定于 ip 的过滤器,允许运行任何 ip 命令,但 ip netns 除外(在这种情况下,它仅允许 listadddelete 子命令)。 参数是

  1. 允许的可执行文件('ip')
  2. 运行 ip 的用户


示例:允许运行任何 ip 命令,但 ip netns execip netns monitor 除外:ip: IpFilter, ip, root

IpNetnsExecFilter

特定于 ip 的过滤器,允许在 ip netns exec 下运行任何其他允许的命令。 指定给 ip netns exec 的命令必须匹配另一个过滤器,此过滤器才能接受它。 参数是

  1. 允许的可执行文件('ip')
  2. 运行 ip 的用户


示例:允许运行 ip netns exec <namespace> <command>,只要 <command> 匹配另一个过滤器:ip: IpNetnsExecFilter, ip, root