在 python 脚本中更改为 sudo 用户

发布于 2024-10-20 06:45:56 字数 396 浏览 6 评论 0 原文

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

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

我的问题在于步骤3,任何指针或者你建议的框架会有很大帮助。

干杯

克里斯

I have a problem. I am writing a piece of software, which is required to perform an operation which requires the user to be in sudo mode. running 'sudo python filename.py' isn't an option, which leads me to my question. Is there a way of changing to sudo half way through a python script, security isn't an issue as the user will know the sudo password the program should run in the following way to illustrate the issue

  1. program running as normal user
  2. ...... performing operations
  3. user enters sudo password
  4. user changed to sudo
  5. sub program requiring sudo permission is run
  6. on trigger even (end of sub program) user becomes normal user again
  7. ...... performing operations

My problem lies in step 3, any pointers or frameworks you could suggest would be of great help.

Cheers

Chris

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

梦境 2024-10-27 06:45:56

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

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

It is better to run as little of the program as possible with elevated privileges. You can run the small part that needs more privilege via the subprocess.call() function, e.g.

import subprocess
returncode = subprocess.call(["/usr/bin/sudo", "/usr/bin/id"])
画中仙 2024-10-27 06:45:56

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

Don't try and make yourself sudo just check if you are and error if your not

class NotSudo(Exception):
    pass

if os.getuid() != 0:
    raise NotSudo("This program is not run as sudo or elevated this it will not work")
酒绊 2024-10-27 06:45:56

我最近在制作系统安装脚本时处理了这个问题。要切换到超级用户权限,我将 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/ ),您可以将其用于此目的。

I've recently dealt with this problem while making a system installation script. To switch to superuser permissions, I used subprocess.call() with '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()

