Como criar um script bash para verificar a conexão SSH?

86

Estou criando um script bash que faria login nas máquinas remotas e criaria chaves públicas e privadas.

Meu problema é que as máquinas remotas não são muito confiáveis ​​e nem sempre funcionam. Preciso de um script bash que verifique se a conexão SSH está ativa. Antes de criar as chaves para uso futuro.

chutsu
fonte
2
Normalmente, é executado ssh-keygenpara gerar um par de chaves na máquina local e, em seguida, ssh-copy-idpara copiar a chave pública para máquinas remotas. Parece que você está fazendo as coisas de forma diferente. Por que, qual é o seu objetivo?
efêmero de
1
Já que você está obviamente mudando a forma como as máquinas remotas estabelecem conexões, considere implantar o mosh . mosh.mit.edu Destina-se a complementar o SSH em conexões instáveis. Tenho experiências muito boas com isso.
Aeyoun
@ephemient Eu sei que é um pouco tarde, mas parece bastante claro que a chave não era para a máquina local ou não para o usuário local.
Carrinho abandonado em

Respostas:

170

Você pode verificar isso com o valor de retorno que ssh fornece:

$ ssh -q user@downhost exit
$ echo $?
255

$ ssh -q user@uphost exit
$ echo $?
0

EDIT: Outra abordagem seria usar o nmap (você não precisa ter chaves ou coisas de login):

$ a=`nmap uphost -PN -p ssh | grep open`
$ b=`nmap downhost -PN -p ssh | grep open`

$ echo $a
22/tcp open ssh
$ echo $b
(empty string)

Mas você terá que fazer um grep na mensagem (o nmap não usa o valor de retorno para mostrar se uma porta foi filtrada, fechada ou aberta).

EDIT2:

Se estiver interessado no estado real do ssh-port, você pode substituí-lo grep openpor egrep 'open|closed|filtered':

$ nmap host -PN -p ssh | egrep 'open|closed|filtered'

Apenas para ser completo.

Tim Cooper
fonte
1
Para ser completo, você pode indicar qual código de retorno significa sucesso e qual significa falha no SSH?
Henley Chiu,
Está se perguntando e se a tentativa de SSH simplesmente travar?
Sibbs Gambling
2
Ótima resposta! No entanto, você não mencionou que a tentativa de sshentrar em um host inativo falha somente após um tempo limite de, por exemplo, 60 segundos - o que pode ser proibitivo para alguns usos. Além disso, se um nome de host for definido em ~/.ssh/config, a primeira sshabordagem funciona, enquanto a segunda nmapfalha com Failed to resolve "<hostname>".
ssc
2
nenhuma explicação sobre os comandos ... ou o que você está realmente fazendo .. o que é $?? etc
Toskan
Uma forma ainda mais concisa de # 1: ssh -q user@downhost exit | echo $? canalizar o resultado da conexão para echo
philn5d
22
ssh -q -o "BatchMode=yes" -i /home/sicmapp/.ssh/id_rsa <ID>@<Servername>.<domain> "echo 2>&1" && echo $host SSH_OK || echo $host SSH_NOK
Brian Ott
fonte
2
Saída de uma linha: (ssh -q -o "BatchMode = yes" -o "ConnectTimeout = 3" [email protected] "echo 2> & 1" && echo SSH_OK || echo SSH_NOK) | tail -n1
Xdg
21

Você pode usar algo assim

$(ssh -o BatchMode=yes -o ConnectTimeout=5 user@host echo ok 2>&1)

Isto irá mostrar "ok" se a conexão ssh estiver ok

Adrià Cidre
fonte
14

Complementando a sua resposta, @Adrià Cidrevocê pode fazer:

status=$(ssh -o BatchMode=yes -o ConnectTimeout=5 user@host echo ok 2>&1)

if [[ $status == ok ]] ; then
  echo auth ok, do something
elif [[ $status == "Permission denied"* ]] ; then
  echo no_auth
else
  echo other_error
fi
iarroyo
fonte
7

Tentar:

