设为首页 收藏本站
查看: 2207|回复: 0

[经验分享] openstack root-wrap

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2015-10-10 14:20:49 | 显示全部楼层 |阅读模式
https://wiki.openstack.org/wiki/Rootwrap
一.nova-rootwrap的作用
  部署玩过openstack的都应该知道,它会生成一个nova用户来管理所有服务.nova身份在linux中属于普通用户级别,避免了一些需要root身份运行的操作,提高linux系统的安全性.
但是openstack在实际过程中会调用很多外部命令,例如就network服务而言就有:`ip`,`ovs-vsctl`,`iptables`,`dnsmasq`,`brctl`等等,这些命令在linux中都是需要以root身份来运行的,如果是普通用户通常的做法是在命令前加`sudo`切换到root身份再执行这些命令,但是这个方法在执行命令的时候需要输入密码确认操作,为了避免输入密码,我们需要配置一下sudo.
建议的方法是在/etc/sudoers.d/目录下新建一个文件,例如:
[iyunv@localhost sudoers.d]# pwd/etc/sudoers.d [iyunv@localhost sudoers.d]# echo 'zhengtianbao ALL = (root) NOPASSWD: ALL' > stack_sh[iyunv@localhost sudoers.d]# cat stack_sh zhengtianbao ALL = (root) NOPASSWD: ALL  这样当我们切换到’zhengtianbao’这个用户的时候,只要在想执行的命令前加’sudo’,不需要输入密码就能以root身份运行.

[iyunv@localhost sudoers.d]# su zhengtianbao[zhengtianbao@localhost sudoers.d]$ lsls: cannot open directory .: Permission denied[zhengtianbao@localhost sudoers.d]$ sudo lsstack_sh  关于sudoers的配置文件如何定义,这里简单介绍下:
通用格式:
user host run_as command
user:一位或几位用户,在/etc/group中可以用一个%代替它,组对象的名称一定要用百分号%开头.
host:一个或几个主机名.
run_as:作为哪个用户运行,常见选项是root和ALL.
command:想让用户或组运行的一个或几个根级别命令.
例如:
hans ALL=(root) useradd,userdel
授权hans用户在所有计算机上以root身份运行useradd,userdel命令.
%smith ALL=(ALL) NOPASSWD:useradd,userdel
授权smith组全部成员在所有计算机上以所有用户的身份运行useradd,userdel命令;且运行时不必输入密码.
一点点疑问:能否控制命令的参数呢?接下来做个测试:
[iyunv@localhost sudoers.d]# echo 'zhengtianbao ALL = (root) NOPASSWD: /bin/ls -l, /bin/ls -a' > stack_sh[iyunv@localhost sudoers.d]# su zhengtianbao[zhengtianbao@localhost sudoers.d]$ ls -als: cannot open directory .: Permission denied[zhengtianbao@localhost sudoers.d]$ sudo ls -a.  ..  stack_sh [zhengtianbao@localhost sudoers.d]$ sudo ls -ltotal 8 -rw-r--r-- 1 root root  59 Jan 26 14:43 stack_sh[zhengtianbao@localhost sudoers.d]$ sudo ls -a -l[sudo] password for zhengtianbao:  可见能够控制的命令参数还是很严格的.
放在openstack中这也是可行的,但是随着项目的增大,单纯的修改sudoers影响了openstack的可维护性,因此引入了root warpper来管理命令权限相关的内容.
二.nova-rootwrap工作原理
  如果是根据devstack来安装openstack的话,查看devstack中的stack.sh里面有关于root权限的内容:
