¿Cómo ejecutar el comando sftp con una contraseña del script Bash?

173

Necesito transferir un archivo de registro a un host remoto usando sftp desde un host Linux. Mi grupo de operaciones me ha proporcionado credenciales para lo mismo. Sin embargo, dado que no tengo control sobre otro host, no puedo generar y compartir claves RSA con el otro host.

Entonces, ¿hay alguna manera de ejecutar el sftpcomando (con el nombre de usuario / contraseña proporcionado) desde el script Bash a través de un trabajo cron ?

Encontré una pregunta similar de Stack Overflow, Especifique la contraseña para sftp en un script Bash , pero no hubo una respuesta satisfactoria a mi problema.

anubhava
fuente

Respuestas:

178

Tiene algunas opciones además de usar la autenticación de clave pública:

  1. Use llavero
  2. Utilice sshpass (menos seguro pero probablemente cumple con sus requisitos)
  3. Utilice esperar (menos seguro y más codificación necesaria)

Si decide darle una oportunidad a sshpass, aquí hay un fragmento de script de trabajo para hacerlo:

export SSHPASS=your-password-here
sshpass -e sftp -oBatchMode=no -b - sftp-user@remote-host << !
   cd incoming
   put your-log-file.log
   bye
!
anubhava
fuente
3
Para usarlo en Mac: stackoverflow.com/questions/9102557/…
anubhava
18
No hay necesidad de exportar, creo. SSHPASS=password sshpass -e ...debería hacer.
Jens
9
Pude hacer una línea para descargar un archivo de registro:sshpass -p "my_password" sftp -oPort=9999 user@host:dir/file.log
Cloud Artisans
66
@gorus: One-liner es muy bueno, sin embargo, no quería usar la contraseña en la línea de comando debido a los mayores riesgos de espionaje.
anubhava
8
-oBatchMode=nofue la pieza crucial que faltaba para mí.
richardkmiller
99

Otra forma sería usar lftp:

lftp sftp://user:password@host  -e "put local-file.name; bye"

La desventaja de este método es que otros usuarios en la computadora pueden leer la contraseña de herramientas como psy que la contraseña puede formar parte de su historial de shell.

Una alternativa más segura que está disponible desde LFTP 4.5.0 es configurar la LFTP_PASSWORDvariable de entorno y ejecutar lftp con --env-password. Aquí hay un ejemplo completo:

LFTP_PASSWORD="just_an_example"
lftp --env-password sftp://user@host  -e "put local-file.name; bye"

LFTP también incluye una función de espejo genial (puede incluir eliminar después de la transferencia confirmada --Remove-source-files):

lftp -e 'mirror -R /local/log/path/ /remote/path/' --env-password -u user sftp.foo.com
Karassik
fuente
9
+1 por sugerir una alternativa, pero ¿podemos evitar proporcionar una contraseña en la línea de comando?
anubhava
1
Votado abajo para mostrar la contraseña a cualquier persona en la misma computadora
Aaron Digulla
10
Puede crear el archivo de script para lftp, de esta manera no tendrá que proporcionar la contraseña en la línea de comando. Crear un archivo put-script: luego open sftp://user:password@host; put local-file.name; exit ejecutar De lftp -f put-script esta manera, no es necesario que tenga el nombre de usuario y la contraseña en una línea de comando y puede configurar permisos restrictivos para su archivo de script.
obaranovsky
@obaranovsky Esa es una buena idea. Me pregunto si tuviera que agregar esto a mi variable de entorno como alias o una función, ¿sería seguro y posible ocultarlo a otros usuarios?
sdkks
1
Mucho más fácil de hacer lftpque perder el tiempo con sftpy sshpass. Buena respuesta.
MeanEYE
53

Esperar es un gran programa para usar.

En Ubuntu, instálalo con:

sudo apt-get install expect

En una máquina CentOS, instálelo con:

yum install expect

Digamos que desea establecer una conexión con un servidor sftp y luego cargar un archivo local desde su máquina local al servidor remoto sftp

#!/usr/bin/expect

spawn sftp username@hostname.com
expect "password:"
send "yourpasswordhere\n"
expect "sftp>"
send "cd logdirectory\n"
expect "sftp>"
send "put /var/log/file.log\n"
expect "sftp>"
send "exit\n"
interact

Esto abre una conexión sftp con su contraseña al servidor.

Luego va al directorio donde desea cargar su archivo, en este caso "logdirectory"

Esto carga un archivo de registro desde el directorio local que se encuentra en / var / log / con el nombre de archivo file.log en el "directorio de registro" en el servidor remoto

rezizter
fuente
Gracias por su respuesta, esperaba una de mis opciones para lograr esta tarea.
anubhava
Gracias. Encontré su respuesta a través de una búsqueda, la utilicé y construí un script con éxito con la expectativa. Acabo de publicar el guión de poterity
rezizter
Muchas gracias por su respuesta, ya lo he votado :)
anubhava
Estoy usando esto para ingresar la frase de contraseña para la clave privada ssh. Es más práctico poner la misma clave pública en todos los servidores y simplemente rotar la frase de contraseña de clave privada periódicamente.
sdkks
24

Puede usar lftp de forma interactiva en un script de shell para que la contraseña no se guarde en .bash_history o similar haciendo lo siguiente:

vi test_script.sh

Agregue lo siguiente a su archivo:

