以sudo方式运行python调用
我们有一个用Python写的安装脚本,之前是以root用户身份运行的,现在我们想以一个有特定权限的普通用户(sudoer用户)来运行它。问题是我们的代码里到处都是像os.makedirs和open(filename)这样的调用。
open(filename) as sudo ?
os.makedirs as sudo ?
... as sudo ?
不适合我们的解决方案:
直接用“sudo python script.py”来运行整个安装脚本 这样做对我们来说有安全隐患,我们需要避免这种方式。
Popen(["sudo","..."]) 这种方法在非Unix系统上支持不好,而且需要重写所有代码。
2 个回答
一般来说,当你代码中的一小部分需要更高的权限来运行,但其他部分不安全时,你可以这样做:
你可以以管理员身份运行你的主脚本。但在启动时,它会创建一个子进程(这个子进程仍然是管理员权限),然后立即降低权限。当你需要以管理员身份做某件事时,你可以使用一些安全的通信方式(比如socketpair
,具体是否安全还要看你的设计)来请求子进程代你执行,并把结果发回来。虽然在Windows上细节会有所不同,但基本思路是一样的。
不过,还有其他的选择,包括:
- 创建setuid程序,并从一个非管理员的父进程中运行它们。这个方法在Windows上不可行,而且在Unix系统中处理子脚本时可能不太合适。
- 把你的应用重新设计成一个守护进程/服务,这个服务由系统的守护进程/服务管理器单独管理,并以管理员身份运行,而主应用则通过IPC与这个守护进程通信。
- 存储可以用来模拟管理员身份的凭证(理想情况下只在短暂的子进程或线程中使用)。这个方法在Windows上效果很好,但在Unix上效果就不太理想。
不过,在这种情况下,有一个更简单的解决方案:你似乎只需要管理员权限来读取(也可能写入?)你安装的、由其他用户拥有的文件。只需让这些文件对组可读(也可能可写),然后以一个属于该组的低权限用户身份运行脚本。
我对第二个要求有点意见。你需要用到sudo(超级用户权限),但又想要你的程序不依赖于特定平台,这怎么可能呢?如果这真的是你的目标,那你就得重新考虑第一个要求,或者检测一下你用的是什么操作系统,如果是*nix(类Unix系统),就给你的命令加上sudo。此外,除了用sudo运行整个脚本,你还得改代码,所以第二个要求的那部分其实没什么意义。不过,在Popen命令中使用sudo其实没什么必要。你必须为那些特定的命令启用无密码的sudo,而我觉得这比直接用UID 0(超级用户)运行整个脚本要危险得多。不过,看起来你只是和文件系统打交道,正如有人评论的那样,这就引出了一个问题:你是否可以直接给你的用户权限,让他们访问所需的文件呢?
简单来说,要么给运行程序的用户权限去访问这些文件,要么退一步想想,为什么会出现这个问题,这真的是解决你问题的最佳方案吗?