Existe uma maneira de programaticamente obter uma impressão digital da chave do servidor SSH sem autenticação para ele?

Estou tentando ssh -v user@host false 2>&1 | grep "Server host key", mas isso trava esperando por uma senha se a autenticação baseada em chave não estiver configurada.

Resposta

Você pode fazer isso combinando ssh-keyscan e ssh-keygen:

$ file=$(mktemp) $ ssh-keyscan host > $file 2> /dev/null $ ssh-keygen -l -f $file 521 de:ad:be:ef:de:ad:be:ef:de:ad:be:ef:de:ad:be:ef host (ECDSA) 4096 8b:ad:f0:0d:8b:ad:f0:0d:8b:ad:f0:0d:8b:ad:f0:0d host (RSA) $ rm $file 

(infelizmente, o muito mais simples ssh-keyscan host | ssh-keygen -l -f /dev/stdin não funciona)

Comentários

  • Talvez ssh-keygen -l -f - <(ssh-keyscan host) sim?
  • OpenSSH > = 7.2 ssh-keyscan é capaz de ler stdin: ssh-keyscan host | ssh-keygen -lf -
  • Basta fazer: ssh-keygen -l -f <(ssh-keyscan host)
  • ssh-keygen -l -f - funciona como esperado no ssh-keygen 7.2 e superior. Ele produz algumas linhas de comentário para STDERR que podem ser filtradas, conforme mencionado na resposta er por Anthony Geoghegan ou ssh-keyscan host 2>/dev/null | ssh-keygen -l -f -
  • Novas versões do openssh (7.2 pelo menos) exibirão a impressão digital como SHA256 (ex: 2048 SHA256:gYz11pP/v/SMzUD58jrZ+m1EFC1pvyMxvIrg4PYlvDY) Se você quiser no formato antigo, forneça -E md5 e você ‘ verá algo como 2048 MD5:0b:f5:49:d2:69:a5:49:2c:d9:45:75:87:4d:a0:7d:33.

Resposta

Recentemente tive que fazer isso sozinho, então pensei que adicionaria uma resposta que mostrasse como isso pode ser feito (com versões do OpenSSH 7.2 ou mais recente ) em uma linha usando a substituição do processo:

ssh-keygen -lf <(ssh-keyscan hostname 2>/dev/null) 

O texto a seguir explica como esses comandos funcionam e destaca algumas das diferenças de comportamento entre as versões mais antigas e mais recentes dos utilitários OpenSSH.

Busque as chaves públicas do host

O comando ssh-keyscan foi desenvolvido para que os usuários possam obter chaves de host públicas sem a necessidade de autenticação no servidor SSH. De sua página de manual:

ssh-keyscan é um utilitário para reunir as chaves de host ssh públicas de uma série de hospedeiros. Ele foi projetado para ajudar na construção e verificação de ssh_known_hosts arquivos.

Tipo de chave

O tipo de chave a ser buscada é especificado usando a opção -t.

  • rsa1 (obsoleto Protocolo SSH versão 1)
  • rsa
  • dsa
  • ecdsa (versões recentes do OpenSSH)
  • ed25519 (versões recentes do OpenSSH)

Em versões OpenSSH modernas, os tipos de chave padrão a serem buscados são rsa (desde a versão 5.1), ecdsa (desde a versão 6.0) e ed25519 (desde a versão 6.7).

Com versões mais antigas de ssh-keyscan (antes do OpenSSH versão 5.1), o tipo de chave padrão era o desatualizado rsa1 (Protocolo SSH 1), portanto os tipos de chave precisam ser especificados explicitamente:

ssh-keyscan -t rsa,dsa hostname 

Obter hashes de impressão digital de chaves Base64

ssh-keyscan imprime a chave do host do servidor SSH em Formato codificado em Base64 . Para converter isso em um hash de impressão digital, o utilitário ssh-keygen pode ser usado com sua opção -l para imprimir a impressão digital da chave pública especificada.

