我在python 3.6中编写了一个使用许多sudo命令的脚本。该脚本作为我的用户在linux机器上运行。该脚本正在创建一种报告,对许多服务器执行ssh并运行lsof等命令
我需要一种方法让python在我使用sudo时随时提供密码。显然,在我第一次输入密码时,它可以保存在脚本的内存中。
我一直在使用python子进程来运行我的sudo命令,例如:
cmd = SSH + '-t ' + source + " ' " + SUDO + "-k " + LSOF + "-p " + pid + " ' " output = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True, universal_newlines=True)
(out,error) = output.communicate()
有可能吗?
限制:
根套件不允许
使用sudo运行脚本不是一个选项,因为脚本会ssh到许多服务器,出于安全考虑,我不允许这样做。
无法改变sudoers文件中的任何内容。
答案 0 :(得分:1)
我建议你使用Python的“pexpect”模块来做到这一点。 它基于“期望”并用于自动化与其他程序的交互。 它不是python标准库的一部分,但如果您创建自己的python环境,则不一定需要root来安装它。
示例:
#import the pexpect module
import pexpect
# here you issue the command with "sudo"
child = pexpect.spawn('sudo /usr/sbin/lsof')
# it will prompt something like: "[sudo] password for < generic_user >:"
# you "expect" to receive a string containing keyword "password"
child.expect('password')
# if it's found, send the password
child.sendline('S3crEt.P4Ss')
# read the output
print(child.read())
# the end
更多细节可以在这里找到:
https://pexpect.readthedocs.io/en/stable/api/index.html
希望这有帮助!
答案 1 :(得分:0)
因为您想为您的python脚本提供sudo
密码,所以我认为最好创建一个新用户组并将此组设置为您的脚本文件。您的脚本不再需要sudo
密码(仍有sudo
权限)。
注意:(我的答案在Ubuntu 14.04
上测试。另一个Linux版本应该是相同的。)
如果您以root用户身份登录,则可以通过键入以下内容随时创建新用户:
adduser <newuser>
或
sudo adduser <newuser>
如果您的新用户应该能够执行具有root(管理)权限的命令,则需要授予新用户sudo
的访问权限。
我们可以使用visudo
命令执行此操作,该命令会在编辑器中打开相应的配置文件。这是进行这些更改的最安全方法。
visudo
或
sudo visudo
搜索如下所示的行:
root ALL=(ALL:ALL) ALL
在此行下方,复制您在此处看到的格式,仅更改“root”一词,以引用您希望赋予sudo
权限的新用户:
root ALL=(ALL:ALL) ALL
<newuser> ALL=(ALL) NOPASSWD:ALL
使用chown
更改python脚本的所有权。
sudo chown <newuser>: <python script>
之后,您可以在sudo
权限下运行您的脚本而无需密码。
注意:(我建议你这样做,因为你想把你的sudo
密码放到源代码中。但是,请注意你的脚本。它有更强大的功能... )
答案 2 :(得分:0)
我认为你应该使用Paramiko库来做到这一点。确保在导入之前安装paramiko。 Check this
以下是示例代码。在使用它之前测试它。
$pip install paramiko
import paramiko
ssh_client = paramiko.SSHClient()
ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
pid = 12345 # Modify this per your requirement
try:
ssh_client.connect('source',username='user',password='pwd')
stdin,stdout,stderr = ssh_client.exec_command('sudo -k lsof -p '+pid)
stdin.write('pwd\n')
stdin.flush()
result = stdout.read.splitlines()
except paramiko.SSHException:
print('Connection Failed')
quit()
答案 3 :(得分:0)
花几个小时弄清楚如何使用子流程。
所以享受:
import getpass
import subprocess
sudo_password = getpass.getpass(prompt='sudo password: ')
p = subprocess.Popen(['sudo', '-S', 'ls'], stderr=subprocess.PIPE, stdout=subprocess.PIPE, stdin=subprocess.PIPE)
try:
out, err = p.communicate(input=(sudo_password+'\n').encode(),timeout=5)
except subprocess.TimeoutExpired:
p.kill()
答案 4 :(得分:0)
以下答案执行三种尝试来验证访问权限:
root
sudo
sudo
对sudo
的调用将调用echo
命令,并检查应该由echo
打印的同一测试:单词OK
。
import os, subprocess
from getpass import getpass
def is_root():
return os.geteuid() == 0
def test_sudo(pwd=""):
args = "sudo -S echo OK".split()
kwargs = dict(stdout=subprocess.PIPE,
encoding="ascii")
if pwd:
kwargs.update(input=pwd)
cmd = subprocess.run(args, **kwargs)
return ("OK" in cmd.stdout)
def prompt_sudo():
ok = is_root() or test_sudo()
if not ok:
pwd = getpass("password: ")
ok = test_sudo(pwd)
return ok
if prompt_sudo():
print("Access granted !")
else:
print("Access denied !")