【问题标题】:Change to sudo user within a python script在 python 脚本中更改为 sudo 用户
【发布时间】:2011-07-08 16:36:26
【问题描述】:

我有问题。我正在编写一个软件,它需要执行需要用户处于 sudo 模式的操作。运行 'sudo python filename.py' 不是一个选项,这让我想到了我的问题。有没有办法通过 python 脚本中途更改为 sudo,安全不是问题,因为用户将知道程序应该运行的 sudo 密码,以说明问题

  1. 程序以普通用户身份运行
  2. ......执行操作
  3. 用户输入 sudo 密码
  4. 用户更改为 sudo
  5. 运行需要 sudo 权限的子程序
  6. 触发偶数(子程序结束)用户再次变为普通用户
  7. ......执行操作

我的问题在于第 3 步,您可以建议的任何指针或框架都会有很大帮助。

干杯

克里斯

【问题讨论】:

  • 我认为,一个完美的解决方案将具有以下品质,无论是否可能: 1. 它不涉及重新启动脚本。 2. 它不涉及在 Python 脚本中调用第二个 Python 脚本。 3. root权限只适用于脚本的指定部分(不是开头,也不一定是结尾)。

标签: python security sudo


【解决方案1】:

最好以提升的权限运行尽可能少的程序。您可以通过subprocess.call()函数运行需要更多权限的小部分,例如

import subprocess
returncode = subprocess.call(["/usr/bin/sudo", "/usr/bin/id"])

【讨论】:

    【解决方案2】:

    不要试图让自己 sudo 只是检查你是否是,如果不是则错误

    class NotSudo(Exception):
        pass
    
    if os.getuid() != 0:
        raise NotSudo("This program is not run as sudo or elevated this it will not work")
    

    【讨论】:

    • 不应该是os.geteuid() != 0吗?
    • 这不是一个很好的解决方案 - 如果只有部分脚本需要 root 怎么办?
    • 特别要求不提升整个程序运行的问题。
    • @JakobBowyer 知道 sudo 还会在吗?
    • @thorr18 其他网站反对在旧线程中发帖,但堆栈溢出已经看到了曙光,并鼓励提出对以后其他人有用的问题的答案,这意味着修复或指出与旧答案很重要。
    【解决方案3】:

    我最近在制作系统安装脚本时处理了这个问题。为了切换到超级用户权限,我使用了带有 'sudo' 的 subprocess.call():

    #!/usr/bin/python
    
    import subprocess
    import shlex
    import getpass
    
    print "This script was called by: " + getpass.getuser()
    
    print "Now do something as 'root'..."
    subprocess.call(shlex.split('sudo id -nu'))
    
    print "Now switch back to the calling user: " + getpass.getuser()
    

    请注意,您需要使用shlex.split() 才能使您的命令可用于subprocess.call()。如果要使用命令的输出,可以使用subprocess.check_output()。还有一个名为 'sh' (http://amoffat.github.com/sh/) 的包可以用于此目的。

    【讨论】:

    • sudo: 没有 tty 并且没有指定 askpass 程序
    【解决方案4】:

    使用 Tcl 和 Expect,加上子流程来提升自己。所以基本上是这样的:

    sudo.tcl

    spawn sudo
    expect {
        "Password:" {
            send "password"
        }
    }
    

    sudo.py

    import subprocess
    subprocess.call(['tclsh', 'sudo.tcl'])
    

    然后运行 ​​sudo.py。

    【讨论】:

    • 当我运行 Python 脚本时,我得到了invalid command name "spawn"(这里的一切都和你的完全一样)。我应该做些什么不同的事情?
    • 也许使用 Python 的 pexpect 模块和 pexpect.spawnu 类将有助于创建全 Python 解决方案。如果您知道如何使用它,请随时将其编辑到您的答案中。 (并不是说我需要一个全 Python 的解决方案。只要它对我有用,那就太好了。)
    • 我需要一个全 python 解决方案。你有吗?
    【解决方案5】:

    如果您能够将需要提升权限的必要功能封装在单独的可执行文件中,则可以使用可执行文件上的 setuid 位 程序,并从您的用户级 python 脚本中调用它。

    这样,只有 setuid-executable 中的 Activity 以 root 身份运行,但执行此操作不需要 sudo,即 root 权限。只有创建/修改 setuid-executable 需要 sudo。

    有一些安全隐患,例如确保您的 setuid 可执行程序正确地清理任何用户输入(例如,参数),这样它就不会被欺骗去做不应该做的事情(混淆代理问题)。

    参考: http://en.wikipedia.org/wiki/Setuid#setuid_on_executables

    编辑:setuid 似乎只适用于已编译的可执行文件(二进制文件),而不适用于解释的脚本,因此您可能需要使用已编译的 setuid 包装器。

    【讨论】:

    • 嗯,作者要求提供 python 脚本,所以 - 正如你所写 - setuid 没用。
    【解决方案6】:

    您可以使用 setuid 来设置用户的 uid。但是出于明显的安全原因,您只能在您是 root(或程序具有 suid root 权限)时执行此操作。这两个都可能是个坏主意。

    在这种情况下,您需要 sudo 权限才能运行特定程序。在这种情况下,只需改为“sudo theprogram”即可。

    【讨论】:

      【解决方案7】:
      import subprocess
      subprocess.check_output("sudo -i -u " + str(username) + " ls -l", shell=True).decode("utf-8").strip()
      

      【讨论】:

        【解决方案8】:

        您是说在执行过程中让用户输入密码吗? raw_input() 可以从控制台获取用户输入,但不会屏蔽密码。

        >>>> y = raw_input()
        somehting
        >>> y
        'somehting'
        

        【讨论】:

        • 没有。我们谈论的是权限,尽管授予权限的程序往往会要求输入密码(但这不是关键元素)。 (就像在程序中途使用 sudo 而不使用第二个脚本等。)
        猜你喜欢
        • 1970-01-01
        • 2012-10-14
        • 1970-01-01
        • 2012-07-23
        • 1970-01-01
        • 2020-05-29
        • 1970-01-01
        相关资源
        最近更新 更多