Inserisci automaticamente la password SSH con lo script


194

Devo creare uno script che immetta automaticamente una password per il sshclient OpenSSH .

Diciamo che ho bisogno di SSH myname@somehostcon la password a1234b.

Ho già provato ...

#~/bin/myssh.sh
ssh myname@somehost
a1234b

...Ma questo non funziona.

Come posso ottenere questa funzionalità in uno script?

Risposte:


278

Per prima cosa devi installare sshpass .

  • Ubuntu / Debian: apt-get install sshpass
  • Fedora / CentOS: yum install sshpass
  • Arco: pacman -S sshpass

Esempio:

sshpass -p "YOUR_PASSWORD" ssh -o StrictHostKeyChecking=no YOUR_USERNAME@SOME_SITE.COM

Esempio di porta personalizzata:

sshpass -p "YOUR_PASSWORD" ssh -o StrictHostKeyChecking=no YOUR_USERNAME@SOME_SITE.COM:2400

Appunti:

  • sshpasspuò anche leggere una password da un file quando -fviene passato il flag.
    • L'uso -fimpedisce di visualizzare la password se il pscomando viene eseguito.
    • Il file in cui è memorizzata la password deve avere autorizzazioni sicure.

12
È molto meglio che usare Expect.
Per Mejdal Rasmussen,

5
tieni presente che mentre sshpass blocca la tua password da comandi come ps -aux, normalmente non dovresti eseguire comandi digitando la tua password perché altri utenti sullo stesso computer potrebbero essere in grado di vedere la password eseguendo ps -aux. se pratico, si desidera utilizzare invece l'autenticazione con chiave pubblica, come indicato nell'altra risposta. questo ti consente di separare le informazioni di autenticazione dallo script in modo da poter condividere lo script con altri senza preoccupazioni, e in seguito decidere di abilitare la crittografia nella cartella ~ / .ssh senza crittografare anche lo script.
Alexander Taylor,

2
Sfortunatamente questo non funziona per me su un server con una porta ssh personalizzata ... perché ssh non può darci la possibilità di inserire la password nella riga di comando?
Andy,

2
affinché la porta personalizzata funzioni, aggiungere "-p port-number" alla fine del comando
Ye Lwin Soe,


96

Dopo aver cercato una risposta per la domanda per mesi, ho finalmente trovato una soluzione migliore: scrivere una semplice sceneggiatura.

#!/usr/bin/expect

set timeout 20

set cmd [lrange $argv 1 end]
set password [lindex $argv 0]

eval spawn $cmd
expect "assword:"
send "$password\r";
interact

Mettilo a /usr/bin/exp, quindi puoi usare:

  • exp <password> ssh <anything>
  • exp <password> scp <anysrc> <anydst>

Fatto!


2
Questa risposta dovrebbe ottenere più voti imo, è un ottimo wrapper. Ho appena provato alcune operazioni comuni come rsyncing con vari flag ed esecuzione di comandi remoti e ha funzionato ogni volta. Aggiunto alla mia cassetta degli attrezzi di script utili, grazie @damn_c!
user2082382

7
Forse non ha ottenuto più voti perché la gente non se lo aspettava?
chiarimento il

7
Il motivo per cui questa non è un'ottima risposta IMO è perché la password è scritta nello script che è di gran lunga il metodo meno sicuro ...
PierreE

8
La password sarà visibile da chiunque esegua ps sulla macchina.
Daniel Persson,

22
"assword" è incredibile :-)
Ciro Santilli 29 冠状 病 六四 事件 法轮功

71

Utilizza l'autenticazione con chiave pubblica: https://help.ubuntu.com/community/SSH/OpenSSH/Keys

Nell'host di origine eseguirlo solo una volta:

ssh-keygen -t rsa # ENTER to every field
ssh-copy-id myname@somehost

Questo è tutto, dopodiché sarai in grado di fare ssh senza password.


21
Vedo. Ma sono richiesto di ssh con password. Questo perché, "I" può avere lo script su una chiavetta USB e deve eseguirlo da qualsiasi computer; pur non disabilitando la necessità di password.
user1467855

3
@ user1467855, penso che tu debba spiegare meglio le tue esigenze. Nessuno suggerisce che tu abbia una rete non sicura. Nell'approccio a chiave pubblica, sarebbe comunque possibile per gli utenti accedere con la password. Ma copieresti la chiave privata sulla tua chiavetta, il che significa che la chiavetta sarebbe l'unica cosa che può accedere senza una password.
Aaron McDaid il

5
Sfortunatamente, mi trovo in una situazione OP, perché l'amministratore di sistema non consente l'autenticazione mediante chiavi rsa / dsa e richiede passwor. Cosa farai.
Karel Bílek,

27
Sottovalutato perché questo non tenta nemmeno di rispondere alla domanda effettiva posta.
Parthian Shot

2
Questo richiede ancora il primo accesso e non può essere utilizzato in uno script!
Mehrdad Mirreza,

29

È possibile utilizzare uno script prevede. Non ne ho scritto uno da un po 'di tempo ma dovrebbe apparire come di seguito. Dovrai dirigere la sceneggiatura con#!/usr/bin/expect

#!/usr/bin/expect -f
spawn ssh HOSTNAME
expect "login:" 
send "username\r"
expect "Password:"
send "password\r"
interact

Ho fatto come mi hai suggerito ma ho /bin/myssh.sh: 2: spawn: not found /bin/myssh.sh: 3: expect: not found /bin/myssh.sh: 4: send: not found /bin/myssh.sh: 5: expect: not found /bin/myssh.sh: 6: send: not found
riscontrato

Grazie Aaron per aver modificato la mia risposta per essere corretta. Potrebbe essere necessario eseguire il comando seguente per trovare il percorso corretto da inserire per aspettarsi. which expect
Lipongo,

1
Puoi anche usare questa linea shebang:#!/usr/bin/env expect
glenn jackman,

1
Ho aggiunto interactalla fine in modo che la sessione SSH sia effettivamente interattiva
Karel Bílek,

-1 per l'enorme rischio per la sicurezza di mantenere una password di testo normale in uno script.
Aaron Digulla,

21

Variante I

sshpass -p PASSWORD ssh USER@SERVER

Variante II

#!/usr/bin/expect -f
spawn ssh USERNAME@SERVER "touch /home/user/ssh_example"
expect "assword:"
send "PASSWORD\r"
interact

Il -pflag serve per specificare un numero di porta.
Kookerus,

4
No. sshpass non è ssh. SYNOPSIS sshpass [-ffilename|-dnum|-ppassword|-e] [options] command arguments
RemiZOffAlex,

Per eseguire sshpass in Linux CentOS devi yum -y install epel-releasee poiyum -y install sshpass
Junior Mayhé,

In questo contesto di questi dati possono essere ignorati
RemiZOffAlex,

Mentre so che questo è un vecchio post, vale la pena notare che il metodo Variant II lascerebbe la password assegnata alla sessione vulnerabile nella storia di bash, rendendola altamente sconsigliata.
Kirkland,

11

sshpass + autossh

Un bel vantaggio del già citato sshpassè che puoi usarlo con autossh, eliminando ancora di più l'inefficienza interattiva.

sshpass -p mypassword autossh -M0 -t myusername@myserver.mydomain.com

Ciò consentirà la connessione automatica se, ad esempio, la connessione wifi viene interrotta chiudendo il laptop.


2
Si noti che non è possibile aggiungere opzioni -fall'autossh in questa combinazione, perché when used with autossh, ssh will be *unable* to ask for passwords or passphrases. harding.motd.ca/autossh/README.txt anche superuser.com/questions/1278583/…
allenyllee,

9

sshpass con una migliore sicurezza

Mi sono imbattuto in questo thread mentre cercavo un modo per accedere a un server impantanato: ci sono voluti più di un minuto per elaborare il tentativo di connessione SSH e sono scaduto prima che potessi inserire una password. In questo caso, volevo poter fornire la mia password immediatamente quando il prompt era disponibile.