Note that you need to use shlex.split() to make your command usable for subprocess.call(). If you want to use the output from a command, you can use subprocess.check_output(). There is also a package called 'sh' (http://amoffat.github.com/sh/) that you can use for this purpose.

老娘不死你永远是小三 2024-10-27 06:45:56

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

sudo.tcl

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

sudo.py

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

然后运行 ​​sudo.py。

Use Tcl and Expect, plus subprocess to elevate yourself. So basically it's like this:

sudo.tcl

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

sudo.py

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

And then run sudo.py.

少跟Wǒ拽 2024-10-27 06:45:56

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

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

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

参考:
编辑

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

If you are able to encapsulate just the necessary functionality requiring elevated privileges in a separate executable, you could use the setuid bit on the executable program, and call it from your user-level python script.

In this way, only the activity in the setuid-executable run as root, however executing this does NOT require sudo, i.e., root privileges. Only creating/modifying the setuid-executable requires sudo.

There are a few security implications, such as ensuring that your setuid executable program properly sanitizes any user input (e.g., parameters), so that it cannot be tricked into doing something it should not (confused deputy problem).

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

edit: setuid only seems to work for compiled executables (binaries), and not interpreted scripts, so you may need to use a compiled setuid wrapper.

人间☆小暴躁 2024-10-27 06:45:56

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

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

You can use setuid to set the users uid. But for obvious security reasons you can only do this if you are root (or the program has suid root rights). Both of these are probably a bad idea.

In this case you need to sudo rights to run a specific program. In that case just sub to "sudo theprogram" instead.

请你别敷衍 2024-10-27 06:45:56
import subprocess
subprocess.check_output("sudo -i -u " + str(username) + " ls -l", shell=True).decode("utf-8").strip()
import subprocess
subprocess.check_output("sudo -i -u " + str(username) + " ls -l", shell=True).decode("utf-8").strip()
总攻大人 2024-10-27 06:45:56

不确定这对您有何帮助,并且它没有回答问题,但是,当您遇到所需的“root”用户问题并且您需要成为“root”才能阅读时,这是一种解决方法/写入文件夹或文件。

然后您可以更改权限并随后将其切换回来。我将其放在 docker-compose 文件中,该文件启动了一个将应用程序部署到服务器的 Python 脚本。这个解决方法是我让它运行的唯一方法。我什至不需要更改容器 bash 的权限,而是由脚本执行此操作,并且只需要密码两次。

在此解决方法之前,我尝试更改为 root 用户,然后使用该 root 用户执行大块代码,但无济于事。

run("ls -ld /usr/local/my_project/")
run("sudo chmod o+wx /usr/local/my_project/")
run("ls -ld /usr/local/my_project/")
my_code_that_needed_root_rights_and_now_runs_without_root_user()
run("sudo chmod 774 /usr/local/my_project/")
run("ls -ld /usr/local/my_project/")

以及输出:

[server_connection] run: ls -ld /usr/local/my_project/
[server_connection] Login password for 'my_user': 
[server_connection] out: drwxrwxr-- 45 root 100005 4096 Apr 25 13:52 /usr/local/my_project/
[server_connection] out: 

[server_connection] run: sudo chmod o+wx /usr/local/my_project/
[server_connection] out: [sudo] password for my_user: 
[server_connection] out: 

[server_connection] run: ls -ld /usr/local/my_project/
[server_connection] out: drwxrwxrwx 45 root 100005 4096 Apr 25 13:52 /usr/local/my_project/
[server_connection] out: 

[...]    

[server_connection] run: sudo chmod 774 /usr/local/my_project/
[server_connection] out: [sudo] password for my_user: 
[server_connection] out: 

[server_connection] run: ls -ld /usr/local/my_project/
[server_connection] out: drwxrwxr-- 46 root 100005 4096 Apr 25 14:02 /usr/local/my_project/
[server_connection] out: 

此后,服务器文件夹具有与之前相同的权限,并且代码不需要root用户来运行。

Not sure how this would help you, and it does not answer the question, yet, it is a workaround to think about when you run into a needed "root" user problem and you need to be "root" only to read / write in a folder or file.

You can then change the permissions and also switch them back afterwards. I had this in a docker-compose file that started a Python script that deployed an application to a server. This workaround was the only way how I got it to run. I do not even need to change the permissions from the container bash, instead, the script does that, and only the password is needed twice.

Before this workaround, I tried to change to the root user and then execute large blocks of code with that root user, to no avail.

run("ls -ld /usr/local/my_project/")
run("sudo chmod o+wx /usr/local/my_project/")
run("ls -ld /usr/local/my_project/")
my_code_that_needed_root_rights_and_now_runs_without_root_user()
run("sudo chmod 774 /usr/local/my_project/")
run("ls -ld /usr/local/my_project/")

And the output:

[server_connection] run: ls -ld /usr/local/my_project/
[server_connection] Login password for 'my_user': 
[server_connection] out: drwxrwxr-- 45 root 100005 4096 Apr 25 13:52 /usr/local/my_project/
[server_connection] out: 

[server_connection] run: sudo chmod o+wx /usr/local/my_project/
[server_connection] out: [sudo] password for my_user: 
[server_connection] out: 

[server_connection] run: ls -ld /usr/local/my_project/
[server_connection] out: drwxrwxrwx 45 root 100005 4096 Apr 25 13:52 /usr/local/my_project/
[server_connection] out: 

[...]    

[server_connection] run: sudo chmod 774 /usr/local/my_project/
[server_connection] out: [sudo] password for my_user: 
[server_connection] out: 

[server_connection] run: ls -ld /usr/local/my_project/
[server_connection] out: drwxrwxr-- 46 root 100005 4096 Apr 25 14:02 /usr/local/my_project/
[server_connection] out: 

After this, the server folder had the same permissions as before, and the code did not need the root user to run through.

始于初秋 2024-10-27 06:45:56

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

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

Are you talking about having the user input password half way through your execution? raw_input() can take a user input from console, but it will not mask the password.

>>>> y = raw_input()
somehting
>>> y
'somehting'
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文