GNU/Linux >> Znalost Linux >  >> Linux

Odeslání hesla přes SSH nebo SCP pomocí subprocess.Popen

OpenSSH scp obslužný program vyvolá ssh program, který vytvoří připojení SSH ke vzdálenému hostiteli, a proces ssh se postará o autentizaci. ssh obslužný program nepřijímá heslo na příkazovém řádku nebo na svém standardním vstupu. Věřím, že jde o záměrné rozhodnutí ze strany vývojářů OpenSSH, protože mají pocit, že by lidé měli používat bezpečnější mechanismy, jako je autentizace založená na klíčích. Jakékoli řešení pro vyvolání ssh bude následovat jeden z těchto přístupů:

  1. K ověření použijte místo hesla klíč SSH.
  2. Použijte sshpass, očekávat nebo podobný nástroj k automatizaci odpovědi na výzvu k zadání hesla.
  3. Použijte (zneužívejte) funkci SSH_ASKPASS k získání ssh k získání hesla vyvoláním jiného příkazu, popsaného zde nebo zde, nebo v některých odpovědích zde.
  4. Požádejte správce serveru SSH, aby povolil autentizaci založenou na hostiteli a použil ji. Pamatujte, že autentizace založená na hostiteli je vhodná pouze pro určitá síťová prostředí. Další poznámky naleznete zde a zde.
  5. Napište si vlastního ssh klienta pomocí perlu, pythonu, javy nebo svého oblíbeného jazyka. Pro většinu moderních programovacích jazyků jsou k dispozici klientské knihovny ssh a vy byste měli plnou kontrolu nad tím, jak klient získá heslo.
  6. Stáhněte si zdrojový kód ssh a vytvořte upravenou verzi ssh to funguje tak, jak chcete.
  7. Použijte jiného klienta ssh. K dispozici jsou další ssh klienti, jak zdarma, tak komerční. Jeden z nich může vyhovovat vašim potřebám lépe než klient OpenSSH.

V tomto konkrétním případě, vzhledem k tomu, že již vyvoláváte scp z python skriptu se zdá, že jeden z nich by byl nejrozumnější přístup:

  1. Použijte pexpect, modul očekávání pythonu, k vyvolání scp a zadejte do něj heslo.
  2. K provedení této úlohy ssh použijte paramiko, implementaci ssh v pythonu, namísto vyvolání externího programu.

Zde je funkce ssh s heslem pomocí pexpect :

import pexpect
import tempfile

def ssh(host, cmd, user, password, timeout=30, bg_run=False):                                                                                                 
    """SSH'es to a host using the supplied credentials and executes a command.                                                                                                 
    Throws an exception if the command doesn't return 0.                                                                                                                       
    bgrun: run command in the background"""                                                                                                                                    
                                                                                                                                                                               
    fname = tempfile.mktemp()                                                                                                                                                  
    fout = open(fname, 'w')                                                                                                                                                    
                                                                                                                                                                               
    options = '-q -oStrictHostKeyChecking=no -oUserKnownHostsFile=/dev/null -oPubkeyAuthentication=no'                                                                         
    if bg_run:                                                                                                                                                         
        options += ' -f'                                                                                                                                                       
    ssh_cmd = 'ssh %[email protected]%s %s "%s"' % (user, host, options, cmd)                                                                                                                 
    child = pexpect.spawn(ssh_cmd, timeout=timeout)  #spawnu for Python 3                                                                                                                          
    child.expect(['[pP]assword: '])                                                                                                                                                                                                                                                                                               
    child.sendline(password)                                                                                                                                                   
    child.logfile = fout                                                                                                                                                       
    child.expect(pexpect.EOF)                                                                                                                                                  
    child.close()                                                                                                                                                              
    fout.close()                                                                                                                                                               
                                                                                                                                                                                                                                                                                                                        
    fin = open(fname, 'r')                                                                                                                                                     
    stdout = fin.read()                                                                                                                                                        
    fin.close()                                                                                                                                                                
                                                                                                                                                                               
    if 0 != child.exitstatus:                                                                                                                                                  
        raise Exception(stdout)                                                                                                                                                
                                                                                                                                                                               
    return stdout

Něco podobného by mělo být možné pomocí scp .


Druhá odpověď, kterou jste propojili, navrhuje, abyste použili Pexpect (což je obvykle správný způsob interakce s programy příkazového řádku, které očekávají vstup). Existuje jeho fork, který funguje pro python3, který můžete použít.


Linux
  1. Ssh – Stále dostáváte výzvu k zadání hesla pomocí Ssh s ověřováním pomocí veřejného klíče?

  2. Oring s True In A Command Over Ssh?

  3. Jak nastavit Rsync s SSH na UNIX / Linux (rsync bez hesla)

  1. Jak povolit ssh s prázdnými hesly v Linuxu

  2. Příkaz sshpass:Neinteraktivní ověřování hesla pomocí SSH

  3. Rsync s výzvou SSH pro vzdálené heslo

  1. Automatizace hesel SSH v Linuxu pomocí sshpass

  2. Použití scp s předávaným ssh agentem

  3. Uživatelské jméno a heslo v příkazovém řádku s sshfs