Se estiver usando Bash, Zsh (ou o shell Korn), substituição de processo pode ser usada para um prático one-liner:

ssh-keygen -lf <(ssh-keyscan hostname 2>/dev/null) 

Observação : com versões do OpenSSH anteriores a 7.2, as funções usadas por ssh-keygen para ler arquivos, não lidavam muito bem com pipes nomeados (FIFOs), então esse método não funcionaria, exigindo, portanto, o uso de arquivos temporários.

Algoritmos de hash

Versões recentes de ssh-keygen print SHA256 hashes de impressão digital das chaves. Para obter MD5 hashes das impressões digitais da chave do servidor (o comportamento antigo), o -E pode ser usada para especificar o algoritmo de hash:

ssh-keygen -E md5 -lf <(ssh-keyscan hostname 2>/dev/null) 

Usando um pipeline

Se estiver usando um shell POSIX (como dash) que não apresenta substituição de processo, as outras soluções que usam arquivos temporários funcionarão. No entanto, com as versões mais recentes do OpenSSH (desde 7.2), um pipeline simples pode ser usado, pois ssh-keygen aceitará - como um nome de arquivo para o fluxo de entrada padrão, permitindo um comando de pipeline de uma linha.

ssh-keyscan hostname 2>/dev/null | ssh-keygen -E md5 -lf - 

Comentários

  • Bom e completo resposta, isso é certamente melhor do que ter um arquivo temporário!Posso sugerir que você forneça um TL; DR no início com a versão de substituição do processo, para fazer com que as pessoas impacientes o encontrem mais rápido? 🙂
  • Não parece funcionar no Ubuntu 14.04 LTS; Recebo um erro ” / dev / fd / 63 não é um arquivo de chave pública “. O subprocesso funciona.
  • @melleb Eu encontrei a mesma coisa em um sistema 12.04 ao qual tenho acesso. Suspeito que ssh-keygen de versões mais antigas do OpenSSH têm um problema ao ler o FIFO / pipe nomeado. Eu ‘ examinarei isso (e atualizarei minha resposta) quando tiver algum tempo livre.
  • @melleb Depois de passar meu tempo baixando vários lançamentos de código-fonte e inserindo as instruções printf de depuração na função do_fingerprint(), descobri que, com versões do OpenSSH anteriores a 7.2, as funções usadas por ssh-keygen para ler arquivos, não lida muito bem com pipes nomeados (FIFOs), então o método de substituição de processo não funcionaria.
  • Isso funciona, mas se for usado para verificar uma impressão digital, os usuários devem estar cientes de que há ‘ uma condição de corrida: a impressão digital que você está verificando com este comando não é ‘ necessariamente a da chave que você buscar, a menos que você despeje a chave antes de chamar ssh-keygen nela.

Resposta

nmap fornece essa capacidade usando o script ssh-hostkey.

Para retornar a impressão digital hexadecimal da chave:

$ nmap [SERVER] --script ssh-hostkey 

Para retornar o conteúdo da chave:

$ nmap [SERVER] --script ssh-hostkey --script-args ssh_hostkey=full 

Para retornar o balão visual da chave

$ nmap [SERVER] --script ssh-hostkey --script-args ssh_hostkey="visual bubble" 

Para retornar todos os itens acima:

$ nmap [SERVER] --script ssh-hostkey --script-args ssh_hostkey=all 

Fonte: nmap docs

Comentários

  • Esses exemplos presumem que o SSH está sempre em execução na porta 22? E se o ssh escuta em uma porta não padrão?
  • @MartinVegter (parafraseando Guarin42, que não poderia ‘ t comment 🙂 nmap tem a opção -p que pode especificar uma porta, por exemplo, -p 22000. ‘ s também é possível usar a opção -vv para aumentar o detalhamento (quantidade de informações fornecidas)

Resposta

filezilla exibe chaves com hash com md5 em hexadecimal .

para encontrar isso em sua ubuntu linux máquina, use este comando:

ssh-keygen -l -E md5 -f <(ssh-keyscan localhost 2>/dev/null) 

observação: substitua “localhost” pelo ip da máquina que deseja verificar.

Comentários

  • Funcionou para mim no Ubuntu 18, mas observe que você obterá resultados de diferença para localhost 127.0.0.1 ou domain.tld. Verifique a impressão digital do URL que o preocupa ~!

Resposta

Aqui está um script de shell (principalmente Bourne shell, mas usando a local palavra-chave, que está disponível na maioria das /bin/sh) modernas que escrevi para fazer isso. Use-a como ssh-hostkey hostname. Ele mostrará as impressões digitais no formato sha256 e md5 para todas as chaves do host para o nome de host ou endereço IP fornecido. Você também pode especificar manualmente “md5 “ou” sha256 “como o segundo argumento para mostrar apenas aquele formato específico.

Ele usa um arquivo temporário em vez de piping para torná-lo compatível com pacotes OpenSSH mais antigos (conforme descrito em outras respostas). O arquivo temporário usa /dev/shm (memória compartilhada) se disponível.

#!/bin/sh usage () { printf "%s\n" "Usage: ssh-hostkey HOSTNAME [FPRINTHASH]" } ssh_hostkey () { local host="$1" local fprinthash="$2" local tmp= case "$host" in -h|--help|"") usage >&2 return 1 ;; esac case "$fprinthash" in md5|sha256|"") true;; *) usage >&2 printf "%s\n" "Fingerprint hash may be "md5" or "sha256"" >&2 return 2 ;; esac if test -d /dev/shm then tmp="$(mktemp -d -p /dev/shm)" else tmp="$(mktemp -d)" fi trap "trap - INT TERM EXIT; rm -rf "$tmp"" INT TERM EXIT ssh-keyscan "$host" > "$tmp/f" 2> /dev/null case "$fprinthash" in sha256|"") ssh-keygen -l -f "$tmp/f" 2> /dev/null;; esac case "$fprinthash" in md5|"") ssh-keygen -l -E md5 -f "$tmp/f" 2> /dev/null;; esac trap - INT TERM EXIT rm -rf "$tmp" > /dev/null 2>&1 } ssh_hostkey "$@" 

Comentários

  • Esta é uma boa demonstração de como agrupar ferramentas de nível inferior com opções de linha de comando. Inclui um bônus de como usar memória compartilhada /dev/shm que eu nunca soube que era tão conveniente de fazer. Obrigado por compartilhar !

Resposta

Para meu próprio servidor, eu uso este:

ssh-keygen -l -E md5 -f <(cat /etc/ssh/ssh_host_*_key.pub) ssh-keygen -l -E sha256 -f <(cat /etc/ssh/ssh_host_*_key.pub) 

Resposta

A resposta simples quando você já tem acesso para o servidor é:

ssh-keygen -lf /etc/ssh/ssh_host_rsa_key.pub 

Agora, você pode não estar usando a chave RSA: se ao conectar, ssh diz a você

ECDSA a impressão digital da chave é SHA256: XXXXX

Você precisa usar /etc/ssh/ssh_host_ecdsa_key.pub em seu lugar. (observe _ecdsa_ ). Um comando mais universal que lista todas as chaves pode, portanto, ser construído ( fonte ):

for f in /etc/ssh/ssh_host_*_key.pub; do ssh-keygen -lf "$f"; done 

Você pode escrever a lista ao configurar o servidor, para referência futura.Outra opção é armazená-los nos registros DNS


da página de manual ssh-keygen (1):

-l Mostrar impressão digital do arquivo de chave pública especificado. Para chaves RSA e DSA, o ssh-keygen tenta encontrar o arquivo de chave pública correspondente e imprime sua impressão digital. Se combinada com -v, uma representação artística ASCII visual da chave é fornecida com a impressão digital.

-f filename Especifica o nome do arquivo da chave.

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *