usando python Paramiko per ssh: sudo: nessun tty presente e nessun programma askpass specificato


5

Voglio usare paramikoper ssh in un mucchio di nodi remoti ed eseguire una riga di comando con rootprivilegio

Ho la chiave ssh nella mia home directory e quindi non ho bisogno di inserire la password quando ssh in quei nodi remoti

ma quando si esegue il seguente script:

    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)

Ho ricevuto il seguente errore:

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

se non aggiungo sudoprima che ls tutto funzioni correttamente, quali sono le ragioni potenziali? Grazie!


l'utente che esegue il sudo non deve essere autorizzato a eseguire i comandi in esecuzione, con la direttiva NOPASSWORD nel file
sudoers

Risposte:


2

Nella sudoersconfigurazione stock , di solito è presente la seguente riga:

Defaults requiretty

Questo è sicuro e ciò di cui hai bisogno nella maggior parte dei casi d'uso.

Nel tuo caso, devi sovrascrivere questa impostazione predefinita per un utente specifico, quindi scrivi di seguito:

Defaults:niky !requiretty

Inoltre, è necessario definire una linea che consenta nikydi chiamare sudosenza password:

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

Questa riga indica che l'utente nikypuò eseguire /bin/lscome rootin remote.nity.comsenza richiedere una password.

Ulteriori riferimenti sono disponibili qui .


1

Cordiali saluti - può aiutarti nella tua ricerca - nota che ottieni lo STESSO errore in SSH semplice se incapsuli un comando SSH all'interno di un altro, es:

localhost $ ssh user1@host1.example.com -C 'sudo su - anotheruser ssh user2@host2.example2.com / run / this / eseguibile'

(Perché non SSH direttamente nella casella di destinazione? Beh, forse le chiavi SSH sono configurate solo tra host1 e host2, oppure la rete è instradata per vietare l'accesso host2 senza viaggiare attraverso host1. Forse non ti è permesso toccare sudoers o qualsiasi altro file su host2 ... comune in Envs di produzione.).

In ogni caso, è possibile eseguire comandi non sudo utilizzando quanto sopra, ma il prefisso con sudo provoca "no tty present".

Come si risolve questo problema con il comando bare ssh? Inserisci -t, ad esempio: localhost $ ssh user1@host1.example.com -C 'sudo su - anotheruser ssh -t user2@host2.example2.com / run / this / eseguibile'

Ora il sudo remoto funziona perfettamente all'interno di SSH, nessuna lamentela su tty. -T lo ha assegnato.

Quindi la domanda è: come si fa a emulare l'opzione "-t" all'interno dell'oggetto Paramiko? C'è la tua risposta

Questo blog tenta di spiegare, ma forse avrebbe potuto dedicare più tempo all'esempio "sudo": http://jessenoller.com/2009/02/05/ssh-programming-with-paramiko-completely-different/

(Mi scuso per il mio punto nella giusta direzione invece di una risposta perfetta ... In realtà sto ancora cercando queste informazioni da solo).


Il blog a cui ti sei collegato mostra il ragazzo che usa sudo senza alcun problema in paramiko.
ArtOfWarfare il

1

Due cose che troverai utili:

  1. exec_commandaccetta un argomento facoltativo di get_pty. Puoi usarlo in questo modo:

    (stdin, stdout, stderr) = ssh.exec_command("sudo ls", get_pty = True)
    
  2. Lancia la password stdin, con un ritorno di linea e svuota per assicurarti che venga recapitata. Questo assicura che riceva la password se chiede (potresti fare qualcosa di più sofisticato per verificare se lo ha effettivamente chiesto o no ... semplicemente lanciarlo non ha sempre causato problemi per me.)

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

Nel loro insieme, quelli dovrebbero risolvere i tuoi problemi di sudoover paramiko.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.