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:
- Gunakan kunci SSH untuk autentikasi, bukan sandi.
- Gunakan sshpass, expect, atau alat serupa untuk secara otomatis merespons prompt sandi.
- 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. - 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.
- 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.
- Unduh kode sumber ssh dan buat versi
ssh
yang dimodifikasi yang berfungsi seperti yang Anda inginkan. - 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:
- Gunakan pexpect, modul ekspektasi python, untuk menjalankan
scp
dan berikan kata sandi untuk itu. - 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.