Ingrese automáticamente la contraseña SSH con script

193

Necesito crear un script que ingrese automáticamente una contraseña para el sshcliente OpenSSH .

Digamos que necesito ingresar SSH myname@somehostcon la contraseñaa1234b .

Ya lo he intentado ...

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

...Pero esto no funciona.

¿Cómo puedo obtener esta funcionalidad en un script?

usuario1467855
fuente

Respuestas:

278

Primero necesitas instalar sshpass .

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

Ejemplo:

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

Ejemplo de puerto personalizado:

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

Notas:

  • sshpassTambién puede leer una contraseña de un archivo cuando -fse pasa la bandera.
    • El uso -fevita que la contraseña sea visible si psse ejecuta el comando.
    • El archivo en el que se almacena la contraseña debe tener permisos seguros.
abbotto
fuente
12
Esto es mucho mejor que usar Expect.
Por Mejdal Rasmussen
55
solo tenga en cuenta que si bien sshpass bloquea su contraseña de comandos como ps -aux, normalmente no debe ejecutar comandos escribiendo su contraseña porque otros usuarios en la misma computadora pueden ver la contraseña al ejecutarla ps -aux. si es práctico, también desea utilizar la autenticación de clave pública, como se menciona en la otra respuesta. esto le permite separar la información de autenticación de su script para que pueda compartir su script con otras personas sin preocupaciones, y luego decidir habilitar el cifrado en su carpeta ~ / .ssh sin cifrar también su script.
Alexander Taylor
2
Desafortunadamente, esto no funciona para mí en un servidor con un puerto ssh personalizado ... ¿por qué ssh no nos da la opción de insertar la contraseña en la línea de comando?
Andy
2
para que el puerto personalizado funcione, agregue "-p número-puerto" al final del comando
Ye Lwin Soe
95

Después de buscar una respuesta para la pregunta durante meses, finalmente encontré una mejor solución: escribir un guión simple.

#!/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

Póngalo en /usr/bin/exp, luego puede usar:

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

¡Hecho!

maldita sea
fuente
2
Esta respuesta debería obtener más votos de la OMI, es una gran envoltura. Solo intenté algunas operaciones comunes como rsyncing con varias banderas y ejecución remota de comandos y funcionó todo el tiempo. Agregado a mi caja de herramientas de scripts útiles, ¡Gracias @damn_c!
user2082382
77
¿Quizás no ha recibido más votos porque la gente no lo esperaba?
clearlight
77
La razón por la cual esta IMO no es una muy buena respuesta es porque la contraseña está escrita en el script, que es, con mucho, el método menos seguro ...
PierreE
8
La contraseña será visible para cualquier persona que ejecute ps en la máquina.
Daniel Persson
22
"assword" es increíble :-)
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
71

Utilice la autenticación de clave pública: https://help.ubuntu.com/community/SSH/OpenSSH/Keys

En el host de origen, ejecute esto solo una vez:

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

Eso es todo, después de eso podrás hacer ssh sin contraseña.

Diego Woitasen
fuente
21
Veo. Pero estoy obligado a ssh con contraseña. Esto se debe a que "I" puede tener el script en una memoria USB y necesitar ejecutarlo desde cualquier computadora; sin deshabilitar la necesidad de contraseña.
user1467855
3
@ user1467855, creo que necesita explicar mejor sus requisitos. Nadie sugiere que tenga una red no segura. En el enfoque de clave pública, aún sería posible para los usuarios iniciar sesión con la contraseña. Pero debería copiar la clave privada en su memoria USB, lo que significa que la memoria USB sería lo único que puede iniciar sesión sin una contraseña.
Aaron McDaid
55
Desafortunadamente, estoy en una situación de OP, porque el administrador del sistema no permite la autenticación mediante las claves rsa / dsa y requiere passwors. Qué vas a hacer.
Karel Bílek
26
Votado en contra porque esto ni siquiera trata de responder a la pregunta real formulada.
Parthian Shot
2
¡Esto todavía solicita el primer inicio de sesión y no se puede usar en un script!
Mehrdad Mirreza
29

Podría usar un script de espera. No he escrito uno en bastante tiempo, pero debería verse a continuación. Deberá encabezar el guión con#!/usr/bin/expect

#!/usr/bin/expect -f
spawn ssh HOSTNAME
expect "login:" 
send "username\r"
expect "Password:"
send "password\r"
interact
Lipongo
fuente
Hice lo que me sugirió pero /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
recibí
Gracias Aaron por modificar mi respuesta para que sea correcta. Es posible que deba ejecutar el siguiente comando para encontrar la ruta correcta para esperar. which expect
Lipongo
1
También puede usar esta línea shebang:#!/usr/bin/env expect
Glenn Jackman
1
Agregué interactal final para que la sesión ssh sea realmente interactiva
Karel Bílek
-1 por el gran riesgo de seguridad de mantener una contraseña de texto sin formato en un 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
RemiZOffAlex
fuente
La -pbandera es para especificar un número de puerto.
Kookerus
44
No. sshpass no es ssh. SYNOPSIS sshpass [-ffilename|-dnum|-ppassword|-e] [options] command arguments
RemiZOffAlex
Para ejecutar sshpass en Linux CentOS debes yum -y install epel-releasey luegoyum -y install sshpass
Junior Mayhé
En este contexto, estos datos pueden ignorarse
RemiZOffAlex
Si bien sé que esta es una publicación anterior, vale la pena señalar que el método Variant II dejaría la contraseña dada a la sesión vulnerable en el historial de bash, por lo que es altamente desaconsejable.
Kirkland
10

sshpass + autossh

Una buena ventaja de lo ya mencionado sshpasses que puede usarlo autossh, eliminando aún más la ineficiencia interactiva.

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

