GNU/Linux >> Belajar Linux >  >> Linux

Mengirim kata sandi melalui SSH atau SCP dengan subprocess.Popen

OpenSSH scp utilitas memanggil ssh program untuk membuat koneksi SSH ke host jarak jauh, dan proses ssh menangani otentikasi. ssh utilitas tidak menerima kata sandi pada baris perintah atau input standarnya. Saya percaya ini adalah keputusan yang disengaja dari pihak pengembang OpenSSH, karena mereka merasa bahwa orang harus menggunakan mekanisme yang lebih aman seperti autentikasi berbasis kunci. Solusi apa pun untuk menjalankan ssh akan mengikuti salah satu pendekatan ini:

  1. Gunakan kunci SSH untuk autentikasi, bukan sandi.
  2. Gunakan sshpass, expect, atau alat serupa untuk secara otomatis merespons prompt sandi.
  3. Gunakan (penyalahgunaan) fitur SSH_ASKPASS untuk mendapatkan ssh untuk mendapatkan kata sandi dengan menjalankan perintah lain, dijelaskan di sini atau di sini, atau dalam beberapa jawaban di sini.
  4. Dapatkan administrator server SSH untuk mengaktifkan autentikasi berbasis host dan gunakan itu. Perhatikan bahwa autentikasi berbasis host hanya cocok untuk lingkungan jaringan tertentu. Lihat catatan tambahan di sini dan di sini.
  5. Tulis klien ssh Anda sendiri menggunakan perl, python, java, atau bahasa favorit Anda. Ada pustaka klien ssh yang tersedia untuk sebagian besar bahasa pemrograman modern, dan Anda akan memiliki kontrol penuh atas cara klien mendapatkan sandi.
  6. Unduh kode sumber ssh dan buat versi ssh yang dimodifikasi yang berfungsi seperti yang Anda inginkan.
  7. Gunakan klien ssh yang berbeda. Ada klien ssh lain yang tersedia, baik gratis maupun komersial. Salah satunya mungkin lebih sesuai dengan kebutuhan Anda daripada klien OpenSSH.

Dalam kasus khusus ini, mengingat Anda sudah memanggil scp dari skrip python, tampaknya salah satunya akan menjadi pendekatan yang paling masuk akal:

  1. Gunakan pexpect, modul ekspektasi python, untuk menjalankan scp dan berikan kata sandi untuk itu.
  2. Gunakan paramiko, implementasi python ssh, untuk melakukan tugas ssh ini alih-alih menggunakan program luar.

Inilah fungsi untuk ssh dengan kata sandi menggunakan 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

Sesuatu yang serupa harus dimungkinkan menggunakan scp .


Jawaban kedua yang Anda tautkan menyarankan Anda menggunakan Pexpect (yang biasanya merupakan cara yang tepat untuk berinteraksi dengan program baris perintah yang mengharapkan input). Ada garpu yang berfungsi untuk python3 yang dapat Anda gunakan.


Linux
  1. Cara Setup Rsync dengan SSH di UNIX/Linux (rsync tanpa password)

  2. Cara mengizinkan ssh dengan kata sandi kosong di Linux

  3. Perintah sshpass:Otentikasi Kata Sandi Non-interaktif dengan SSH

  1. Bagaimana cara Setup Rsync tanpa kata sandi dengan SSH di UNIX / Linux?

  2. Rsync dengan SSH meminta kata sandi jarak jauh

  3. Nama pengguna dan kata sandi di baris perintah dengan sshfs

  1. Otomatisasi kata sandi SSH di Linux dengan sshpass

  2. Ssh Login Dengan Clear Text Password Sebagai Parameter??

  3. Ssh – Membatasi Pengguna Ssh/scp/sftp ke Direktori?