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ů:
- K ověření použijte místo hesla klíč SSH.
- Použijte sshpass, očekávat nebo podobný nástroj k automatizaci odpovědi na výzvu k zadání hesla.
- 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. - 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.
- 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.
- Stáhněte si zdrojový kód ssh a vytvořte upravenou verzi
ssh
to funguje tak, jak chcete. - 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:
- Použijte pexpect, modul očekávání pythonu, k vyvolání
scp
a zadejte do něj heslo. - 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.