Digite automaticamente a senha SSH com script

193

Preciso criar um script que insira automaticamente uma senha para o sshcliente OpenSSH .

Digamos que eu precise fazer o SSH myname@somehostcom a senha a1234b.

Eu já tentei ...

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

... mas isso não funciona.

Como posso obter essa funcionalidade em um script?

user1467855
fonte

Respostas:

278

Primeiro você precisa instalar o sshpass .

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

Exemplo:

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

Exemplo de porta personalizada:

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

Notas:

  • sshpasstambém pode ler uma senha de um arquivo quando a -fbandeira é passada.
    • O uso -fevita que a senha seja visível se o pscomando for executado.
    • O arquivo em que a senha está armazenada deve ter permissões seguras.
abbotto
fonte
12
Isso é muito melhor do que usar o Expect.
Por Mejdal Rasmussen
5
esteja ciente de que, embora o sshpass bloqueie sua senha de comandos como ps -aux, normalmente você não deve executar comandos digitando sua senha, porque outros usuários no mesmo computador poderão ver a senha executando ps -aux. se for prático, você também deseja usar a autenticação de chave pública, como mencionado na outra resposta. isso permite que você separe as informações de autenticação do seu script para poder compartilhá-lo com outras pessoas, sem preocupações, e depois decidir ativar a criptografia na sua pasta ~ / .ssh sem também criptografar o script.
Alexander Taylor
2
Infelizmente, isso não está funcionando para mim em um servidor com uma porta ssh personalizada ... por que o ssh não pode nos dar a opção de inserir a senha na linha de comando?
Andy
2
para porta personalizada ao trabalho add "port-number -p" no final do comando
Ye Lwin Soe
1
Adicionei uma resposta com um uso mais seguro desshpass .
21417 Ian Ian
95

Depois de procurar uma resposta para a pergunta por meses, finalmente encontrei uma solução melhor: escrever um script simples.

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

Coloque /usr/bin/exp, então você pode usar:

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

Feito!

damn_c
fonte
2
Esta resposta deve receber mais votos, é um ótimo invólucro. Apenas tentei algumas operações comuns, como rsyncing com vários sinalizadores e execução de comandos remotos, e funcionou sempre. Adicionado à minha caixa de ferramentas de scripts úteis, Obrigado @damn_c!
User2082382
7
Talvez não tenha recebido mais votos porque as pessoas não esperavam isso?
Clearlight
7
A razão para isso não é IMO uma resposta muito boa é porque a senha está escrito no script que é de longe o método menos seguro ...
Pierree
8
A senha será visível por qualquer pessoa que execute ps na máquina.
Daniel Persson
22
"assword" is amazing :-)
Ciro Santilli escreveu:
71

Use a autenticação de chave pública: https://help.ubuntu.com/community/SSH/OpenSSH/Keys

No host de origem, execute isso apenas uma vez:

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

Isso é tudo, depois disso você poderá fazer o ssh sem senha.

Diego Woitasen
fonte
21
Entendo. Mas eu sou obrigado a ssh com senha. Isso ocorre porque "I" pode ter o script em um pen drive e precisa executá-lo em qualquer computador; enquanto não desabilita a necessidade de senha.
user1467855
3
@ user1467855, acho que você precisa explicar melhor seus requisitos. Ninguém está sugerindo que você tenha uma rede não segura. Na abordagem de chave pública, ainda seria possível que os usuários efetuassem login com a senha. Mas você copiaria a chave privada no seu pen drive, o que significa que o pen drive seria a única coisa que pode efetuar login sem uma senha.
Aaron McDaid
5
Infelizmente, estou na situação de OP, porque o sysadmin desabilita a autenticação por chaves rsa / dsa e requer senhas. O que você vai fazer.
Karel Bílek
26
Voto negativo, porque isso nem tenta responder à pergunta real.
Parthian Shot
2
Isso ainda solicita o primeiro login e não pode ser usado em um script!
Mehrdad Mirreza
29

Você pode usar um script esperado. Eu não escrevi um há algum tempo, mas deve se parecer com abaixo. Você precisará encabeçar o script com#!/usr/bin/expect

#!/usr/bin/expect -f
spawn ssh HOSTNAME
expect "login:" 
send "username\r"
expect "Password:"
send "password\r"
interact
Lipongo
fonte
Eu fiz como você sugeriu, mas obter os seguintes erros:/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
user1467855
Obrigado Aaron por modificar minha resposta para estar correta. Pode ser necessário executar o comando abaixo para encontrar o caminho correto a ser esperado. which expect
Lipongo 30/08/12
1
Você também pode usar esta linha shebang:#!/usr/bin/env expect
glenn jackman
1
Eu adicionei interactao fim de modo a sessão ssh é realmente interativo
Karel Bílek
-1 para o enorme risco de segurança de manter uma senha de texto sem formatação em um 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
fonte
O -psinalizador é para especificar um número de porta.
Kookerus
4
Não. Sshpass não é ssh. SYNOPSIS sshpass [-ffilename|-dnum|-ppassword|-e] [options] command arguments
RemiZOffAlex
Para executar sshpass em Linux CentOS você deve yum -y install epel-releasee depoisyum -y install sshpass
júnior Mayhé
Neste contexto destes dados pode ser ignorado
RemiZOffAlex
Embora eu saiba que este é um post antigo, vale a pena notar que o método Variant II deixaria a senha dada à sessão vulnerável no histórico do bash, tornando-o altamente desaconselhável.
22918 Kirkland
10

