Lista de servidores para verificar a disponibilidade do SSH

6

Eu tenho uma lista de endereços IP que eu preciso para o SSH para logar se eu puder acessá-los. Eu usaria um script Ping, mas o DNS já poderia ter reatribuído o endereço. Eu não me importo com os que eu não consigo. Se o SSH funcionar eu preciso registrar esse endereço IP, eu não deveria ter que me preocupar com senhas ou chaves, porque eu não quero fazer login na caixa. Eu só quero ver se posso SSH para eles. Até agora eu tenho:

touch logfile_$(date "+%Y%m%d%T")
IP_FILE="path/to/ip_address.txt"
LOGFILE="path/to/logfile_$(date "+%Y%m%d%T")"


if [[ ! -f ${IP_FILE} ]]; then
   echo "Cannot find IP address!"
   exit 1
fi

for IP_ADDRESS in 'cat $IP_FILE' ; do

    ssh $IP_ADDRESS >> $LOGFILE 2>&1

Ainda sou novo em scripts e qualquer ajuda seria ótima. Eu olhei para "Como verificar se consigo fazer login no servidor via ssh?" postado por LanceBaynes mas não é realmente o que eu preciso.

Não consigo instalar nada nessas caixas. Ou eu teria baixado um scanner legal. Como o Netcat ou o Nmap, ambos são ótimas opções.

    
por Dolyak 05.07.2013 / 15:09

4 respostas

11

Método 1: ssh-keyscan

Um método seria usar o comando ssh-keyscan para ver se um daemon ssh está ativo e funcionando.

Basta percorrer os endereços IP e ssh-keyscan <ip> | grep -v ... de cada servidor. Se o servidor estiver lá, o status retornado pela execução do comando ssh-keyscan ... | grep -v ... será 0, qualquer outra coisa (1 ou superior) significa que não há um servidor lá.

Exemplo

$ for IP_ADDRESS in 'cat $IP_FILE' ; do
    ssh-keyscan $IP_ADDRESS 2>&1 | grep -v "^$" > /dev/null
    [ $? == 0 ] && echo $IP_ADDRESS >> $LOGFILE 2>&1
  done

Apenas para detalhar isso um pouco mais, é claro o que está acontecendo, o ssh-keyscan $IP_ADDRESS 2>&1 será executado, qualquer saída retornada (ambos stderr & stdout serão mesclados). Toda essa saída é canalizada para o grep -v "^$" , que retornará um 0 para as linhas que retornam a saída (servidores ssh em execução) e um 1 para os servidores que não retornam (o "^$" é uma linha em branco).

Tangente rápida em loops (por vs. enquanto e como eles analisam)

O mecanismo de looping acima (para loop) funciona porque o arquivo contém apenas uma cadeia de caracteres dos quais nenhum é um espaço e que cada "string" é terminada por um novo caractere de linha. Por padrão, um espaço é o caractere de separação especial usado para designar ao loop for como analisar os argumentos que estão sendo passados para ele. Esse caractere é definido pela variável $IFS e pode ser substituído de forma que seja o novo caractere de linha ( IFS='^M' ), por exemplo.

Você pode tornar isso um pouco mais eficiente ao substituir o cat $IP_FILE por $( < $IP_FILE ) . Por exemplo:

$ for IP_ADDRESS in $( < $IP_FILE ) ; do
    ssh-keyscan $IP_ADDRESS 2>&1 | grep -v "^$" > /dev/null
    [ $? == 0 ] && echo $IP_ADDRESS >> $LOGFILE 2>&1
  done

Se as linhas no arquivo $IP_FILE incluírem espaços, você poderia substituir o $IFS , conforme discutido há pouco, para que ele fosse definido como ^M ou um loop while poderia ser usado, ou seja, ( while read -ra line ; do ... ; done < $IP_FILE ).

