Как запустить sudo с paramiko? (Python)
Что я пробовал:
-
invoke_shell()
затем channel.send
su
а затем отправляет пароль, в результате которого не будет root -
invoke_shell()
а затем channel.exec_command
приводит к ошибке "Channel Closed" -
_transport.open_session()
тогда channel.exec_command
привел к тому, что не был root -
invoke_shell()
тогда запись в stdin и очистка привела к тому, что он не был root
Ответы
Ответ 1
проверьте этот пример:
ssh.connect('127.0.0.1', username='jesse',
password='lol')
stdin, stdout, stderr = ssh.exec_command(
"sudo dmesg")
stdin.write('lol\n')
stdin.flush()
data = stdout.read.splitlines()
for line in data:
if line.split(':')[0] == 'AirPort':
print line
Пример, найденный здесь с дополнительными пояснениями:
http://jessenoller.com/2009/02/05/ssh-programming-with-paramiko-completely-different/
Надеюсь, что это поможет!
Ответ 2
invoke_shell
работал у меня следующим образом:
import paramiko, getpass, re, time
ssh_client = paramiko.SSHClient()
ssh_client.connect( host )
sudo_pw = getpass.getpass("sudo pw for %s: " % host)
command = "sudo magicwand"
channel = ssh_client.invoke_shell()
channel.send( command )
# wait for prompt
while not re.search(".*\[sudo\].*",channel.recv(1024)): time.sleep(1)
channel.send( "%s\n" % sudo_pw )
Ответ 3
Мне жаль, что у меня нет времени на подробные ответы, но я смог реализовать команды sudo на paramiko, используя this сообщить
import paramiko
l_password = "yourpassword"
l_host = "yourhost"
l_user = "yourusername"
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(l_host, username=l_user, password=l_password)
transport = ssh.get_transport()
session = transport.open_session()
session.set_combine_stderr(True)
session.get_pty()
#for testing purposes we want to force sudo to always to ask for password. because of that we use "-k" key
session.exec_command("sudo -k dmesg")
stdin = session.makefile('wb', -1)
stdout = session.makefile('rb', -1)
#you have to check if you really need to send password here
stdin.write(l_password +'\n')
stdin.flush()
for line in stdout.read().splitlines():
print 'host: %s: %s' % (l_host, line)
Ответ 4
You Can use channel to send sudo password:
passwd = getpass.getpass()
ssh = paramiko.client.SSHClient()
ssh.set_missing_host_key_policy(paramiko.client.AutoAddPolicy())
ssh.load_system_host_keys()
ssh.connect(host, allow_agent=True)
chan = ssh.get_transport().open_session()
chan.get_pty()
chan.setblocking(1)
chan.exec_command("sudo -k dmesg")
while chan.recv_ready()==False:
stdout=chan.recv(4096)
if re.search('[Pp]assword', stdout):
chan.send(passwd+'\n')
time.sleep(1)
while chan.recv_ready():
stdout += chan.recv(20000)
chan.close()
ssh.close()de here
Ответ 5
AlexS
Тонко настроенный ответ (который я теперь использую для его создания):
def sudo_run_commands_remote(command, server_address, server_username, server_pass, server_key_file):
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname=server_address,
username=server_username,
password=server_pass,
key_filename=server_key_file)
session = ssh.get_transport().open_session()
session.set_combine_stderr(True)
session.get_pty()
session.exec_command("sudo bash -c \"" + command + "\"")
stdin = session.makefile('wb', -1)
stdout = session.makefile('rb', -1)
stdin.write(server_pass + '\n')
stdin.flush()
print(stdout.read().decode("utf-8"))
Удалите часть key_filename
метода connect
, если вы не используете файл ключа, и, наоборот, если вы используете только ключ без пароля, удалите часть password
.
Некоторые примечания по этому поводу заключаются в том, что это многопользовательская команда. Это означает, что bash
работает как root
, поэтому вы можете использовать столько команд, сколько сможете, за один раз, просто разделив их на ;
.
Ответ 6
На мой взгляд, было бы намного проще и безопаснее создать script, у которого есть права sudoer.
Например, добавьте это в sudoers:
myuser ALL=NOPASSWD:/home/myuser/somescript.sh
Теперь вы можете просто вызвать script через paramiko на главной машине и сделать с ним.
Ответ 7
Мне удалось запустить команду sudo cupsdisable
на удаленном сервере вручную без ввода пароля при входе на этот сервер в качестве одного из пользователей admin (не root), но когда я выполняю то же самое с помощью stdin, stdout, stderr = client.exec_command("sudo cupsdisable <Printqueuename>")
ничего не делает.
Команда, которая работала для меня, была:
stdin, stdout, stderr = client.exec_command("sudo -u root /usr/sbin/cupsdisable <printQueuename>")
Это характерно только для вышеупомянутого сценария. Надеюсь, это поможет кому-то