# root Access # ----------- # OpenStack is designed to be run as a non-root user; Horizon will fail to run# as **root** since Apache will not serve content from **root** user).# ``stack.sh`` must not be run as **root**.  It aborts and suggests one course of# action to create a suitable user account.if[[ $EUID -eq0 ]];then     echo"You are running this script as root."    echo"Cut it out."    echo"Really."    echo"If you need an account to run DevStack, do this (as root, heh) to create $STACK_USER:"    echo"$TOP_DIR/tools/create-stack-user.sh"    exit1fi # We're not **root**, make sure ``sudo`` is availableis_package_installedsudo|| install_packagesudo  好,它这里表示需要先通过脚本tools/create-stack-user.sh来创建一个用户,再通过那个用户来执行,看脚本内容:
# Needed to get ``ENABLED_SERVICES``source $TOP_DIR/stackrc # Give the non-root user the ability to run as **root** via ``sudo``is_package_installedsudo|| install_packagesudo     if! getent group $STACK_USER >/dev/null;then    echo"Creating a group called $STACK_USER"    groupadd $STACK_USER fi       if! getentpasswd$STACK_USER >/dev/null;then    echo"Creating a user called $STACK_USER"    useradd-g $STACK_USER -s/bin/bash-d $DEST -m $STACK_USERfi echo"Giving stack user passwordless sudo privileges"# UEC images ``/etc/sudoers`` doesnot have a ``#includedir``, add onegrep -q "^#includedir.*/etc/sudoers.d" /etc/sudoers ||     echo"#includedir /etc/sudoers.d">> /etc/sudoers( umask226 &&echo "$STACK_USER ALL=(ALL) NOPASSWD:ALL"\     >/etc/sudoers.d/50_stack_sh)  $STACK_USER的值在stackrc文件中定义,当前环境是root身份时则为’stack’:
# Determine stack userif [[ $EUID -eq 0 ]];then    STACK_USER=stackelse    STACK_USER=$(whoami)fi  ok,这里发现它在/etc/sudoers.d/目录下生成了一个50_stack_sh的文件,里面的内容是:
stack ALL=(ALL) NOPASSWD:ALL
显然它创建的stack用户现在可以在使用`sudo`执行任何命令都能省略输入密码的过程了.
接下来继续看nova的安装过程,在devstack/lib/目录下的nova脚本中有configure_nova()的方法,它会在stack.sh中被调用到,正如名字所示,它用来设置nova的config文件,创建一些数据等工作:
# configure_nova() - Set config files, create data dirs, etcfunction configure_nova() {     # Put config files in ``/etc/nova`` for everyone to find   if [[ ! -d $NOVA_CONF_DIR ]];then        sudomkdir-p $NOVA_CONF_DIR    fi    sudochown$STACK_USER $NOVA_CONF_DIR      cp-p $NOVA_DIR/etc/nova/policy.json $NOVA_CONF_DIR      configure_nova_rootwrap    ...  注意里面的configure_nova_rootwrap,查看该方法:
# configure_nova_rootwrap() - configure Nova's rootwrapfunction configure_nova_rootwrap() {     # Deploy new rootwrap filters files (owned by root).   # Wipe any existing rootwrap.d files first    if [[ -d $NOVA_CONF_DIR/rootwrap.d ]];then        sudorm-rf $NOVA_CONF_DIR/rootwrap.d    fi    # Deploy filters to /etc/nova/rootwrap.d   sudo mkdir-m 755 $NOVA_CONF_DIR/rootwrap.d    sudocp$NOVA_DIR/etc/nova/rootwrap.d/*.filters $NOVA_CONF_DIR/rootwrap.d    sudochown-R root:root $NOVA_CONF_DIR/rootwrap.d    sudochmod644 $NOVA_CONF_DIR/rootwrap.d/*    # Set up rootwrap.conf, pointing to /etc/nova/rootwrap.d   sudo cp $NOVA_DIR/etc/nova/rootwrap.conf $NOVA_CONF_DIR/    sudosed-e "s:^filters_path=.*$:filters_path=$NOVA_CONF_DIR/rootwrap.d:"-i $NOVA_CONF_DIR/rootwrap.conf    sudochownroot:root $NOVA_CONF_DIR/rootwrap.conf    sudochmod0644 $NOVA_CONF_DIR/rootwrap.conf    # Specify rootwrap.conf as first parameter to nova-rootwrap   ROOTWRAP_SUDOER_CMD="$NOVA_ROOTWRAP $NOVA_CONF_DIR/rootwrap.conf *"      # Set up the rootwrap sudoers for nova   TEMPFILE=`mktemp`     echo"$STACK_USER ALL=(root) NOPASSWD: $ROOTWRAP_SUDOER_CMD">$TEMPFILE    chmod0440 $TEMPFILE    sudochownroot:root $TEMPFILE    sudomv$TEMPFILE /etc/sudoers.d/nova-rootwrap}  显然,它在/etc/sudoers.d/目录下创建了nova-rootwrap的文件,里面的内容可能是:
nova ALL = (root) NOPASSWD: /usr/bin/nova-rootwrap /etc/nova/rootwrap.conf *
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 …`.
/usr/bin/nova-rootwrap是一个可执行的脚本文件,/etc/nova/rootwrap.conf则是rootwrap相关的配置,里面定义了filters-path所在路径,以及缺省的可执行命令所在路径,具体的过滤逻辑如下:
1)获取要执行的命令,如:ip
2)通过filters-path加载配置文件中定义的可以执行的命令列表
3)判断命令是否在可执行命令列表中
4)若在则通过python的subprocess模块执行Popen方法;不在则给出错误信息,退出.
这些都可以在nova的bin/nova-rootwrap文件中查看.
三.nova中执行外部命令过程分析
  所有的nova代码在执行外部命令的时候都会用到execute函数,这个函数定义在nova顶层目录下的utils.py模块下.
例如:
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   defexecute(*cmd,**kwargs):    """Convenience wrapper around oslo's execute() method."""    if'run_as_root'inkwargs andnot 'root_helper'in kwargs:         kwargs['root_helper']=_get_root_helper()    returnprocessutils.execute(*cmd,**kwargs)  然后丢给processutils中的execute,查看代码:
def execute(*cmd,**kwargs):    ...    ifrun_as_rootandhasattr(os,'geteuid') andos.geteuid() !=0:        ifnotroot_helper:             raiseNoRootWrapSpecified(                message=_('Command requested root, butdid not '                          'specify a root helper.'))        cmd=shlex.split(root_helper)+list(cmd)      cmd=map(str, cmd)      whileattempts >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的rootwrap/filters.py中,里面还定义了其他的filter(RegExp,Path,Kill,ReadFile,Ip,Env,Chaining,IpNetnsExec).
更加详细的内容请查看nova/rootwarp目录下的filters.py与wrapper.py.

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-125174-1-1.html 上篇帖子: Hadoop分布式文件系统(HDFS)和OpenStack对象存储(Swift)的技术差异 下篇帖子: openstack 不适合做公有云
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表