Verwenden von Python Paramiko für ssh: sudo: Kein tty vorhanden und kein askpass-Programm angegeben

5

Ich möchte benutzen paramiko zu ssh in ein Bündel einen Remote-Knoten und führen Sie eine Befehlszeile mit root Privileg

Ich habe einen SSH-Schlüssel in meinem Home-Verzeichnis und muss daher kein Passwort eingeben, wenn ich in diese Remote-Knoten sshe

aber beim Ausführen des folgenden Skripts:

    def connect(hostname):
                    ssh = paramiko.SSHClient()
                    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())               
                    ssh.connect(hostname, username='niky', pkey=paramiko.RSAKey.from_private_key(open('id_rsa'), 'passwd'), timeout = 240.0)                return ssh          



    def run(hostname):
            ssh = connect(hostname)
            (stdin, stdout, stderr) = ssh.exec_command("sudo ls")
            res = stderr.readlines()
            print hostname+': '+''.join(str(elem) for elem in res)+'\n'

    run(remote.nity.com)

Ich habe folgende Fehlermeldung erhalten:

remote.nity.com: sudo: no tty present and no askpass program specified

wenn ich nicht hinzufüge sudo Vor ls alles funktioniert gut Was sind mögliche Gründe? Vielen Dank!

misteryes
quelle
Der Benutzer, der das sudo ausführt, darf die von Ihnen ausgeführten Befehle mit der Anweisung NOPASSWORD in der Datei sudoers nicht ausführen
MelBurslan

Antworten:

2

Im Lager sudoers Konfiguration ist in der Regel folgende Zeile vorhanden:

Defaults requiretty

Dies ist sowohl sicher als auch das, was Sie in den meisten Anwendungsfällen benötigen.

In Ihrem Fall müssen Sie diese Standardeinstellung für einen bestimmten Benutzer überschreiben, sodass Sie Folgendes schreiben würden:

Defaults:niky !requiretty

Außerdem müssen Sie eine zulässige Zeile definieren niky anrufen sudo ohne Passwort:

niky remote.nity.com = (root)NOPASSWD: /bin/ls

Diese Zeile bedeutet, dass der Benutzer niky darf ausführen /bin/ls wie root im remote.nity.com ohne ein Passwort zu benötigen.

Weitere Hinweise finden Sie in Hier .

dawud
quelle
1

FYI - kann Ihnen bei Ihrer Suche helfen - Beachten Sie, dass Sie den SAME-Fehler in einfachem SSH erhalten, wenn Sie einen SSH-Befehl in einen anderen einbetten, z.

localhost $ ssh [email protected] -C 'sudo su - anderer Benutzer ssh [email protected] / run / this / executable'

(Warum nicht SSH direkt auf die Zielbox übertragen? Vielleicht werden SSH-Schlüssel nur zwischen Host1 und Host2 eingerichtet, oder das Netzwerk wird so geroutet, dass der Zugriff auf Host2 ohne Weiterleitung über Host1 verhindert wird. Vielleicht dürfen Sie keine Sudoer oder andere berühren andere Datei auf Host2 ... häufig in Produktionsumgebungen.).

In jedem Fall können Sie Nicht-Sudo-Befehle mit den oben genannten Befehlen ausführen. Das Präfixieren mit sudo führt jedoch zu "no tty present".

Wie behebt man das mit dem Befehl bare ssh? Geben Sie das -t ein, z. B .: localhost $ ssh [email protected] -C 'sudo su - ein anderer Benutzer ssh -t [email protected] / run / this / executable'

Nun läuft der Remote Sudo einwandfrei innerhalb von SSH, keine Beschwerden über tty. Der -t hat es zugeteilt.

Die Frage ist also, wie man die Option "-t" im Paramiko-Objekt emuliert. Da ist deine Antwort.

Dieser Blog versucht es zu erklären, hätte aber möglicherweise mehr Zeit für das 'sudo'-Beispiel aufwenden können: http://jessenoller.com/2009/02/05/ssh-programming-with-paramiko-completely-different/

(Entschuldigung für meinen Hinweis in die richtige Richtung anstelle einer perfekten Antwort ... Ich suche selbst noch nach diesen Informationen).

Crossfit_and_Beer
quelle
Der Blog, mit dem Sie verlinkt haben, zeigt den Typen, der sudo ohne Probleme in paramiko verwendet.
ArtOfWarfare
1

Zwei Dinge, die Sie nützlich finden werden:

  1. exec_command nimmt ein optionales Argument von get_pty. Du kannst es so benutzen:

    (stdin, stdout, stderr) = ssh.exec_command("sudo ls", get_pty = True)
    
  2. Geben Sie das Passwort in ein stdin, mit einem Zeilenumbruch und einem Flush, um sicherzustellen, dass es geliefert wird. Dies stellt sicher, dass es das Passwort erhält, wenn es gefragt wird (Sie könnten etwas Feineres tun, um zu prüfen, ob es tatsächlich gefragt wurde oder nicht ... das einfache Einwerfen hat mir noch keine Probleme bereitet.)

    stdin.write('passwd' + '\n')
    stdin.flush()
    

Zusammen genommen sollten die Ihre reparieren sudo Über paramiko Probleme.

ArtOfWarfare
quelle