在python脚本中更改为sudo user

在python脚本中更改为sudo user,python,security,sudo,Python,Security,Sudo,我有个问题。我正在编写一个软件,它需要执行一个需要用户处于sudo模式的操作。运行“sudo python filename.py”不是一个选项,这就引出了我的问题。是否有一种方法可以通过python脚本中途更改为sudo,安全性不是问题,因为用户将知道sudo密码程序应以以下方式运行以说明问题 以普通用户身份运行的程序 。。。。。。执行操作 用户输入sudo密码 用户已更改为sudo 运行需要sudo权限的子程序 在触发偶数(子程序结束)时,用户再次成为正常用户 。。。。。。执行操作 我的问题

我有个问题。我正在编写一个软件,它需要执行一个需要用户处于sudo模式的操作。运行“sudo python filename.py”不是一个选项,这就引出了我的问题。是否有一种方法可以通过python脚本中途更改为sudo,安全性不是问题,因为用户将知道sudo密码程序应以以下方式运行以说明问题

  • 以普通用户身份运行的程序
  • 。。。。。。执行操作
  • 用户输入sudo密码
  • 用户已更改为sudo
  • 运行需要sudo权限的子程序
  • 在触发偶数(子程序结束)时,用户再次成为正常用户
  • 。。。。。。执行操作
  • 我的问题在于第3步,任何你可以建议的指针或框架都会有很大的帮助

    干杯


    克里斯

    不要试着让自己做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")
    

    不要试图让自己做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")
    

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


    在这种情况下,您需要sudo权限来运行特定的程序。在这种情况下,只需转到“sudo theprogram”即可。

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


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

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

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

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

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

    我最近在编写系统安装脚本时处理了这个问题。要切换到超级用户权限,我将subprocess.call()与“sudo”一起使用:

    #!/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()
    使命令可用于
    子流程.call()
    。如果要使用命令的输出,可以使用
    子流程。请检查\u output()
    。还有一个名为“sh”(sh)的软件包可用于此目的。

    我最近在编写系统安装脚本时处理了这个问题。要切换到超级用户权限,我将subprocess.call()与“sudo”一起使用:

    #!/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()
    使命令可用于
    子流程.call()
    。如果要使用命令的输出,可以使用
    子流程。请检查\u output()
    。还有一个名为“sh”(sh)的包可用于此目的。

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

    这样,只有setuid可执行文件中的活动以root身份运行,但是执行此操作不需要sudo,即root权限。只有创建/修改setuid可执行文件才需要sudo

    这里有一些安全问题,例如确保setuid可执行程序正确地清理任何用户输入(例如参数),以便它不会被欺骗去做它不应该做的事情(问题)

    参考:


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

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

    这样,只有setuid可执行文件中的活动以root身份运行,但是执行此操作不需要sudo,即root权限。只有创建/修改setuid可执行文件才需要sudo

    这里有一些安全问题,例如确保setuid可执行程序正确地清理任何用户输入(例如参数),以便它不会被欺骗去做它不应该做的事情(问题)

    参考:


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

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

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

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

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

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

    sudo.tcl

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

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

    然后运行sudo.py。

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

    import subprocess
    subprocess.check_output("sudo -i -u " + str(username) + " ls -l", shell=True).decode("utf-8").strip()
    
    sudo.tcl

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

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

    然后运行sudo.py。

    这不应该是
    os.geteuid()!=0
    ?这不是一个很好的解决方案-如果只有脚本的一部分需要root怎么办?这个问题特别要求不要运行整个程序。@JakobBowyer,他知道sudo还会存在吗?@Thor18其他网站反对使用旧线程发布,但堆栈溢出已经看到了曙光,并鼓励对其进行提问对以后的其他人有用的答案,这意味着用旧答案修复或指出问题很重要。这不应该是
    os.geteuid()!=0
    ?这不是一个很好的解决方案
    import subprocess
    subprocess.check_output("sudo -i -u " + str(username) + " ls -l", shell=True).decode("utf-8").strip()