Script EXPECT para acesso SSH automático

Para acessar determinadas máquinas Linux, Administratores em geral usam o protocolo SSH. Isso fornece controle total da máquina remotamente, via linha de comando.

Este POST aborda uma maneira automática para que o Administrador não precise interagir com o SSH para digitar a senha da máquina linux remota que está querendo acessar. Logicamente, a senha precisa ser informada de alguma otura forma (neste caso via parâmetro/argumento), pois quem vai interagir com o SSH ao invés do ser humano é o EXPECT.Segue código:

#!/usr/bin/expect -f
set timeout 500
if {$argc != 3} { puts “use: $argv0 usuario senha ip_do_linux”; exit 0; }
set usuario [lindex $argv 0]
set senha [lindex $argv 1]
set ip_do_linux [lindex $argv 2]
spawn -noecho ssh $usuario@$ip_do_linux
expect “assword:” { send “$senhar” }
interact;

O código acima pode ser colocado dentro de qualquer arquivo com permissão para execução. Neste exemplo foi usado o nome lnxremoto.exp.

Ao executar ./lnxremoto.exp sem parâmetros/argumentos, o script retorna a maneira correta de se utilizar, conforme abaixo:

root@localhost:/tmp/cialinux# ./lnxremoto.exp
use: ./lnxremoto.exp usuario senha ip_do_linux
root@localhost:/tmp/cialinux#

Ao executar o programa de forma correta, o resultado é um prompt de acesso à máquina, conforme abaixo:

root@localhost:/tmp/cialinux# ./lnxremoto.exp root ****senha**** 192.168.0.1
root@192.168.0.1’s password:
Last login: Fri Jun 26 10:39:57 2009 from 192.168.0.40
[root@gateway root]#

Observação: É importante que o Administrador já tenha acessado a máquina anteriormente, para que o arquivo ~/.ssh/known_hosts já esteja preenchido. Caso contrário, o SSH irá pedir confirmação para gerar a chave RSA para o IP em questão, e se isso acontecer, o EXPECT não estará esperando essa pergunta e não saberá como interagir.

Se for o caso, existem formas de implementar uma limpeza no arquivo ~/.ssh/known_hosts para que sempre seja necessário confirmar com “yes” antes de digitar a senha. Assim basta ensinar seu script EXPECT a interagir com “yes” sempre que for detectada a palavra ‘connecting’.

Outros controles que podem ser implementados junto com a interação da chave RSA são: Interação em caso de erro de conexão recusada; Interação em caso de tempo esgotado; Interação em csao de falta de rota para host;

Conforme códigos abaixo:

expect “connecting” { send “yesr” }
“refused” { send_user “ERRO: Conexão recusada por $ip_do_linuxn”; exit 0; }
“timed” { send_user “ERR: Conexão excedeu o tempo limite.n”; exit 0;}
“No route to host” { send_user “***ERRO: Sem rota para $ip_do_linuxn”; exit 0; }
expect “assword:” { send “$passwdr” }

Também existe uma forma de fazer o EXPECT já executar automaticamente um comando na máquina remota, conforme abaixo:

expect “#” {
send “hostnamer”;
}

Mesmo com toda essa automação, é importante usar apenas em casos especiais pois sabemos que não é uma boa prática utilizar senha passada como parâmetro. Mesmo colocando a senha em arquivo ou em variáveis no SCRIPT, fica vulnerável.

Sinte-se a vontade para deixar seus comentários para melhoria do código aqui exposto e também outras formas de se solucionar o mesmo problema. Dúvidas também serão respondidas com satisfação.

Por: Hudson Murilo dos Santos

6 thoughts on “Script EXPECT para acesso SSH automático

  1. Na minha utilização do ssh com o expect faço da seguinte maneira:

    spawn ssh -o StrictHostKeyChecking=no $USER@$IP

    Com a opção “-o StrictHostKeyChecking=n” ele não pede confirmação para gerar a chave RSA… 😉

    Abraço!

  2. Sei que o post é antigo, mas o artigo é muito importante para quem trabalha com infraestrutura e deseja automatizar algumas tarefas. Bom, primeiramente eu gostaria de lhes desejar um ótimo início de ano (Hudson e Franklin) e gostaria de deixar uma dica com base nesta aí de cima. Eu utilizo “screen + sshpass”, então dentro do screenrc fica “screen -t ‘FirewallCUA’ 0 sshpass -p ssh @”, quando abro meu screen já tenho as principais telas de trabalho do dia a dia. Não desistam, continuem postando !!! Abraços.

    1. Obrigado Scotti pela dica e incentivo. A meu ver o post em blogs é apenas mero combustível inicial para o verdadeiro fogo que acontece nos comentários do post, aqui onde você contribuiu. Obrigado novamente! Ainda estamos com pouco movimento aqui no BLOG CIALINUX, que ainda é relativamente novo e pouco divulgado.

      Essa dica é uma boa mesmo pra deixar ainda mais automático o acesso às máquinas pelo screen..

      Sempre que possível, estamos postando por aqui. É bom postar quando aparece uma informação relevante pra comunidade. Pra não acabar postando simplesmente por postar, sabe?

      Alias, se você tiver escrito algo, sinta-se a vontade pra me enviar que eu posto aqui em seu nome.. Quem sabe até criamos uma conta pra você se tu quiser. Botãozinho [blog] no site da trustnet.. e por aí vai… Sabes que contigo é parceria de longa-data. O Blog é um recurso que está aqui pra ser usado. Está esperando alguém que utilize-o plenamente. Tem aproximadamente 5 anos de vida e 70 posts e quando estava hospedado nos sites da wordpress.com tinha em média 1.000 visitas/mês, agora que tiramos de lá, diminuiu um pouco. Mas é só voltar a divulgação que alcançamos isso novamente.

      Forte abraço e volte sempre.

      Atenciosamente,

  3. Boa tarde encontrei este blog em consulta no google. Estou montando um script para atualização de servidores linux onde faço uma copia de arquivo.
    spawn scp $fpath/$fname root@$host:”arquivo”

    Estou tentando imprimir em um arquivo texto o resultado dos comandos onde a copia foi executada com sucesso:
    set flog [open saida.txt w]
    log_file log/saida.txt
    puts $flog “arquivo $fname copiado em $host”

    Porém neste arquivo saida.txt ele esta imprimindo todos os comandos de forma interativa. Como faço para que ele imprima apenas o resultado final?

    atte

    1. Poisé Gustavo, boa pergunta! Eu também ainda não sei a resposta para esta sua pergunta. Vamos continuar pesquisando. Quem achar primeiro posta aqui. Forte abraço e obrigado pela leitura.

Leave a Comment

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *