检查脚本用户是否具有类似root权限的最佳方法是什么?

Pau*_*man 64 python privileges root

我有一个Python脚本,它将执行许多需要根级权限的事情,例如在/ etc中移动文件,使用apt-get安装,等等.我目前有:

if os.geteuid() != 0:
    exit("You need to have root privileges to run this script.\nPlease try again, this time using 'sudo'. Exiting.")
Run Code Online (Sandbox Code Playgroud)

这是检查的最佳方式吗?还有其他最佳做法吗?

Ale*_*lli 64

os.geteuid得到有效的用户ID,这正是你想要的,所以我想不出更好的方法来执行这样的检查.一点不确定的是标题中的"root-like":你的代码完全 检查root,没有关于它的"喜欢",事实上我不知道"root-like而不是root"是什么意思 - 所以如果你的意思不同于"完全根",也许你可以澄清一下,谢谢!

  • 有效UID == 0意味着"root"的假设在UNIX代码中非常根深蒂固(包括大多数类UNIX内核源代码).从技术上讲,Linux下的假设不一定正确.Linux"功能"模型允许系统使用通过进程继承(lcap2包装器)或可能通过扩展文件系统属性委派的更细粒度的控件来运行.此外,SELinux功能可能会对此类假设造成严重破坏.对于99%的系统,geteuid()== 0就足够了; 其余的尝试:...除了:是你的朋友. (8认同)
  • 我假设Paul担心不同的系统使用不同的uid给管理员.通常id(root)== 0,但它不是必须的,在某些系统上它实际上并不相等. (2认同)

msw*_*msw 27

根据"更容易请求宽恕而不是许可"原则:

try:
    os.rename('/etc/foo', '/etc/bar')
except IOError as e:
    if (e[0] == errno.EPERM):
       print >> sys.stderr, "You need root permissions to do this, laterz!"
       sys.exit(1)
Run Code Online (Sandbox Code Playgroud)

如果你担心不可移植性,os.geteuid()你可能不应该捣乱/etc.

  • 根据情况,这实际上可能更糟.嗯,弗洛里安有一个观点. (4认同)
  • 有时,在开始进行更改之前,您需要知道任务的所有部分是否都会成功。我不想执行步骤 1、2 和 3 只是为了发现我无法执行步骤 4,并希望我可以撤销已完成的操作。 (2认同)

jca*_*llo 12

您可以提示用户进行sudo访问:

import os, subprocess

def prompt_sudo():
    ret = 0
    if os.geteuid() != 0:
        msg = "[sudo] password for %u:"
        ret = subprocess.check_call("sudo -v -p '%s'" % msg, shell=True)
    return ret

if prompt_sudo() != 0:
    # the user wasn't authenticated as a sudoer, exit?
Run Code Online (Sandbox Code Playgroud)

sudo -v交换机更新用户的缓存的凭据(见图man sudo).


dim*_*4eg 8

对于Linux:

def is_root():
    return os.geteuid() == 0
Run Code Online (Sandbox Code Playgroud)


Jim*_*nis 7

如果您真的希望您的代码在各种Linux配置中都是健壮的,我建议您考虑有人可能正在使用SELinux或文件系统ACL或Linux内核中的"功能"功能的极端情况.因为2.2左右.您的进程可能正在使用SELinux或某些Linux功能库(如libcap2 libcap-ng)或fscapselfcap之类的包装器上运行,这些包装通过更为异国情调的东西,如Niels Provos的精彩且令人遗憾的不太受欢迎的systrace系统.

所有这些都是您的代码可能以非root身份运行的方式,但您的流程可能已被委派了必要的访问权限,无需EUID == 0即可执行其工作.

因此,我建议您考虑通过包装由于权限或异常处理代码的其他问题而可能失败的操作来更加Python地编写代码.如果您正在进行各种操作(例如使用subprocess模块),您可以提供所有此类调用的前缀sudo(例如,作为命令行,环境或.rc文件选项).如果它以交互方式运行,您可以提供重新执行任何引发权限相关异常的命令sudo(可选地,只有sudo在os.environ ['PATH']上找到).

总的来说,大多数Linux和UNIX系统的大多数管理仍由"root"特权用户完成.然而,它是老派,作为程序员,我们应该尝试支持更新的模型.尝试操作并让异常处理完成其工作允许您的代码在透明地允许您需要的操作的任何系统下工作,并且知道并准备好使用sudo是一个很好的接触(因为它是迄今为止最普遍的用于受控委托系统特权的工具).


vos*_*n77 7

我喜欢在环境变量中检查 sudo :

如果不是 os.environ.keys() 中的“SUDO_UID”:
  打印“此程序需要超级用户权限。”
  sys.exit(1)


Tho*_*ler 7

import os

def check_privileges():

    if not os.environ.get("SUDO_UID") and os.geteuid() != 0:
        raise PermissionError("You need to run this script with sudo or as root.")
Run Code Online (Sandbox Code Playgroud)

SUDO_UID如果脚本未使用 运行,则不可用sudo