[代码修订版] Python 踩坑之旅 [进程篇其四] 踩透 uid euid suid gid egid sgid的坑坑洼洼

代码示例支持
平台: Centos 6.3
Python: 2.7.14
代码示例: 公众号点击 踩坑之旅菜单 或者 https://github.com/mythmgn/awesome_py_traps

1.1 踩坑案例

小明是个服务器管理员, 他从老管理员手里接手了一个很是繁琐的运维工做: 短暂受权root 帐号给不一样的 team 接口人运行备份任务c++

该运维任务有几个特色:git

  1. 任务需且仅需运行在 root 下
    • root 帐号只能短暂受权给各个小组
    • 经过帐号管理平台, 提早申请一段时间的临时密码
    • 将临时密码提供给小组接口人
    • 时间超时后密码自动变动
  2. 不一样 team 分时使用, 没法并发使用

小明很是烦躁, 为了填上这个坑, 他调研了填坑解法.github

1.2 填坑解法

填坑解法知足:bash

  • 短时出借权限
    • (在权限范围内)执行该任务时才能使用 root 权限
    • 作完任务当即失去 root 权限
  • 权限范围必须清晰
    • 能作什么
      • 能作数据备份
    • 不能作什么
      • 除了数据备份其余什么都不在 root 权限下作

具体作法:服务器

  1. 利用c/c++程序出借部分 root 权限 (完整代码关注公号点击菜单查看)并发

    • 该c程序限定执行的备份操做为 python 代码 euid_backup.py
    int main(int argc, char **argv){
        if(0==isRunUnderRoot()){
            fprintf(stderr,"does not run under +S attribute. Exiting....\n");
            return EXIT_FAILURE;
        }
        exit(runNewProcess("./", "env python ./euid_backup.py"));
    }
    • euid_backup.py owner 为 root, 非 root 用户不许更改备份操做内容
  2. 为生成的执行文件euid_cp及euid_backup.py 设置root权限借用运维

    sudo rm -f ./euid_cp
    sudo gcc euid_cp.c -o euid_cp
    # 设置文件owner为root, 非root用户没法更改执行内容
    sudo chown root euid_cp euid_backup.py
    # 设置a. 非root只读  b. 增长执行权限
    sudo chmod 755 euid_cp
    # 设置stick bit, 执行euid_cp便可短暂获取root 权限, 执行任务
    sudo chmod +s euid_cp
  • euid_backup.py Python 代码执行具体的备份任务ui

    from __future__ import print_function
    import os
    import time
    
    print('euid is {0}'.format(os.geteuid()))
    
    if os.geteuid() == 0:
        print('start to copy under root')
        print('do some operations here')
        time.sleep(2)
        print('end copying things')
        print('drop privileges from root')
    else:
        print('non-root, euid {0} will exit'.format(os.geteuid()))

运行试验:code

  1. 经过 ./euid_cp 执行, 能够在非 root 下执行 root 权限才能执行的备份任务(euid_backup.py)
    • 执行环境: Mac 10.14.4 (18E226)
  2. 直接执行备份任务(euid_backup.py) 会失败, 没有权限
    • 执行环境: 同上

1.3 坑位分析

  1. uid / euid / suid 是什么

    • uid 是用户的 userid
      • 登录后, 在不切换用户状况下 uid 通常不变
    • euid 是用户的有效 id
      • euid 在正常执行状况下通常等于uid
      • euid 通常决定了用户对系统中存储介质的access (访问) 权限
    • suid (saved uid) 是文件在被访问过程当中的短暂切换用户euid的属性设置
      • 简单来讲, suid让本没有权限的用户能够短暂访问这些资源
      • suid 在执行过程当中进行了权限切换
        • 执行之初, 切换到这个saved uid(文中为 root)
        • fork执行过程当中, euid == suid
        • 执行完成后, euid 在切换回 uid
  2. gid, egid 等同理, [*]uid的判断优先

1.4 技术关键字

  • uid euid suid
  • gid egid sgid

1.5 坑后思考

  1. 为何本文没有直接对euid_backup.py文件进行设置+s操做, 而是用可执行的c/c++程序作执行器

  2. Linux 系统里的passwd 程序是否也是这个原理? 它跟哪些文件/命令相关

下期坑位预告

进程篇其五之眼花缭乱的进程间通讯


Life is short. We use Python.

相关文章
相关标签/搜索