OpenStack oslo.rootwrap 实现原理

发布时间: 更新时间: 总字数:487 阅读时间:1m 作者: IP上海 分享 网址

OpenStack oslo.rootwrap 普通用户执行 root 权限的 linux 命令实现原理。

目标

实现普通用户执行 root 命令。

实现方式

通用配置 /etc/sudoers.d/nova 允许 nova 用户作为 root 运行 nova-rootwrap,通过 /etc/nova/rootwrap.d/*.filters 过滤器限定命令范围。Available Filter classes

$ cat /etc/sudoers.d/nova
Defaults:nova !requiretty

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

nova 身份运行命令 sudo /usr/bin/nova-rootwrap /etc/nova/rootwrap.conf * 时,是不需要输入密码的,其中的 * 指的是任意字符串,例如:ip route show ...

示例

from nova import utils

utils.execute('chmod', '777', tmpdir, run_as_root=True)

execute 函数首先根据 run_as_root 参数进行如下处理:

def _get_root_helper():
    return 'sudo nova-rootwrap %s' % CONF.rootwrap_config


def execute(*cmd, **kwargs):
    """Convenience wrapper around oslo's execute() method."""
    if 'run_as_root' in kwargs and not 'root_helper' in kwargs:
        kwargs['root_helper'] = _get_root_helper()
    return processutils.execute(*cmd, **kwargs)

然后丢给 processutils 中的 execute,查看代码:

def execute(*cmd, **kwargs):
    ...
    if run_as_root and hasattr(os, 'geteuid') and os.geteuid() != 0:
        if not root_helper:
            raise NoRootWrapSpecified(
                message=_('Command requested root, but did not '
                          'specify a root helper.'))
        cmd = shlex.split(root_helper) + list(cmd)
 
    cmd = map(str, cmd)
 
    while attempts > 0:
        ...
        obj = subprocess.Popen(cmd,
                               stdin=_PIPE,
                               stdout=_PIPE,
                               stderr=_PIPE,
                               close_fds=close_fds,
                               preexec_fn=preexec_fn,
                               shell=shell)
        ...

最终执行的cmd命令:

sudo /usr/bin/nova-rootwrap /etc/nova/rootwrap.conf chmod 777 tmpdir

这里chmod这个命令在 rootwrap.d 目录下的 filters 文件中可以找到对应的配置:

chmod: CommandFilter, chmod, root
  • CommandFilter 的定义是在 oslo.rootwraposlo_rootwrap/filters.py 中,里面还定义了其他的 filter,如:RegExpFilter、PathFilter、KillFilter、ReadFileFilter、EnvFilter、ChainingFilter、IpNetnsExecFilter、ChainingRegExpFilter。通过 oslo_rootwrap/wrapper.py:start_subprocess 调用命令。

参考

  1. https://wiki.openstack.org/wiki/Rootwrap
Home Archives Categories Tags Statistics
本文总阅读量 次 本站总访问量 次 本站总访客数