在python脚本中更改为sudo用户

时间:2011-03-04 09:25:37

标签: python security sudo

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

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

    干杯

    克里斯

8 个答案:

答案 0 :(得分:18)

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

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

答案 1 :(得分:9)

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

答案 2 :(得分:5)

我最近在制作系统安装脚本时遇到了这个问题。要切换到超级用户权限,我使用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()使您的命令可用于subprocess.call()。如果要使用命令的输出,可以使用subprocess.check_output()。还有一个名为'sh'(http://amoffat.github.com/sh/)的包,您可以将其用于此目的。

答案 3 :(得分:2)

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

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

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

REF: http://en.wikipedia.org/wiki/Setuid#setuid_on_executables

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

答案 4 :(得分:2)

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

sudo.tcl

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

sudo.py

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

然后运行sudo.py。

答案 5 :(得分:0)

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

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

答案 6 :(得分:0)

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

答案 7 :(得分:-4)

您是在谈论在执行过程中有一半的用户输入密码? raw_input()可以从控制台获取用户输入,但不会屏蔽密码。

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