Como usar o sshpass?


28

Eu preciso usar sshpasspara iniciar um comando remoto através do SSH a partir de um código Java.

Se eu digitar manualmente um console:

ssh -p 22 user@ipaddress mplayer '/media/data/myFavouriteSong.mp3'

funciona perfeitamente, mas pede senha. Então eu tentei correr sshpass:

sshpass -p mypass ssh -p 22 user@ipaddress mplayer '/media/data/myFavouriteSong.mp3'
sshpass -p mypass ssh -l user@ipaddress mplayer '/media/data/myFavouriteSong.mp3'
sshpass -p mypass ssh -t user@ipaddress mplayer '/media/data/myFavouriteSong.mp3'
sshpass -p mypass ssh user@ipaddress echo 'OK'

e nenhum deles funciona.

Respostas:


28

Isso pode ser causado pelas verificações de chave do host feitas por ssh. Parece que sshpasspermanece silencioso em chaves de host inválidas (sem saída nem stderrnem stdout) e existe com código de status 6. No momento da redação deste texto, essa era a revisão 50, e a constante correspondente no código é RETURN_HOST_KEY_UNKNOWN, o que indica esse erro.

Seu código de erro pode ser diferente e, olhando para o código vinculado acima, pode fornecer algumas dicas.

Se o seu problema for uma chave de host inválida, pense duas vezes em substituir o erro por uma opção da CLI. Sua máquina pode estar comprometida ou você pode estar sujeito a um ataque MITM! Se você estiver 100% certo de que não é esse o caso e se não tiver meios de manter as chaves do host atualizadas, poderá usar um comando como este:

sshpass -pfoobar ssh -o StrictHostKeyChecking=no user@host command_to_run

2
Com a instalação do brew, é necessário um espaço após -p. github.com/hudochenkov/homebrew-sshpass
AnneTheAgile

AVISO: Todos devem se lembrar de que é mais seguro usar chaves de host SSH sem senha sempre que possível! Por definição, o uso do SSHPass é menos seguro.
Questionmark

@Questionmark, enquanto isso é verdade, há casos extremos nos quais o ponto de extremidade remoto não suporta autenticação via chave. É aí que o sshpass é útil
exhuma

Sim eu conheço. É por isso que eu disse "sempre que possível" ...
Questionmark

1
Com o novo SSH suficiente, existe StrictHostKeyChecking=accept-new.
Muru

5

sshpasssó funciona se o prompt de senha terminar assword:.

Se sua solicitação de senha for diferente, talvez seja necessário ajustar o código de origem sshpasspara reconhecer a solicitação que você possui.

Eu vi prompts de senha como Password for user@host:em alguns sistemas, talvez esse seja o seu problema.


1
Desculpe? -P prompt Which string should sshpass search for to detect a password prompt
M3nda # 29/17

2
Esta nova opção (precisa de pelo menos V1.0.6 do sshpass) resolve esse problema.
RJS

Oh, desculpe. Esse tipo de problema (solução?) Acontece com tanta frequência, perguntas antigas que já foram corrigidas em novas versões. Obrigado.
M3nda 02/11

2

Eu acho que você quer algo como:

sshpass -p yourpassword ssh user@ipaddress somecommand

Por exemplo, isso funciona para mim:

sshpass -p mypassword ssh username@10.0.0.9 touch foo

1

Você configurou o login sem senha?

Logins sem senha com o OpenSSH http://www.debian-administration.org/articles/152


Eu prefiro ficar com sshpass, devido aos inconvenientes de permitir autenticação sem senha em uma empresa
Roman Rdgz

Você tentou o seguinte: sshpass -p 'mypass' ssh username@server.example.com
koni_raid

Eu fiz, não importa se eu uso 'mypass' ou mypass. Ele começa a espera para sempre
Roman Rdgz

sshpass -V funciona?
koni_raid

Ele imprime: "Este programa é um software gratuito e pode ser distribuído sob os termos da GPL. Consulte o arquivo COPYING para obter mais informações". E depois termina sua execução e não faz nada mais (Eu tentei adicionar -V para o início do comando que eu estava lidando, não apenas digitando sshpass -V)
Roman Rdgz

