简体   繁体   中英

How to make python script to give sudo prompt my password

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:

  • Check if the current user is root
  • Call sudo without providing password
  • Ask the user for a password and call sudo

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM