I'm writing a script in python 3.6 that uses many sudo commands. The script runs on linux machines, as my user. The script is creating a sort of a report, doing ssh to many servers and running commands like lsof.
I need a way of making python give my password any time I use sudo. Obviously in the first time I'll enter my password, and it can be saved in the script's memory. I've been using python subprocess to run my sudo commands, for example:
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()
Is it possible?
constraints:
Root kit is not allowed
Running the script with sudo is not an option, since the script does ssh to many servers, and for security reasons I'm not allowed to do so.
Can't change anything in sudoers file.
I suggest you use Python's "pexpect" module which does just that. It's based an "expect" and used to automate interactions with other programs. It's not part of the python standard library mind you, but you do not necessarily need root to install it if you create your own python environment.
Example:
#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
More details can be found here:
https://pexpect.readthedocs.io/en/stable/api/index.html
Hope this helps!
Spent some hours to figure out how to do it with subprocess.
So enjoy:
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()
The following answer performs three attempts to verify the access:
root
sudo
without providing passwordsudo
The calls to sudo
invoke the echo
command and check the same test that is supposed to be printed by echo
: the word 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 !")
Because you want to give your python script the sudo
password, so I think that's better for create a new user group and set up this group to your script files. Your script does not require sudo
password anymore (Still have sudo
permission).
Note: ( My answer tested on Ubuntu 14.04
. Another Linux version should be the same. )
If you are signed in as the root user, you can create a new user at any time by typing:
adduser <newuser>
or
sudo adduser <newuser>
If your new user should have the ability to execute commands with root (administrative) privileges, you will need to give the new user access to sudo
.
We can do this by using the visudo
command, which opens the appropriate configuration file in your editor. This is the safest way to make these changes.
visudo
or
sudo visudo
Search for the line that looks like this:
root ALL=(ALL:ALL) ALL
Below this line, copy the format you see here, changing only the word "root" to reference the new user that you would like to give sudo
privileges to:
root ALL=(ALL:ALL) ALL
<newuser> ALL=(ALL) NOPASSWD:ALL
Use chown
to change ownership of your python script.
sudo chown <newuser>: <python script>
After that you could run your script under sudo
permission without the password.
Note: ( I suggest you this way because you want to put your sudo
password into source code. However, please careful with your script. It has more powerful... )
I think you should do it by using Paramiko library. Make sure you install paramiko before importing it. Check this
Below is a sample code. Test it before you use it.
$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()
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.