(E se non è dolorosamente chiaro: con un server in questo stato, è troppo tardi per impostare un accesso con chiave pubblica.)

sshpassAl salvataggio. Tuttavia, ci sono modi migliori per farlo rispetto a sshpass -p.

La mia implementazione salta direttamente alla richiesta della password interattiva (non si perde tempo a vedere se può avvenire lo scambio di chiavi pubbliche) e non rivela mai la password come testo semplice.

#!/bin/sh
# preempt-ssh.sh
# usage: same arguments that you'd pass to ssh normally
echo "You're going to run (with our additions) ssh $@"

# Read password interactively and save it to the environment
read -s -p "Password to use: " SSHPASS 
export SSHPASS

# have sshpass load the password from the environment, and skip public key auth
# all other args come directly from the input
sshpass -e ssh -o PreferredAuthentications=keyboard-interactive -o PubkeyAuthentication=no "$@"

# clear the exported variable containing the password
unset SSHPASS

1
nota a se stesso: aggiorna lo script da utilizzare trapper impedire a ctrl-C di perdere la SSHPASSvariabile
Ian

1
Ho scoperto che PreferredAuthentications=keyboard-interactivenon funzionava, ma sostituendolo con PreferredAuthentications=passwordfunzionava.
Mike Partridge,

8

Ecco come accedo ai miei server.

ssp <server_ip>
  • alias ssp = '/ home / myuser / Documents / ssh_script.sh'
  • cat /home/myuser/Documents/ssh_script.sh

#! / Bin / bash

sshpass -p mypassword ssh root @ $ 1

E quindi...

ssp server_ip

5
# create a file that echo's out your password .. you may need to get crazy with escape chars or for extra credit put ASCII in your password...
echo "echo YerPasswordhere" > /tmp/1
chmod 777 /tmp/1

# sets some vars for ssh to play nice with something to do with GUI but here we are using it to pass creds.
export SSH_ASKPASS="/tmp/1"
export DISPLAY=YOURDOINGITWRONG
setsid ssh root@owned.com -p 22

riferimento: https://www.linkedin.com/pulse/youre-doing-wrong-ssh-plain-text-credentials-robert-mccurdy?trk=mp-reader-card


3
Penso che questo articolo sia solo sarcastico!
Yan Foto

5

Non credo di aver visto nessuno suggerire questo e l'OP ha appena detto "script", quindi ...

Avevo bisogno di risolvere lo stesso problema e il mio linguaggio più comodo è Python.

Ho usato la libreria paramiko. Inoltre, avevo anche bisogno di emettere comandi per i quali avrei bisogno di autorizzazioni escalate usando sudo. Si scopre che sudo può accettare la sua password tramite stdin tramite il flag "-S"! Vedi sotto:

import paramiko

ssh_client = paramiko.SSHClient()

# To avoid an "unknown hosts" error. Solve this differently if you must...
ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())

# This mechanism uses a private key.
pkey = paramiko.RSAKey.from_private_key_file(PKEY_PATH)

# This mechanism uses a password.
# Get it from cli args or a file or hard code it, whatever works best for you
password = "password"

ssh_client.connect(hostname="my.host.name.com",
                       username="username",
                       # Uncomment one of the following...
                       # password=password
                       # pkey=pkey
                       )

# do something restricted
# If you don't need escalated permissions, omit everything before "mkdir"
command = "echo {} | sudo -S mkdir /var/log/test_dir 2>/dev/null".format(password)

# In order to inspect the exit code
# you need go under paramiko's hood a bit
# rather than just using "ssh_client.exec_command()"
chan = ssh_client.get_transport().open_session()
chan.exec_command(command)

exit_status = chan.recv_exit_status()

if exit_status != 0:
    stderr = chan.recv_stderr(5000)

# Note that sudo's "-S" flag will send the password prompt to stderr
# so you will see that string here too, as well as the actual error.
# It was because of this behavior that we needed access to the exit code
# to assert success.

    logger.error("Uh oh")
    logger.error(stderr)
else:
    logger.info("Successful!")