echo quit | telnet IP 22 2>/dev/null | grep Connected
GUESSWHOz
fonte
1
Um problema dessa abordagem é que ela não reconhece os hosts definidos em ssh_config (ou seja, / etc / ssh / config ou ~ / .ssh / config)
Ding-Yi Chen
1

O sshcomando abaixo deve ter um código de saída 0em uma conexão bem-sucedida e um valor diferente de zero caso contrário.

ssh -q -o BatchMode=yes [email protected] exit

if [ $? != "0" ]; then
    echo "Connection failed"
fi
mate
fonte
Ótimo! Recomendo também adicionar -o ConnectTimeout = 5, para uma saída mais rápida nos casos em que a porta de destino é filtrada.
Daniel
0

Caso alguém queira apenas verificar se a porta 22 está aberta em uma máquina remota, este comando netcat simples é útil. Eu usei porque nmap e telnet não estavam disponíveis para mim. Além disso, minha configuração de ssh usa autenticação de senha de teclado.

É uma variante da solução proposta por GUESSWHOz.

nc -q 0 -w 1 "${remote_ip}" 22 < /dev/null &> /dev/null && echo "Port is reachable" || echo "Port is unreachable"
Mathieu C.
fonte
0

Se você gostaria de verificar se existe uma pasta remota ou qualquer outro arquivo de teste:

if [ -n "$(ssh "${user}@${server}" [ -d "$folder" ] && echo 1; exit)" ]; then
    # exists
else
    # doesn't exist
fi

Não se esqueça das aspas "$(ssh ...)".

Jonathan H
fonte
Isso não responde à pergunta. O OP deseja verificar se a conexão SSH pode ser estabelecida sem verificar um arquivo em um local ssh remoto.
Rakib Fiha
0

Exemplo usando o script BASH 4+:

# -- ip/host and res which is result of nmap (note must have nmap installed)
ip="192.168.0.1"
res=$(nmap ${ip} -PN -p ssh | grep open)

# -- if result contains open, we can reach ssh else assume failure) --
if [[ "${res}" =~ "open" ]] ;then
    echo "It's Open! Let's SSH to it.."
else
    echo "The host ${ip} is not accessible!"
fi
Mike Q
fonte
0

https://onpyth.blogspot.com/2019/08/check-ping-connectivity-to-multiple-host.html

O link acima é para criar um script Python para verificar a conectividade. Você pode usar um método semelhante e usar:

ping -w 1 -c 1 "IP Address" 

Comando para criar script bash.

Dheeraj Kumar
fonte
2
Isso só fará ping no IP remoto. Não garante se a conexão ssh é possível.
RJ
Obrigado por apontar isso, aqui está o código para ssh xlinu.blogspot.com/2019/09/… export user = "username" export pass = "password" export i = "hostname" export SSHPASS = $ pass sshpass -e ssh $ usuário @ $ i -q "echo $ i está acessível"
Dheeraj Kumar
-7

Sinto que você está tentando resolver o problema errado aqui. Você não deveria tentar tornar os daemons ssh mais estáveis? Tente executar algo como o monit , que verificará se o daemon está rodando e o reiniciará se não estiver (dando a você tempo para encontrar a raiz do problema por trás do desligamento do sshd em você). Ou o serviço de rede é problemático? Tente olhar man ifup. The Whole Damn Thing apenas gosta de fechar em você? Bem, esse é um problema maior ... tente olhar seus logs (comece com syslog) para encontrar falhas de hardware ou serviços que estão desligando seu boxen (talvez um monitor de temperatura?).

Tornar seus scripts tolerantes a falhas é ótimo, mas você também pode querer tornar seu boxen tolerante a falhas.

Sam Bisbee
fonte
4
Sam: existem casos de uso válidos para que o script verifique isso. Por exemplo, (como eu): Tenho um cron job em execução na minha máquina para fazer backup dos meus dados via rsync para o meu NAS doméstico. Agora estou fora ou até mesmo desconectado com frequência e preciso reagendar se a conexão não estiver disponível. Meu boxen funciona muito bem, mas como diz o ditado: é sempre o cabo (também conhecido como rede)
stwissel