#!/bin/sh
HOST=<yourhostname>
USER=<someusername>
PASSWD=<yourpasswd>

cd <base directory for your put file>

lftp<<END_SCRIPT
open sftp://$HOST
user $USER $PASSWD
put local-file.name
bye
END_SCRIPT

Y escriba / salga del editor vi después de editar el host, el usuario, el pase y el directorio para escribir el archivo put. :wqLuego haga que su script sea ejecutable chmod +x test_script.shy ejecútelo ./test_script.sh.

Mike S.
fuente
2
Para sobrescribir el archivo existente, agregue "set xfer: clobber on" después de lftp << END_SCRIPT
Balaji Natarajan
17

Recientemente me pidieron que cambiara de ftp a sftp, para asegurar la transmisión de archivos entre servidores. Estamos utilizando el paquete Tectia SSH, que tiene la opción --passwordde pasar la contraseña en la línea de comando.

ejemplo: sftp --password="password" "userid"@"servername"

Ejemplo de lote:

(
  echo "
  ascii
  cd pub
  lcd dir_name
  put filename
  close
  quit
    "
) | sftp --password="password" "userid"@"servername"

Pensé que debería compartir esta información, ya que estaba mirando varios sitios web, antes de ejecutar el comando de ayuda ( sftp -h), y me sorprendió ver la opción de contraseña.

Mahony
fuente
9
+1 para ti buena sugerencia. Sin embargo, esto requerirá que pase la contraseña en la línea de comando y cualquiera en el sistema que ejecute el pscomando podrá ver su contraseña.
anubhava 05 de
44
Lo intenté, obtuveunknown option -- - usage: sftp [-1246aCfpqrv] [-B buffer_size] [-b batchfile] [-c cipher] [-D sftp_server_path] [-F ssh_config] [-i identity_file] [-l limit] [-o ssh_option] [-P port] [-R num_requests] [-S program] [-s subsystem | sftp_server] host sftp [user@]host[:file ...] sftp [user@]host[:dir[/]] sftp -b batchfile [user@]host
cyber8200
1
@ihue probablemente porque necesita Techia SSH , no OpenSSH
qris
17

Puede anular habilitando la contraseña sin autenticación. Pero debe instalar claves (pub, priv) antes de hacerlo.

Ejecute los siguientes comandos en el servidor local.

Local $> ssh-keygen -t rsa 

Presione ENTRAR para todas las opciones solicitadas. No es necesario escribir valores.

Local $> cd .ssh
Local $> scp .ssh/id_rsa.pub user@targetmachine:
Prompts for pwd$>  ENTERPASSWORD

Conéctese al servidor remoto con el siguiente comando

Local $> ssh user@targetmachine
Prompts for pwd$> ENTERPASSWORD

Ejecute los siguientes comandos en el servidor remoto

Remote $> mkdir .ssh
Remote $> chmod 700 .ssh
Remote $> cat id_rsa.pub >> .ssh/authorized_keys
Remote $> chmod 600 .ssh/authorized_keys
Remote $> exit

Ejecute el siguiente comando en el servidor local para probar la autenticación sin contraseña. Debe estar conectado sin contraseña.

$> ssh user@targetmachine
SriniV
fuente
1
+1 para su respuesta, pero la pregunta era sobre hacerlo sin claves públicas / privadas.
anubhava
¡Vaya! Acabo de ver las restricciones para compartir claves :)
SriniV
Por curiosidad, ¿este comando lftp -p ${port} -u ${login_id},${password} ${ip_number}cuando se invoca desde un script de shell los imprimirá en alguna parte? ¿Cómo resolviste aparte de sshpass?
SriniV
No tengo lftpy confío en sshpassMac y Linux ambos.
anubhava
Oro puro. ¡Gracias! :)
Nikolay Tsenkov
7

Combine sshpass con un archivo de credenciales bloqueado y, en la práctica, es tan seguro como cualquier otra cosa: si tiene root en el cuadro para leer el archivo de credenciales, todas las apuestas están desactivadas de todos modos.

Rich Harding
fuente
5

Programa Bash para esperar a que sftp solicite una contraseña y luego enviarla:

#!/bin/bash
expect -c "
spawn sftp username@your_host
expect \"Password\"
send \"your_password_here\r\"
interact "

Es posible que deba instalar esperar, cambiar la redacción de 'Contraseña' a 'p' en minúscula para que coincida con lo que recibe su mensaje. El problema aquí es que expone su contraseña en texto plano en el archivo, así como en el historial de comandos. Lo que casi anula el propósito de tener una contraseña en primer lugar.

Eric Leschinski
fuente
+1 pero creo que dices claramente cuáles son los problemas con este enfoque.
Anubhava
5

Puedes usar sshpass para ello. Debajo están los pasos

  1. Instalar sshpass para Ubuntu - sudo apt-get install sshpass
  2. Agregue la IP remota a su archivo de host conocido si es la primera vez Para Ubuntu -> ssh user @ IP -> ingrese 'yes'
  3. dar un comando combinado de scp y sshpass para ello. A continuación se muestra un código de muestra para hacer frente a la guerra a tomcat remoto sshpass -p '#Password_For_remote_machine' scp /home/ubuntu/latest_build/abc.war #user@#RemoteIP:/var/lib/tomcat7/webapps
ravi ranjan
fuente