用法¶
Rootwrap 应该作为一个独立的 Python 进程调用 oslo_rootwrap.cmd:main 函数。你可以设置一个特定的控制台脚本调用 oslo_rootwrap.cmd:main,例如命名为 nova-rootwrap。为了保持简单,本文档将认为你的控制台脚本名为 /usr/bin/nova-rootwrap。
rootwrap 命令行应该在 sudo 下调用。它的第一个参数是使用的配置文件,其余参数是要执行的命令行
sudo nova-rootwrap ROOTWRAP_CONFIG COMMAND_LINE
rootwrap 的工作原理¶
OpenStack 服务通常在特定的非特权用户下运行。但是,有时它们需要以 root 用户身份运行命令。与其直接调用 sudo make me a sandwich 并拥有一个允许从其非特权用户到 root 用户的 blanket sudoers 权限,不如这些服务调用 sudo nova-rootwrap /etc/nova/rootwrap.conf make me a sandwich。
一个 sudoers 条目允许非特权用户以 root 身份运行 nova-rootwrap。 nova-rootwrap 在其配置文件中查找过滤器定义目录,并从中加载命令过滤器。然后它检查 OpenStack 服务请求的命令是否与这些过滤器中的一个匹配,在这种情况下它将执行该命令(以 root 身份)。如果没有过滤器匹配,它将拒绝该请求。这允许对允许的命令进行复杂的过滤,以及将过滤器定义与需要它们的代码一起打包。
安全模型¶
升级路径完全由 root 用户控制。一个 sudoers 条目(由 root 用户拥有)允许非特权用户以 root 身份运行特定的 rootwrap 可执行文件,并且仅使用特定的配置文件(应该由 root 用户拥有)作为其第一个参数。
nova-rootwrap 从清理后的(和系统默认的)PYTHONPATH 导入它需要的 Python 模块。配置文件指向 root 拥有的过滤器定义目录,其中包含 root 拥有的过滤器定义文件。这个链条确保非特权用户本身从不控制 nova-rootwrap 可执行文件使用的配置或模块。
安装¶
希望运行 nova-rootwrap 的所有节点都应该包含一个 sudoers 条目,允许非特权用户以 root 身份运行 nova-rootwrap,指向 root 拥有的 rootwrap.conf 配置文件,并允许其后的任何参数。例如,Nova 节点应该在其 sudoers 文件中包含以下行,以允许 nova 用户调用 sudo nova-rootwrap
nova ALL = (root) NOPASSWD: /usr/bin/nova-rootwrap /etc/nova/rootwrap.conf *
然后该节点还应该提供与它使用 nova-rootwrap 对应的过滤器定义。你不应该在节点上安装任何其他过滤器文件,否则你将允许额外的、不必要的命令以 root 身份运行。
与节点对应的过滤器文件必须安装在 filters_path 目录之一中。例如,在 Nova 计算节点上,你只应该安装 compute.filters。该文件应该仅由 root 用户拥有和可写。
Rootwrap 配置¶
rootwrap.conf 文件用于影响 nova-rootwrap 的工作方式。由于它位于受信任的安全路径中,因此它需要由 root 用户拥有和可写。它的位置在 sudoers 条目中指定,并且必须作为 nova-rootwrap 命令行的第一个参数提供。
rootwrap.conf 使用 INI 文件格式,包含以下部分和参数
[DEFAULT] 部分¶
- filters_path
包含过滤器定义文件的目录的逗号分隔列表。列出的所有目录必须由
root用户拥有且只能由其写入。这是唯一的强制参数。示例:filters_path=/etc/nova/rootwrap.d,/usr/share/nova/rootwrap- exec_dirs
如果过滤器没有显式指定完整路径,则在其中搜索可执行文件的目录的逗号分隔列表。如果未指定,则默认为系统的
PATH环境变量。列出的所有目录必须由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- rlimit_nofile
指定 oslo rootwrap 及其子进程使用的打开文件描述符数量的 rlimit。这在为调用进程配置了过大的 ulimit 的情况下很有用,不应将其继承给 oslo.rootwrap 及其调用的进程。不会尝试提高限制。默认值为 1024。
在不提供“/proc/self/fd”(例如,非 Linux)的平台上忽略。
.filters 文件¶
过滤器定义文件包含 nova-rootwrap 将用于允许或拒绝特定命令的过滤器列表。它们通常以 .filters 为后缀。由于它们位于受信任的安全路径中,因此它们需要由 root 用户拥有和可写。它们的位置在 rootwrap.conf 文件中指定。
它使用 INI 文件格式,包含一个 [Filters] 部分和多行,每行都有一个唯一的参数名称(对于你定义的每个过滤器不同)
[Filters] 部分¶
- filter_name(每个过滤器不同)
包含首先使用要使用的过滤器类,然后是该过滤器参数(具体取决于所选的过滤器类)的逗号分隔列表。示例:
kpartx: CommandFilter, /sbin/kpartx, root
可用的过滤器类¶
CommandFilter¶
基本过滤器,仅检查调用的可执行文件。参数是
允许的可执行文件
运行命令的用户
示例:允许以 root 用户身份运行 kpartx,并使用任何参数
kpartx: CommandFilter, kpartx, root
RegExpFilter¶
通用过滤器,首先检查调用的可执行文件,然后使用正则表达式列表来检查所有后续参数。参数是
允许的可执行文件
运行命令的用户
(以及后续)用于匹配第一个(和后续)命令参数的正则表达式
示例:允许运行 /usr/sbin/tunctl,但仅在三个参数的情况下,前两个参数为 -b 和 -t
tunctl: RegExpFilter, /usr/sbin/tunctl, root, tunctl, -b, -t, .*
PathFilter¶
通用过滤器,允许你检查作为参数提供的路径是否落在给定的目录之下。参数是
允许的可执行文件
运行命令的用户
(以及后续)命令参数。
有三种类型的命令参数:pass 将接受任何参数值,字符串将仅接受相应的字符串作为参数,除非该字符串以“/”开头,在这种情况下它将接受解析为相应目录的任何路径。
示例:允许将 /var/lib/images 下的任何文件 chown 到“nova”用户
chown: PathFilter, /bin/chown, root, nova, /var/lib/images
EnvFilter¶
允许调用代码设置额外环境变量的过滤器。参数是
env运行命令的用户
(以及后续)可以设置的环境变量的名称,后跟
=允许的可执行文件
示例:允许以 root 身份运行 CONFIG_FILE=foo NETWORK_ID=bar dnsmasq ...
dnsmasq: EnvFilter, env, root, CONFIG_FILE=, NETWORK_ID=, dnsmasq
ReadFileFilter¶
特定过滤器,允许你使用 cat 以 root 身份读取文件。参数是
要作为
root用户读取的文件的路径。
示例:允许以 root 身份运行 cat /etc/iscsi/initiatorname.iscsi
read_initiator: ReadFileFilter, /etc/iscsi/initiatorname.iscsi
KillFilter¶
特定于 kill 的过滤器,在允许该命令之前会检查受影响的进程和发送的信号。参数是
运行
kill的用户仅影响正在运行该可执行文件的进程
(以及后续)允许发送的信号
示例:允许发送 -9 或 -HUP 信号到 /usr/sbin/dnsmasq 进程
kill_dnsmasq: KillFilter, root, /usr/sbin/dnsmasq, -9, -HUP
IpFilter¶
特定于 ip 的过滤器,允许运行任何 ip 命令,但 ip netns 除外(在这种情况下,它仅允许 list、add 和 delete 子命令)。参数是
ip运行
ip的用户
示例:允许运行任何 ip 命令,但 ip netns exec 和 ip netns monitor 除外
ip: IpFilter, ip, root
IpNetnsExecFilter¶
特定于 ip 的过滤器,允许在 ip netns exec 下运行任何其他允许的命令。指定给 ip netns exec 的命令必须匹配另一个过滤器,此过滤器才能接受它。参数是
ip运行
ip的用户
示例:允许运行 ip netns exec <namespace> <command>,只要 <command> 匹配另一个过滤器
ip: IpNetnsExecFilter, ip, root
ChainingRegExpFilter¶
如果其参数的开头与正则表达式列表匹配,并且剩余参数是任何其他允许的命令,则允许运行前缀命令的过滤器。参数是
允许的可执行文件
运行命令的用户
(以及后续)用于匹配第一个(和后续)命令参数的正则表达式。
此过滤器将正则表达式列表的长度视为要检查的参数数量,其余部分由其他过滤器检查。
示例:允许运行 /usr/bin/nice,但仅当前两个参数为 -n 和整数,并且之后跟随其他过滤器允许的任何命令时
nice: ChainingRegExpFilter, /usr/bin/nice, root, nice, -n, -?\d+
注意:此过滤器不能用于强制子命令始终在 prefix 命令下运行。特别是,它不能强制某个命令仅在“nice”下运行,因为子命令可以直接显式调用。
从 OpenStack 服务调用 rootwrap¶
独立模式(sudo 方式)¶
oslo.processutils 库附带了一个方便的 execute() 函数,如果使用以下参数调用,则可用于以 root 身份调用 shell 命令
run_as_root=True
root_helper='sudo nova-rootwrap /etc/nova/rootwrap.conf
注意:某些服务附带一个 utils.execute() 方便函数,该函数会自动根据 rootwrap_config 参数的值设置 root_helper,因此只需要设置 run_as_root=True 即可。
如果您想以 root 身份调用先前未授权的命令,您还需要修改过滤器(通常在源代码树的 etc/rootwrap.d 下),以便您想要以 root 身份运行的命令实际上会被 nova-rootwrap 允许。
守护进程模式¶
自 1.3.0 版本起,oslo.rootwrap 支持“守护进程模式”。在这种模式下,rootwrap 将启动,读取配置文件并等待以 root 权限运行命令。所有与守护进程的通信都应通过位于 oslo_rootwrap.client 模块中的 Client 类进行。
它的构造函数需要一个参数 - 一个可以传递给 Popen 以创建 rootwrap 守护进程过程的列表。对于上面的 root_helper,它将是 ["sudo", "nova-rootwrap-daemon", "/etc/neutron/rootwrap.conf"],例如。请注意,它使用一个单独的脚本,该脚本指向 oslo_rootwrap.cmd:daemon 端点(而不是 :main)。
该类提供一个名为 execute 的方法,其参数如下
userargs- 用于运行命令的命令行参数列表;stdin- 要传递给子进程标准输入的字符串。
该方法返回一个 3 元组,包含
子进程的返回码;
从其 stdout 流捕获的所有内容的字符串;
从其 stderr 流捕获的所有内容的字符串。
该类延迟创建守护进程的一个实例,连接到它并传递参数。如果该守护进程死亡或被杀死,Client 将根据需要重新生成它和/或重新连接到它。