1

Há muitas maneiras de fazer isso, aqui está minha solução sugerida:

Primeiro de tudo, armazenar sua senha em uma variável é fornecer comandos mais flexíveis. sshpasstem uma opção para isso:

-e: esta opção permite ler a senha da $SSHPASSvariável de ambiente

Você tem duas maneiras de definir essa variável:

  1. Defina diretamente no seu código:

    export SSHPASS='your_pass'
    
  2. Ou peça:

    readPassword () {
      echo Ssh Password: 
      read -s SSHPASS
      eval "export SSHPASS='""$SSHPASS""'"
    }
    
    # read password
    
    readPassword
    

Do que executar seu comando;

  1. Se o seu comando for estático, execute-o diretamente:

    sshpass -e ssh user@host << EOF
    mplayer '/media/data/myFavouriteSong.mp3'
    command2 parameter1 parameter2 parameter3 ...
    command3 parameter1 parameter2 parameter3 ...
    ...
    EOF
    
  2. Se seu comando for dinâmico, use assim:

    DYN_FILE_LOC='/media/data/myFavouriteSong.mp3'
    
    eval 'sshpass -e ssh user@host << EOF
    mplayer "$DYN_FILE_LOC"
    command2 parameter1 parameter2 parameter3 ...
    command3 parameter1 parameter2 parameter3 ...
    ...
    EOF'
    

espero que isso ajude alguém.


Na sua função readPassword, você não pode simplesmente exportar SSHPASS?
Kutschkem

@kutschkem, eu confio, mas minha ideia é que penso aqui; Eu não quero escrever minha senha em um arquivo estático, mas em vez de escrever a senha repetidamente para muitos servidores (7 ou mais), escrevo uma vez :) Você não precisa usar a readPasswordfunção, basta escrever sua senha, deve funcionar :) Só quero compartilhar meu código que é mostra um exemplo usando sshpasspara comandos dinâmicos: D
veysiertekin

Não, apenas quero dizer que a avaliação não é necessária após a leitura, a exportação não precisa de uma atribuição. ss64.com/bash/export.html
kutschkem

o problema com -e é que a exportação será listada no seu histórico
ejaenv

0

sshpassusa pseudo terminais e a manpágina inclui desculpas por quebrar ocasionalmente. Você também pode tentar fd0ssh. Funciona se você não precisar enviar stdinpara um processo na máquina remota. Isso funciona se você apenas emitir um comando e capturar o resultado.


0

A sintaxe sshpass é

sshpass [-ffilename|-dnum|-ppassword|-e] [options] command arguments

Observe que não há espaço entre o -p e a senha.

Também tenho notado que você tem que se conectar com ssh pelo menos uma vez manualmente para obter a chave RSA da máquina que você está se conectando, para ir para o ~/.ssh/known_hostsarquivo antes sshpass permitirá que você se conectar.

então, depois de obter a entrada no arquivo known_hosts, posso executar um comando como

sshpass -ffilename_with_password_in_it ssh user@server uname -a

e executará o comando uname -ano servidor remoto e enviará os resultados para o padrão na máquina local.


0

O que você precisa é -f -t -t -t

sshpass -p$PASS ssh -f -t -t -t $USER@$HOST $COMMAND

Além disso, pode ser necessário remover o "requiretty" do sudo config (/ etc / sudoers) na máquina remota.


0
  1. faça uma chave

    ssh-keygen -t rsa

  2. criar uma pasta .ssh no servidor remoto, ele solicitará uma senha

    ssh $USER@SEVERNAME mkdir -p .ssh

  3. copie a chave para o servidor remoto

    cat .ssh/id_rsa.pub | ssh $USER@SERVER 'cat >> .ssh/authorized_keys'


Verifique se ele pede uma senha; caso contrário, deve funcionar.

ssh $USER@SEVERNAME 'command'

0

A @exhuma teve um exemplo que o levou a trabalhar para mim.

A senha precisa estar na forma de -pPassword(sem o espaço)

citações também podem ser necessárias: sshpass -p'Password&0' user@hostname

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.