Esto permitirá la conexión automática si, por ejemplo, su wifi se interrumpe al cerrar su computadora portátil.

Sridhar Sarnobat
fuente
2
Tenga en cuenta que no se puede agregar la opción -fa autossh en esta combinación, porque when used with autossh, ssh will be *unable* to ask for passwords or passphrases. harding.motd.ca/autossh/README.txt también superuser.com/questions/1278583/...~~V~~singular~~3rd
allenyllee
9

sshpass con mejor seguridad

Me topé con este hilo mientras buscaba una forma de ingresar a un servidor atascado: me llevó más de un minuto procesar el intento de conexión SSH y agotó el tiempo de espera antes de que pudiera ingresar una contraseña. En este caso, quería poder proporcionar mi contraseña de inmediato cuando el aviso estuviera disponible.

(Y si no es dolorosamente claro: con un servidor en este estado, es demasiado tarde para configurar un inicio de sesión de clave pública).

sshpassal rescate. Sin embargo, hay mejores formas de hacerlo que sshpass -p.

Mi implementación salta directamente a la solicitud de contraseña interactiva (no se pierde tiempo viendo si puede ocurrir un intercambio de clave pública), y nunca revela la contraseña como texto sin formato.

#!/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
Ian
fuente
1
note a sí mismo: actualizar el script para trapevitar que ctrl-C filtre la SSHPASSvariable
Ian
1
Descubrí que eso PreferredAuthentications=keyboard-interactiveno funcionó, pero reemplazarlo con PreferredAuthentications=passwordtrabajado.
Mike Partridge
7

Así es como inicio sesión en mis servidores.

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

Y por lo tanto...

ssp server_ip
DimiDak
fuente
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

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

RmccurdyDOTcom
fuente
3
¡Creo que este artículo está siendo sarcástico!
Yan Foto
5

No creo haber visto a nadie sugerir esto y el OP simplemente dijo "guión", así que ...

Necesitaba resolver el mismo problema y mi lenguaje más cómodo es Python.

Usé la biblioteca paramiko. Además, también necesitaba emitir comandos para los que necesitaría usar permisos escalados sudo. Resulta que sudo puede aceptar su contraseña a través de stdin a través de la bandera "-S". Vea abajo:

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!")

Espero que esto ayude a alguien. Mi caso de uso fue crear directorios, enviar y descomprimir archivos e iniciar programas en ~ 300 servidores a la vez. Como tal, la automatización era primordial. Lo intenté sshpass, expecty luego se me ocurrió esto.

John Carrell
fuente
2

Obtuve esto funcionando de la siguiente manera

.ssh / config se modificó para eliminar el mensaje yes / no: estoy detrás de un firewall, así que no me preocupan las claves ssh falsas

host *
     StrictHostKeyChecking no

Cree un archivo de respuesta para esperar, es decir, 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

Cree su script bash y solo llame a wait en el archivo

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

  expect answer.expect hadoopslave$i

  i=[$i + 1]
  sleep 5

done

Obtiene 128 nodos de datos hadoop actualizados con una nueva configuración, suponiendo que esté utilizando un montaje NFS para los archivos hadoop / conf

Espero que esto ayude a alguien: soy un Windows numpty y esto me tomó alrededor de 5 horas para descubrirlo.

WT29
fuente
"Estoy detrás de un firewall, así que no me preocupan las claves ssh falsas". Un firewall no hace exactamente nada en este caso. HostKeyCheck es para que pueda verificar que el host en el otro extremo no sea un host troyano. Es decir, uno que solo pretende ser donde quieres conectarte. Si se conecta a un host desconocido y hace algo sensible, como escribir un archivo que tiene credenciales o un token o ingresar una contraseña, esa información ahora es de conocimiento público. Estar detrás de un firewall es irrelevante.
JCGB
2

Si está haciendo esto en un sistema Windows, puede usar Plink (parte de PuTTY).

plink your_username@yourhost -pw your_password
Marko Vranjkovic
fuente
1

Me las arreglé para que funcione con eso:

SSH_ASKPASS="echo \"my-pass-here\""
ssh -tt remotehost -l myusername
Konstantin Ineshin
fuente
0

En el siguiente ejemplo, escribiré la solución que usé:

El escenario: quiero copiar el archivo de un servidor usando el script sh:

#!/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"
BERGUIGA Mohamed Amine
fuente
-2

Use esta secuencia de comandos dentro de la secuencia de comandos, el primer argumento es el nombre de host y el segundo será la contraseña.

#!/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"
Shivam Mehrotra
fuente
¿Qué muestra esto además de las respuestas existentes? Particularmente los de damn_c, Lipongo o RemiZOffAlex y otros ...
Martin Prikryl
ejecución del script junto con ssh #! / usr / bin / expect set pass [lindex $ argv 1] set host [lindex $ argv 0] spawn ssh -t root @ $ host sh /tmp/anyscript.sh wait "* assword:" enviar "$ pass \ n"; interactuar "
Shivam Mehrotra
-3

Para conectar la máquina remota a través de scripts de shell, use el siguiente comando:

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

donde IPADDRESS, USERNAMEy PASSWORDson valores de entrada que deben proporcionarse en el script, o si queremos proporcionar en tiempo de ejecución, use el comando "leer".

shyam
fuente
55
¿Qué muestra esta respuesta además de las respuestas existentes? + Nunca sugiera a nadie que lo use StrictHostKeyChecking=nosin explicar las consecuencias.
Martin Prikryl
-5
sudo ssh username@server_ip_address -p port_number

presione la tecla enter y luego ingrese la contraseña de su sistema y finalmente ingrese la contraseña de su servidor

Manoj Rana
fuente