Como executar o comando sftp com uma senha do script Bash?

173

Preciso transferir um arquivo de log para um host remoto usando sftp de um host Linux. Recebi credenciais para o mesmo do meu grupo de operações. No entanto, como não tenho controle sobre outro host, não posso gerar e compartilhar chaves RSA com o outro host.

Portanto, existe uma maneira de executar o sftpcomando (com o nome de usuário / senha fornecido) de dentro do script Bash por meio de um trabalho cron ?

Encontrei uma pergunta semelhante ao Stack Overflow, Especifique a senha para sftp em um script Bash , mas não houve resposta satisfatória para o meu problema.

anubhava
fonte

Respostas:

178

Você tem algumas opções além de usar autenticação de chave pública:

  1. Use chaveiro
  2. Use sshpass (menos seguro, mas provavelmente que atenda às suas necessidades)
  3. Use expect (menos seguro e mais codificação necessária)

Se você decidir dar uma chance ao sshpass, aqui está um trecho de script de trabalho para fazê-lo:

export SSHPASS=your-password-here
sshpass -e sftp -oBatchMode=no -b - sftp-user@remote-host << !
   cd incoming
   put your-log-file.log
   bye
!
anubhava
fonte
3
Para usá-lo no Mac: stackoverflow.com/questions/9102557/…
anubhava 27/02/2012
18
Não precisa exportar, eu acho. SSHPASS=password sshpass -e ...deveria fazer.
Jens
9
Eu era capaz de fazer um one-liner para fazer o download de um arquivo de log:sshpass -p "my_password" sftp -oPort=9999 user@host:dir/file.log
Nuvem Artesãos
6
@ Gorus: One-liner é muito legal, no entanto, eu não queria usar a senha na linha de comando por causa dos riscos aprimorados de bisbilhoteiros.
Anubhava
8
-oBatchMode=nofoi a peça que faltava para mim.
Richardkmiller
99

Outra maneira seria usar o lftp:

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

A desvantagem desse método é que outros usuários no computador podem ler a senha de ferramentas como pse que a senha pode se tornar parte do seu histórico de shell.

Uma alternativa mais segura disponível desde o LFTP 4.5.0 é definir a LFTP_PASSWORDvariável de ambiente e executar o lftp --env-password. Aqui está um exemplo completo:

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

O LFTP também inclui um recurso interessante de espelhamento (pode incluir exclusão após transferência confirmada --Remove-source-files):

lftp -e 'mirror -R /local/log/path/ /remote/path/' --env-password -u user sftp.foo.com
Karassik
fonte
9
+1 por sugerir uma alternativa, mas podemos evitar o fornecimento de senha na linha de comando?
Anubhava
1
Downvoted para mostrar a senha a ninguém no mesmo computador
Aaron Digulla
10
Você pode criar o arquivo de script para lftp, desta forma não precisará fornecer a senha na linha de comando. Crie um arquivo put-script: open sftp://user:password@host; put local-file.name; exit Execute lftp -f put-script Dessa forma, você não precisa ter o nome de usuário e a senha em uma linha de comando e pode configurar permissões restritivas ao seu arquivo de script.
Obaranovsky #
@obaranovsky Essa é uma boa ideia. Gostaria de saber se eu adicionaria isso à minha variável de ambiente como alias ou função, seria seguro e possível ocultá-lo de outros usuários?
Sdkks
1
Muito mais fácil de fazer do lftpque mexer com sftpe sshpass. Boa resposta.
MeanEYE
53

O Expect é um ótimo programa para usar.

No Ubuntu, instale-o com:

sudo apt-get install expect

Em uma máquina CentOS, instale-o com:

yum install expect

Digamos que você queira fazer uma conexão com um servidor sftp e depois fazer upload de um arquivo local da sua máquina local para o servidor sftp remoto

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

Isso abre uma conexão sftp com sua senha para o servidor.

Em seguida, ele vai para o diretório em que você deseja enviar o arquivo, neste caso "diretório de log"

Isso carrega um arquivo de log do diretório local encontrado em / var / log / com o nome de arquivo file.log no "diretório de log" no servidor remoto

