[代碼修訂版] 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.

相關文章
相關標籤/搜索