Spero che questo aiuti qualcuno. Il mio caso d'uso era la creazione di directory, l'invio e l'estrazione di file e l'avvio di programmi su ~ 300 server alla volta. Come tale, l'automazione era fondamentale. Ho provato sshpass, expecte poi ho pensato a questo.


2

Ho funzionato come segue

.ssh / config è stato modificato per eliminare il prompt yes / no - Sono protetto da un firewall, quindi non sono preoccupato per le chiavi ssh contraffatte

host *
     StrictHostKeyChecking no

Creare un file di risposta per aspettarsi, ad esempio answer.expect

set timeout 20
set node [lindex $argv 0]
spawn ssh root@node service hadoop-hdfs-datanode restart

expect  "*?assword {
      send "password\r"   <- your password here.

interact

Crea il tuo script bash e basta chiamare aspettarsi nel file

#!/bin/bash
i=1
while [$i -lt 129]    # a few nodes here

  expect answer.expect hadoopslave$i

  i=[$i + 1]
  sleep 5

done

Ottiene 128 codici dati hadoop aggiornati con la nuova configurazione - supponendo che si stia utilizzando un mount NFS per i file hadoop / conf

Spero che questo aiuti qualcuno - Sono un intorpidito di Windows e mi ci sono volute circa 5 ore per capire!


"Sono dietro un firewall, quindi non sono preoccupato per le chiavi SSH contraffatte". Un firewall non fa esattamente nulla in questo caso. HostKeyCheck consente di verificare che l'host dall'altra parte non sia un trojan. Cioè uno che sta solo fingendo di essere dove vuoi connetterti. Se ti connetti a un host sconosciuto e fai qualcosa di sensibile, come scrivere un file con credenziali o token o inserire una password, tali informazioni ora sono effettivamente di dominio pubblico. Essere dietro un firewall è irrilevante.
JCGB

2

Se lo stai facendo su un sistema Windows, puoi usare Plink (parte di PuTTY).

plink your_username@yourhost -pw your_password



1

Sono riuscito a farlo funzionare con quello:

SSH_ASKPASS="echo \"my-pass-here\""
ssh -tt remotehost -l myusername

0

Nell'esempio seguente scriverò la soluzione che ho usato:

Lo scenario: voglio copiare il file da un server usando sh script:

#!/usr/bin/expect
$PASSWORD=password
my_script=$(expect -c "spawn scp userName@server-name:path/file.txt /home/Amine/Bureau/trash/test/
expect \"password:\"
send \"$PASSWORD\r\"
expect \"#\"
send \"exit \r\"
")

echo "$my_script"

-2

Usa questo script all'interno dello script, il primo argomento è il nome host e il secondo sarà la password.

#!/usr/bin/expect
set pass [lindex $argv 1]
set host [lindex $argv 0]
spawn ssh -t root@$host echo Hello
expect "*assword: " 
send "$pass\n";
interact"

Cosa mostra questo in cima alle risposte esistenti? In particolare quelli di damn_c, Lipongo o RemiZOffAlex e altri ...
Martin Prikryl,

esecuzione dello script insieme a ssh #! / usr / bin / explore set pass [lindex $ argv 1] set host [lindex $ argv 0] spawn ssh -t root @ $ host sh /tmp/anyscript.sh prevede "* assword:" invia "$ pass \ n"; interagisci "
Shivam Mehrotra,

-3

Per connettere la macchina remota tramite script di shell, utilizzare il comando seguente:

sshpass -p PASSWORD ssh -o StrictHostKeyChecking=no USERNAME@IPADDRESS

dove IPADDRESS, USERNAMEe PASSWORDsono i valori di input che hanno bisogno di fornire nello script, o se vogliamo fornire in uso runtime "leggere" il comando.


5
Cosa mostra questa risposta oltre alle risposte esistenti? + Non suggerire mai a nessuno di usarlo StrictHostKeyChecking=nosenza spiegarne le conseguenze.
Martin Prikryl,

-5
sudo ssh username@server_ip_address -p port_number

premere il tasto Invio, quindi immettere la password del sistema e infine immettere la password del server

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.