$ while read -ra IP_ADDRESS ; do
    ssh-keyscan $IP_ADDRESS 2>&1 | grep -v "^$" > /dev/null
    [ $? == 0 ] && echo $IP_ADDRESS >> $LOGFILE 2>&1
  done < $IP_FILE

Seu exemplo

touch logfile_$(date "+%Y%m%d%T")
IP_FILE="ip.txt"
LOGFILE="logfile_$(date "+%Y%m%d%T")"


if [[ ! -f ${IP_FILE} ]]; then
 echo "Cannot find IP address!"
 exit 1
fi

for IP_ADDRESS in 'cat $IP_FILE' ; do
  #ssh $IP_ADDRESS >> $LOGFILE 2>&1
  ssh-keyscan $IP_ADDRESS 2>&1 | grep -v "^$" > /dev/null
  [ $? == 0 ] && echo $IP_ADDRESS >> $LOGFILE 2>&1
done

Método # 2: nmap

Você também pode fazer algo com a ferramenta nmap .

$ nmap -A -iL ip.txt -p T:22

Isso passará pelo arquivo ip.txt , que pode conter nomes de host e endereços IP, e varrerá a porta TCP # 22 de cada um, retornando resultados semelhantes aos seguintes:

Nmap scan report for somehost.somedom.local (192.168.1.200)
Host is up (0.012s latency).
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 4.3 (protocol 2.0)
| ssh-hostkey: 1024 2e:32:85:a2:56:23:01:f1:c2:8f:df:aa:83:7a:1e:ad (DSA)
|_2048 f6:a1:23:1d:aa:44:4a:ce:b4:d3:f4:fe:e1:00:47:b7 (RSA)

Referências

por 05.07.2013 / 15:26
4

Você está procurando o utilitário netcat (o executável binário é chamado de nc ). Ele pode executar vários testes de rede, entre os quais um teste somente de conexão com a porta TCP 22 também funcionaria. Se você estiver usando o antigo utilitário netcat, o comando é:

nc -vz [ip.or.hostname] 22 -w [desired.timeout.value.in.seconds]

Acredito que a versão atualizada se livrará da opção -z por padrão.

Por exemplo:

[jadavis6@cmsoracle ~]$ nc -vz wfwhite.xxx.edu 22 -w 5
nc: connect to wfwhite.xxx.edu port 22 (tcp) timed out: Operation now in progress
[jadavis6@cmsoracle ~]$ echo $?
1
[jadavis6@cmsoracle ~]$ nc -vz ditirlns01.xxx.edu 22 -w 5
Connection to ditirlns01.xxx.edu 22 port [tcp/ssh] succeeded!
[jadavis6@cmsoracle ~]$ echo $?
0
[jadavis6@cmsoracle ~]$
    
por 05.07.2013 / 15:25
4

Alguém mencionou o netcat, mas vou recomendar o nmap, pois é um dos comandos para fazer o que você quer.

nmap -iL path/to/ip_address.txt -p 22

Isso fornecerá todas as informações de que você precisa.

    
por 05.07.2013 / 15:36
1

Se você não pode instalar nada, você deve ser capaz de fazer algo assim (adaptado de aqui ):

$ for ip in 'cat ips.txt'; do 
    ssh -o PreferredAuthentications=publickey foobar@$ip "echo ''" 2>&1 | 
    grep denied >/dev/null && echo "$ip has SSH"; 
  done < ips.txt

O truque aqui é PreferredAuthentications . Isso diz ao ssh para tentar se conectar usando as informações de chave armazenadas em ~/.ssh . Contanto que o usuário foobar não tenha acesso ao sistema remoto (altere-o para qualquer nome aleatório desejado), a conexão falhará com um erro "Permissão negada". Isso significa que o grep denied será bem-sucedido e, portanto, o comando echo será executado. && significa executar o próximo comando se o anterior (aqui, o grep ) foi bem sucedido.

Se você executar este scriptlet em um arquivo contendo os IPs, ele imprimirá apenas os servidores com um serviço ssh em execução.

    
por 05.07.2013 / 16:23