sshpass + autossh

Um bom bônus do já mencionado sshpassé que você pode usá-lo autossh, eliminando ainda mais a ineficiência interativa.

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

Isso permitirá a reconexão automática se, por exemplo, seu wifi for interrompido, fechando o seu laptop.

Sridhar Sarnobat
fonte
2
Note que você não pode adicionar opção -fpara autossh nesta combinação, pois when used with autossh, ssh will be *unable* to ask for passwords or passphrases. harding.motd.ca/autossh/README.txt também superuser.com/questions/1278583/...
allenyllee
9

sshpass com melhor segurança

Eu tropecei nesse segmento enquanto procurava uma maneira de ssh em um servidor atolado - demorou um minuto para processar a tentativa de conexão SSH, e atingi o tempo limite antes que eu pudesse inserir uma senha. Nesse caso, eu queria poder fornecer minha senha imediatamente quando o prompt estivesse disponível.

(E se não for muito claro: com um servidor nesse estado, é tarde demais para configurar um login de chave pública.)

sshpasspara o resgate. No entanto, existem maneiras melhores de fazer isso do que sshpass -p.

Minha implementação pula diretamente para o prompt de senha interativa (sem perda de tempo, verificando se pode ocorrer troca de chave pública) e nunca revela a senha como texto sem formatação.

#!/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
fonte
1
Nota to self: script de atualização para usar trappara evitar ctrl-C de vazar a SSHPASSvariável
Ian
1
Descobri que PreferredAuthentications=keyboard-interactivenão funcionava, mas substituí-lo por PreferredAuthentications=passwordfuncionou.
Mike Partridge
7

É assim que eu faço login nos meus servidores.

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

#! / bin / bash

sshpass -p minha senha ssh root @ $ 1

E portanto ...

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

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

RmccurdyDOTcom
fonte
3
Acho que este artigo está sendo sarcástico!
21716 Yan Foto
5

Eu não acho que vi alguém sugerir isso e o OP acabou de dizer "script", então ...

Eu precisava resolver o mesmo problema e minha linguagem mais confortável é Python.

Eu usei a biblioteca paramiko. Além disso, eu também precisava emitir comandos para os quais eu precisaria de permissões escaladas usando sudo. Acontece que o sudo pode aceitar sua senha via stdin através da bandeira "-S"! Ver abaixo:

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 isso ajude alguém. Meu caso de uso foi criar diretórios, enviar e descompactar arquivos e iniciar programas em ~ 300 servidores por vez. Como tal, a automação foi fundamental. Eu tentei sshpass, expecte depois criei isso.

John Carrell
fonte
2

Eu consegui isso da seguinte maneira

.ssh / config foi modificado para eliminar o prompt sim / não - estou atrás de um firewall, portanto não estou preocupado com chaves ssh falsificadas

host *
     StrictHostKeyChecking no

Crie um arquivo de resposta para expect, por exemplo, 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

Crie seu script bash e chame apenas expect no arquivo

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

  expect answer.expect hadoopslave$i

  i=[$i + 1]
  sleep 5

done

Obtém 128 dados do hadoop atualizados com a nova configuração - assumindo que você esteja usando uma montagem NFS para os arquivos hadoop / conf

Espero que isso ajude alguém - eu sou um Windows entorpecido e isso me levou cerca de 5 horas para descobrir!

WT29
fonte
"Estou atrás de um firewall, então não estou preocupado com as chaves ssh falsificadas". Um firewall não faz exatamente nada neste caso. O HostKeyCheck é para que você possa verificar se o host do outro lado não é um host de trojan. Ou seja, aquele que está apenas fingindo estar onde você deseja se conectar. Se você se conectar a um host desconhecido e fizer algo confidencial, como gravar um arquivo que tenha credenciais ou um token ou digitar uma senha, essas informações agora são efetivamente de conhecimento público. Você estar atrás de um firewall é irrelevante.
JCGB
2

Se você estiver fazendo isso em um sistema Windows, poderá usar o Plink (parte do PuTTY).

plink your_username@yourhost -pw your_password
Marko Vranjkovic
fonte
1

Eu consegui fazê-lo funcionar com isso:

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

No exemplo abaixo, escreverei a solução que usei:

O cenário: quero copiar o arquivo de um servidor usando o 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
fonte
-2

Use esse script para lançar dentro do script, o primeiro argumento é o nome do host e o segundo será a senha.

#!/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
fonte
O que isso mostra sobre as respostas existentes? Particularmente aqueles por damn_c, Lipongo ou RemiZOffAlex e outros ...
Martin Prikryl
execução de script junto com ssh #! / usr / bin / expect definir passe [lindex $ argv 1] definir host [lindex $ argv 0] gerar ssh -t raiz @ $ host sh /tmp/anyscript.sh expect "* assword:" envie "$ pass \ n"; interagir "
Shivam Mehrotra
-3

Para conectar uma máquina remota através de scripts shell, use o comando abaixo:

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

onde IPADDRESS, USERNAMEe PASSWORDsão valores de entrada que precisam fornecer no script, ou se queremos proporcionar em uso runtime "ler" de comando.

shyam
fonte
5
O que essa resposta mostra sobre as respostas existentes? + Nunca sugira alguém para usar StrictHostKeyChecking=nosem explicar as consequências.
Martin Prikryl
-5
sudo ssh username@server_ip_address -p port_number

pressione a tecla enter e digite a senha do seu sistema e, finalmente, digite a senha do servidor

Manoj Rana
fonte