rezizter
fonte
Obrigado pela sua resposta, eu esperava como uma das minhas opções para realizar esta tarefa.
Anubhava 28/03
Obrigado. Encontrei sua resposta através de uma pesquisa, usei-a e criei um script com êxito com expect. Só postou o script para poterity
rezizter
Muito obrigado pela sua resposta, eu já o votei :) :) #
31 anubhava
Estou usando isso para inserir a senha da chave privada ssh. É mais fácil colocar a mesma chave pública em todos os servidores e apenas girar a senha da chave privada periodicamente.
Sdkks
24

Você pode usar o lftp interativamente em um script de shell para que a senha não seja salva em .bash_history ou similar, fazendo o seguinte:

vi test_script.sh

Adicione o seguinte ao seu arquivo:

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

E escreva / saia do editor vi depois de editar o host, o usuário, a passagem e o diretório para a digitação do arquivo put. :wqDepois, torne seu script executável chmod +x test_script.she execute-o ./test_script.sh.

Mike S.
fonte
2
Para substituir o arquivo existente, adicione "set xfer: clobber on" após o lftp << END_SCRIPT
Balaji Natarajan
17

Recentemente, fui convidado a mudar de ftp para sftp, a fim de garantir a transmissão de arquivos entre servidores. Estamos usando o pacote Tectia SSH, que tem uma opção --passwordpara passar a senha na linha de comando.

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

Exemplo de lote:

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

Eu pensei que deveria compartilhar essas informações, já que estava procurando em vários sites, antes de executar o comando help ( sftp -h), e fiquei surpreso ao ver a opção de senha.

Mahony
fonte
9
+1 para você boa sugestão. No entanto, isso exigirá que você passe a senha na linha de comando e qualquer pessoa no sistema psque esteja executando o comando poderá ver sua senha.
Anubhava
4
Tentei fazer isso, eu tenhounknown 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 provavelmente porque você precisa do Techia SSH , não do OpenSSH
qris
17

Você pode substituir ativando a Senha com menos autenticação. Mas você deve instalar as chaves (pub, priv) antes de prosseguir.

Execute os seguintes comandos no servidor local.

Local $> ssh-keygen -t rsa 

Pressione ENTER para todas as opções solicitadas. Nenhum valor precisa ser digitado.

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

Conecte-se ao servidor remoto usando o seguinte comando

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

Execute os seguintes comandos no 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

Execute o seguinte comando no servidor local para testar a autenticação sem senha. Deve ser conectado sem senha.

$> ssh user@targetmachine
SriniV
fonte
1
+1 na sua resposta, mas a pergunta era sobre fazer isso sem chaves públicas / privadas.
Anubhava
oops .. Só vi as restrições sobre a partilha de chave :)
SriniV
Por curiosidade, esse comando, lftp -p ${port} -u ${login_id},${password} ${ip_number}quando invocado a partir de um script de shell, os imprime em algum lugar? Como você resolveu além do sshpass?
SriniV
Eu não tenho lftpe confio no sshpassMac e no Linux.
Anubhava
Ouro puro. Obrigado! :)
Nikolay Tsenkov /
7

Combine sshpass com um arquivo de credenciais bloqueadas e, na prática, é tão seguro quanto qualquer outra coisa - se você tiver uma raiz na caixa para ler o arquivo de credenciais, todas as apostas serão desativadas de qualquer maneira.

Rich Harding
fonte
5

Programa Bash para aguardar que o sftp solicite uma senha e envie-a junto:

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

Pode ser necessário instalar o expect, altere o texto de 'Senha' para minúsculas 'p' para corresponder ao que o prompt recebe. O problema aqui é que ela expõe sua senha em texto sem formatação no arquivo e também no histórico de comandos. O que quase derrota o propósito de ter uma senha em primeiro lugar.

Eric Leschinski
fonte
+1, mas acho que você afirma claramente quais são os problemas dessa abordagem.
Anubhava
5

Você pode usar o sshpass para isso. Abaixo estão os passos

  1. Instale o sshpass para Ubuntu - sudo apt-get install sshpass
  2. Adicione o IP remoto ao seu arquivo host conhecido, se for a primeira vez. Para Ubuntu -> ssh user @ IP -> digite 'yes'
  3. dê um comando combinado de scp e sshpass para ele. Abaixo está um código de exemplo para lidar com a guerra no tomcat remoto sshpass -p '#Password_For_remote_machine' scp /home/ubuntu/latest_build/abc.war #user@#RemoteIP:/var/lib/tomcat7/webapps
Ravi Ranjan
fonte