Posso adicionar automaticamente um novo host ao known_hosts?

249

Aqui está minha situação: estou configurando um equipamento de teste que, a partir de um cliente central, inicia várias instâncias de máquina virtual e executa comandos nelas via ssh. As máquinas virtuais terão nomes de host e endereços IP anteriormente não utilizados, portanto não estarão no ~/.ssh/known_hostsarquivo no cliente central.

O problema que estou tendo é que o primeiro sshcomando executado em uma nova instância virtual sempre aparece com um prompt interativo:

The authenticity of host '[hostname] ([IP address])' can't be established.
RSA key fingerprint is [key fingerprint].
Are you sure you want to continue connecting (yes/no)?

Existe uma maneira de contornar isso e fazer com que o novo host já seja conhecido pela máquina cliente, talvez usando uma chave pública que já esteja inserida na imagem da máquina virtual? Eu realmente gostaria de evitar ter que usar o Expect ou o que quer que seja para responder ao prompt interativo, se puder.

gareth_bowles
fonte
5
Para um ambiente de teste independente e fisicamente seguro, a aceitação automatizada de chaves pode funcionar perfeitamente. Mas a aceitação automática de chaves públicas em um ambiente de produção ou em uma rede não confiável (como a Internet) ignora completamente qualquer proteção contra ataques intermediários que o SSH poderia oferecer. A única maneira válida de garantir a segurança contra ataques MITM é verificar a chave pública do host por meio de algum canal confiável fora da banda. Não há maneira segura de automatizá-lo sem configurar uma infraestrutura de assinatura de chave moderadamente complicada.
Eil

Respostas:

142

Defina a StrictHostKeyCheckingopção como no, no arquivo de configuração ou via -o:

ssh -o StrictHostKeyChecking=no [email protected]

Ignacio Vazquez-Abrams
fonte
62
Isso deixa você aberto ao homem nos ataques intermediários, provavelmente não é uma boa idéia.
JasperWallace 23/09
9
@JasperWallace, embora isso geralmente seja um bom conselho, o caso de uso específico (implantar VMs de teste e enviar comandos a elas) deve ser suficientemente seguro.
Massimo
8
Isto dá uma Warning: Permanently added 'hostname,1.2.3.4' (RSA) to the list of known hosts.Para evitar o aviso, e para evitar a entrada a ser adicionado a qualquer arquivo known_hosts, eu faço:ssh -o StrictHostKeyChecking=no -o LogLevel=ERROR -o UserKnownHostsFile=/dev/null [email protected]
Peter V. Mørch
11
O voto negativo, pois isso não responde à pergunta e se abre para sérias vulnerabilidades de segurança.
Marcv81
12
@Mnebuerquo: Se você estivesse preocupado com a segurança, não teria nada a ver com essa pergunta. Você teria a chave do host correta à sua frente, reunida no console do sistema ao qual deseja se conectar e a verificaria manualmente na primeira conexão. Você certamente não faria nada "automaticamente".
Ignacio Vazquez-Abrams
230

Na IMO, a melhor maneira de fazer isso é o seguinte:

ssh-keygen -R [hostname]
ssh-keygen -R [ip_address]
ssh-keygen -R [hostname],[ip_address]
ssh-keyscan -H [hostname],[ip_address] >> ~/.ssh/known_hosts
ssh-keyscan -H [ip_address] >> ~/.ssh/known_hosts
ssh-keyscan -H [hostname] >> ~/.ssh/known_hosts

Isso garantirá que não haja entradas duplicadas, que você esteja coberto tanto pelo nome do host quanto pelo endereço IP, e também fará o hash da saída, uma medida extra de segurança.

yardena
fonte
4
Por que você precisa de todos os 3 ssh-keyscan's? Você não consegue conviver apenas com o primeiro, uma vez que funciona tanto para o nome do host quanto para o ip?
Robert
6
Você pode ter certeza de que a máquina que responde à solicitação do ssh-keyscan é realmente aquela com quem deseja conversar? Caso contrário, você se abriu para um homem no meio do ataque.
JasperWallace 23/09
2
@JasperWallace Sim, para isso você precisa de pelo menos a impressão digital ou, melhor ainda, a chave pública; nesse caso, você pode adicioná-la diretamente a known_hosts, tornando essa questão discutível. Se você só tem a impressão digital, você terá que escrever uma etapa extra que verifica a chave pública baixado com sua impressão digital ...
1
As chamadas para ssh-keyscanestavam falhando para mim porque meu host de destino não suporta o tipo de chave padrão da versão 1. A adição -t rsa,dsaao comando corrigiu isso.
phasetwenty
5
Esta é provavelmente uma má ideia. Você está se abrindo para um ataque man-in-the-middle atualizando essas chaves. Para evitar entradas duplicadas, verifique o status de retorno ssh-keygen -F [address]. medium.com/@wblankenship/…
retrohacker 29/09
93

Para os preguiçosos:

ssh-keyscan -H <host> >> ~/.ssh/known_hosts

-H faz hash no nome do host / endereço IP

fivef
fonte
2
"ssh-keyscan -H <host> >> ~ / .ssh / known_hosts" produz uma entrada mais parecida com o que o ssh faz com a interação do usuário. (A-H hashes o nome do host remoto.)
Sarah Messer
3
Vulnerável a ataques MITM. Você não está verificando a impressão digital chave.
Mnebuerquo
8
@ Macnuer Você diz o que fazer, mas não como, o que seria útil.
Raio
4
@jameshfisher Sim, é vulnerável a ataques MITM, mas você já comparou a impressão digital RSA, que foi mostrada com a atual do servidor, quando você fazia isso manualmente? Não? Portanto, esta resposta é a maneira de fazer isso por você. Em caso afirmativo, você não deve usar esta resposta e fazê-lo manualmente ou implementar outras medidas de segurança ...
fivef
2
@Mnebuerquo, ficaria muito feliz se você também nos informar sobre uma maneira melhor de lidar com isso, quando precisarmos clonar um repo usando scripts em lote não atendidos e queremos ignorar esse prompt. Por favor, ilumine uma solução real, se você acha que essa não é a correta!
Waqas Shah
42

Como mencionado, o uso da digitalização de teclas seria a maneira correta e discreta de fazer isso.

ssh-keyscan -t rsa,dsa HOST 2>&1 | sort -u - ~/.ssh/known_hosts > ~/.ssh/tmp_hosts
mv ~/.ssh/tmp_hosts ~/.ssh/known_hosts

O acima será o truque para adicionar um host, SOMENTE se ele ainda não tiver sido adicionado. Também não é seguro para simultaneidade; você não deve executar o snippet na mesma máquina de origem mais de uma vez ao mesmo tempo, pois o arquivo tmp_hosts pode ser derrotado, resultando no inchaço do arquivo known_hosts ...

ysawej
fonte
Existe uma maneira de verificar se a chave está em known_hosts antes ssh-keyscan ? O motivo é que isso requer algum tempo e conexão de rede adicional.
Utapyngo 23/05
1
A versão original do pôster deste arquivo tinha cat ~/.ssh/tmp_hosts > ~/.ssh/known_hosts, mas uma edição subsequente foi alterada para >>. Usar >>é um erro. Ele anula o objetivo da exclusividade na primeira linha e faz com que ele despeje novas entradas known_hoststoda vez que é executado. (Just postou uma edição para mudá-lo de volta.)
paulmelnikow
1
Isso está sujeito aos mesmos ataques MITM que os outros.
Mnebuerquo
O @utapyngo ssh-keygen -F fornecerá a impressão digital atual. Se voltar em branco com o código de retorno 1, você não o terá. Se ele imprime algo e o código de retorno é 0, então já está presente.
Ricos L
1
Se você se preocupa muito com o MITM, implante os registros DNSSEC e SSHFP ou use algum outro meio seguro de distribuir as chaves, e essa solução kludge será irrelevante.
Zart 28/11
19

Você pode usar o ssh-keyscancomando para pegar a chave pública e anexá-la ao seu known_hostsarquivo.

Alex
fonte
3
Verifique a impressão digital para garantir que seja a chave correta. Caso contrário, você se abrirá para ataques MITM.
Mnebuerquo
3
@Mnebuerquo Fair point no contexto geral, mas por que alguém tentaria reunir chaves programaticamente se já sabia qual era a chave correta?
Brian Cline
Esta não é a maneira de fazê-lo. MITM.
Jameshfisher #
8

É assim que você pode incorporar o ssh-keyscan no seu jogo:

---
# ansible playbook that adds ssh fingerprints to known_hosts
- hosts: all
  connection: local
  gather_facts: no
  tasks:
  - command: /usr/bin/ssh-keyscan -T 10 {{ ansible_host }}
    register: keyscan
  - lineinfile: name=~/.ssh/known_hosts create=yes line={{ item }}
    with_items: '{{ keyscan.stdout_lines }}'
Zart
fonte
1
Você está carregando um arquivo conhecido_hosts válidos ou está executando o ssh-keyscan e despejando a saída em conhecidos_hosts sem verificar as impressões digitais?
Mnebuerquo
1
Isso é simplesmente descarregar a saída de um keycan, sim. Portanto, na verdade, é o mesmo que StrictHostKeyChecking = no, apenas com o silêncio conhecido_hosts atualizando sem mexer nas opções ssh. Esta solução também não funciona bem devido a várias linhas ssh-KeyScan retornando que faz com que esta tarefa sempre ser sinalizado como 'mudou'
Zart
Esta não é a maneira de fazê-lo. MITM.
Jameshfisher #
3
@jameshfisher Eu ficaria muito feliz se você também nos informar uma maneira melhor de lidar com isso, quando precisarmos clonar um repositório usando scripts em lote não atendidos e queremos ignorar esse prompt. Por favor, ilumine uma solução real se você acha que essa não é a correta! Por favor, deixe-nos saber "como" fazê-lo, se você acha que não é o caminho certo para fazê-lo!
Waqas Shah
É um método perfeitamente válido para adicionar valores a known_hosts, mas sim, é suscetível ao MITM. No entanto, para uso interno, tudo bem.
Cameron Lowell Palmer
7

essa seria uma solução completa, aceitando a chave do host pela primeira vez apenas

#!/usr/bin/env ansible-playbook
---
- name: accept ssh fingerprint automatically for the first time
  hosts: all
  connection: local
  gather_facts: False

  tasks:
    - name: "check if known_hosts contains server's fingerprint"
      command: ssh-keygen -F {{ inventory_hostname }}
      register: keygen
      failed_when: keygen.stderr != ''
      changed_when: False

    - name: fetch remote ssh key
      command: ssh-keyscan -T5 {{ inventory_hostname }}
      register: keyscan
      failed_when: keyscan.rc != 0 or keyscan.stdout == ''
      changed_when: False
      when: keygen.rc == 1

    - name: add ssh-key to local known_hosts
      lineinfile:
        name: ~/.ssh/known_hosts
        create: yes
        line: "{{ item }}"
      when: keygen.rc == 1
      with_items: '{{ keyscan.stdout_lines|default([]) }}'
mazac
fonte
1
Esta não é a maneira de fazê-lo. MITM.
Jameshfisher #
6

Eu tive um problema semelhante e descobri que algumas das respostas fornecidas me levaram apenas a uma solução automatizada. A seguir, o que acabei usando, espero que ajude:

ssh -o "StrictHostKeyChecking no" -o PasswordAuthentication=no 10.x.x.x

Ele adiciona a chave known_hostse não solicita a senha.

VenomFangs
fonte
2
Vulnerável a ataques MITM. Você não está verificando a impressão digital.
Mnebuerquo
6
Ninguém verifica a impressão digital.
Brendan Byrd
Esta não é a maneira de fazê-lo. MITM.
Jameshfisher #
5

Então, eu estava procurando uma maneira mundana de ignorar a interação manual host desconhecida de clonar um repositório git, como mostrado abaixo:

brad@computer:~$ git clone [email protected]:viperks/viperks-api.git
Cloning into 'viperks-api'...
The authenticity of host 'bitbucket.org (104.192.143.3)' can't be established.
RSA key fingerprint is 97:8c:1b:f2:6f:14:6b:5c:3b:ec:aa:46:46:74:7c:40.
Are you sure you want to continue connecting (yes/no)?

Observe a impressão digital da chave RSA ...

Então, isso é uma coisa do SSH, isso funcionará para git sobre SSH e apenas coisas relacionadas ao SSH em geral ...

brad@computer:~$ nmap bitbucket.org --script ssh-hostkey

Starting Nmap 7.01 ( https://nmap.org ) at 2016-10-05 10:21 EDT
Nmap scan report for bitbucket.org (104.192.143.3)
Host is up (0.032s latency).
Other addresses for bitbucket.org (not scanned): 104.192.143.2 104.192.143.1 2401:1d80:1010::150
Not shown: 997 filtered ports
PORT    STATE SERVICE
22/tcp  open  ssh
| ssh-hostkey:
|   1024 35:ee:d7:b8:ef:d7:79:e2:c6:43:9e:ab:40:6f:50:74 (DSA)
|_  2048 97:8c:1b:f2:6f:14:6b:5c:3b:ec:aa:46:46:74:7c:40 (RSA)
80/tcp  open  http
443/tcp open  https

Nmap done: 1 IP address (1 host up) scanned in 42.42 seconds

Primeiro, instale o nmap no seu driver diário. O nmap é altamente útil para certas coisas, como detectar portas abertas e isso - verificar manualmente as impressões digitais SSH. Mas, voltando ao que estamos fazendo.

Boa. Ou estou comprometida nos vários lugares e máquinas em que verifiquei - ou a explicação mais plausível de tudo o que está acontecendo é o que está acontecendo.

Essa 'impressão digital' é apenas uma string reduzida com um algoritmo unidirecional para nossa conveniência humana, com o risco de mais de uma string ser resolvida na mesma impressão digital. Acontece, eles são chamados de colisões.

Independentemente disso, de volta à string original que podemos ver no contexto abaixo.

brad@computer:~$ ssh-keyscan bitbucket.org
# bitbucket.org SSH-2.0-conker_1.0.257-ce87fba app-128
no hostkey alg
# bitbucket.org SSH-2.0-conker_1.0.257-ce87fba app-129
bitbucket.org ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAubiN81eDcafrgMeLzaFPsw2kNvEcqTKl/VqLat/MaB33pZy0y3rJZtnqwR2qOOvbwKZYKiEO1O6VqNEBxKvJJelCq0dTXWT5pbO2gDXC6h6QDXCaHo6pOHGPUy+YBaGQRGuSusMEASYiWunYN0vCAI8QaXnWMXNMdFP3jHAJH0eDsoiGnLPBlBp4TNm6rYI74nMzgz3B9IikW4WVK+dc8KZJZWYjAuORU3jc1c/NPskD2ASinf8v3xnfXeukU0sJ5N6m5E8VLjObPEO+mN2t/FZTMZLiFqPWc/ALSqnMnnhwrNi2rbfg/rd/IpL8Le3pSBne8+seeFVBoGqzHM9yXw==
# bitbucket.org SSH-2.0-conker_1.0.257-ce87fba app-123
no hostkey alg

Portanto, com antecedência, temos uma maneira de solicitar uma forma de identificação ao host original.

Nesse ponto, estamos manualmente tão vulneráveis ​​quanto automaticamente - as cadeias correspondem, temos os dados de base que criam a impressão digital e poderíamos solicitar esses dados de base (evitando colisões) no futuro.

Agora, para usar essa string de uma maneira que evite perguntar sobre a autenticidade dos hosts ...

O arquivo known_hosts nesse caso não usa entradas de texto sem formatação. Você saberá entradas de hash quando as vir; elas se parecem com hashes com caracteres aleatórios em vez de xyz.com ou 123.45.67.89.

brad@computer:~$ ssh-keyscan -t rsa -H bitbucket.org
# bitbucket.org SSH-2.0-conker_1.0.257-ce87fba app-128
|1|yr6p7i8doyLhDtrrnWDk7m9QVXk=|LuKNg9gypeDhfRo/AvLTAlxnyQw= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAubiN81eDcafrgMeLzaFPsw2kNvEcqTKl/VqLat/MaB33pZy0y3rJZtnqwR2qOOvbwKZYKiEO1O6VqNEBxKvJJelCq0dTXWT5pbO2gDXC6h6QDXCaHo6pOHGPUy+YBaGQRGuSusMEASYiWunYN0vCAI8QaXnWMXNMdFP3jHAJH0eDsoiGnLPBlBp4TNm6rYI74nMzgz3B9IikW4WVK+dc8KZJZWYjAuORU3jc1c/NPskD2ASinf8v3xnfXeukU0sJ5N6m5E8VLjObPEO+mN2t/FZTMZLiFqPWc/ALSqnMnnhwrNi2rbfg/rd/IpL8Le3pSBne8+seeFVBoGqzHM9yXw==

A primeira linha de comentário aparece irritantemente - mas você pode se livrar dela com um redirecionamento simples através da convenção ">" ou ">>".

Como eu fiz o meu melhor para obter dados não contaminados para serem usados ​​para identificar um "host" e confiança, adicionarei essa identificação ao meu arquivo known_hosts no meu diretório ~ / .ssh. Como agora será identificado como um host conhecido, não receberei o prompt mencionado acima quando você era jovem.

Obrigado por ficar comigo, aqui está. Estou adicionando a chave RSA do bitbucket para que eu possa interagir com meus repositórios git de uma maneira não interativa como parte de um fluxo de trabalho de IC, mas faça o que quiser.

#!/bin/bash
cp ~/.ssh/known_hosts ~/.ssh/known_hosts.old && echo "|1|yr6p7i8doyLhDtrrnWDk7m9QVXk=|LuKNg9gypeDhfRo/AvLTAlxnyQw= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAubiN81eDcafrgMeLzaFPsw2kNvEcqTKl/VqLat/MaB33pZy0y3rJZtnqwR2qOOvbwKZYKiEO1O6VqNEBxKvJJelCq0dTXWT5pbO2gDXC6h6QDXCaHo6pOHGPUy+YBaGQRGuSusMEASYiWunYN0vCAI8QaXnWMXNMdFP3jHAJH0eDsoiGnLPBlBp4TNm6rYI74nMzgz3B9IikW4WVK+dc8KZJZWYjAuORU3jc1c/NPskD2ASinf8v3xnfXeukU0sJ5N6m5E8VLjObPEO+mN2t/FZTMZLiFqPWc/ALSqnMnnhwrNi2rbfg/rd/IpL8Le3pSBne8+seeFVBoGqzHM9yXw==" >> ~/.ssh/known_hosts

Então é assim que você permanece virgem por hoje. Você pode fazer o mesmo com o github seguindo instruções semelhantes no seu próprio tempo.

Vi tantas mensagens de estouro de pilha dizendo para adicionar programaticamente a chave às cegas sem nenhum tipo de verificação. Quanto mais você checa a chave de máquinas diferentes em redes diferentes, mais confiança você tem que o host é o que diz ser - e isso é o melhor que você pode esperar dessa camada de segurança.

ERRADO ssh -oStrictHostKeyChecking = nenhum nome de host [comando]

ERRADO ssh-keyscan -t rsa -H nome do host >> ~ / .ssh / known_hosts

Não faça nenhuma das coisas acima, por favor. Você tem a oportunidade de aumentar suas chances de evitar alguém espionando suas transferências de dados através de um homem no meio do ataque - aproveite essa oportunidade. A diferença é literalmente verificar se a chave RSA que você possui é a do servidor de boa-fé e agora você sabe como obter essas informações para compará-las, para que possa confiar na conexão. Lembre-se de que mais comparações de diferentes computadores e redes geralmente aumentam sua capacidade de confiar na conexão.

BradChesney79
fonte
Eu acho que essa é a melhor solução para esse problema. No entanto, tenha muito cuidado ao usar o Nmap em algo como o Amazon EC2, recebi um aviso sobre a verificação de portas que o Nmap faz! Preencha o formulário antes de fazer o portscanning!
Waqas Shah
...bem, sim. Não sei por que você faria a digitalização de porta do EC2. Se você estiver conectado à sua conta, poderá obter as chaves das máquinas reais. Isso é mais para máquinas sobre as quais você não tem controle. Suponho que você teria uma máquina local não sujeita às restrições de varredura de portas da AWS a serem usadas. Mas, se você estiver nessa situação de ponta em que deve executar o nmap com a AWS, suponho que esse aviso seja útil.
precisa saber é o seguinte
Usar o nmap para ler a chave do host SSH da sua estação de trabalho e confiar nesse valor não é diferente de conectar-se via SSH com o StructHostKeyChecking desativado. É tão vulnerável a um ataque do tipo "homem do meio".
Micah R Ledbetter
... @ MicahRLedbetter, por isso sugeri que "mais comparações de diferentes computadores e redes geralmente aumentam sua capacidade de confiar na conexão". Mas, esse é o meu ponto. Se você apenas verificar seu host de destino a partir de um conjunto de condições ambientais, como saberia alguma discrepância? Você teve alguma sugestão melhor?
precisa saber é o seguinte
1
Isso é teatro de segurança. Fazendo algo complicado para criar a aparência de maior segurança. Não importa quantos métodos diferentes você use para solicitar sua chave ao host. Como perguntar à mesma pessoa várias vezes se você pode confiar nela (talvez você ligue, envie um email, texto e correio tradicional). Eles sempre dizem que sim, mas se você está perguntando à pessoa errada, isso não importa.
22418
5

Eu faço um script de uma linha, um pouco longo, mas útil para executar esta tarefa em hosts com vários IPs, usando digebash

(host=github.com; ssh-keyscan -H $host; for ip in $(dig @8.8.8.8 github.com +short); do ssh-keyscan -H $host,$ip; ssh-keyscan -H $ip; done) 2> /dev/null >> .ssh/known_hosts
Felipe Alcacibar
fonte
5

A seguir, evite entradas duplicadas em ~ / .ssh / known_hosts:

if ! grep "$(ssh-keyscan github.com 2>/dev/null)" ~/.ssh/known_hosts > /dev/null; then
    ssh-keyscan github.com >> ~/.ssh/known_hosts
fi
Amadu Bah
fonte
1
Esta não é a maneira de fazê-lo. MITM.
Jameshfisher #
Eu gosto mais desta resposta. Para a configuração inicial de scripts de um VPS aleatório sem importância para ninguém além de mim, o risco do MITM é muito pequeno. Infinitesimal quibble ... primeira linha precisa sermkdir -p ~/.ssh/known_hosts;
Martin Bramwell
5

Como você está construindo essas máquinas? você pode executar um script de atualização de DNS? você pode participar de um domínio IPA?

O FreeIPA faz isso automaticamente, mas basicamente tudo o que você precisa é de registros de DNS SSHFP e DNSSEC na sua zona (o freeipa fornece como opções configuráveis ​​(dnssec desativado por padrão)).

Você pode obter os registros SSHFP existentes do seu host executando.

ssh-keygen -r jersey.jacobdevans.com

jersey.jacobdevans.com EM SSHFP 1 1 4d8589de6b1a48e148d8fc9fbb967f1b29f53ebc jersey.jacobdevans.com EM SSHFP 1 2 6503272a11ba6d7fec2518c02dfed88f3d455ac7786ee5dbd72df63307209d55 jersey.jacobdevans.com EM SSHFP 3 1 5a7a1e8ab8f25b86b63c377b303659289b895736> jersey.jacobdevans.com EM SSHFP 3 2 1f50f790117dfedd329dbcf622a7d47551e12ff5913902c66a7da28e47de4f4b

depois de publicado, você adicionaria VerifyHostKeyDNS yesao seu ssh_config ou ~ / .ssh / config

Se / quando o google decidir ativar o DNSSEC, você poderá fazer o ssh sem um prompt de chave de host.

ssh jersey.jacobdevans.com

MAS meu domínio ainda não está assinado, então por enquanto você veria ....

debug1: Chave do host do servidor: ecdsa-sha2-nistp256 SHA256: H1D3kBF9 / t0ynbz2IqfUdVHhL / WROQLGan2ijkfeT0s

debug1: encontrou 4 impressões digitais inseguras no DNS

debug1: impressão digital da chave do host correspondente

encontrado no DNS A autenticidade do host 'jersey.jacobdevans.com (2605: 6400: 10: 434 :: 10)' não pode ser estabelecida. A impressão digital da chave ECDSA é SHA256: H1D3kBF9 / t0ynbz2IqfUdVHhL / WROQLGan2ijkfeT0s. Impressão digital da chave do host correspondente encontrada no DNS. Tem certeza de que deseja continuar se conectando (sim / não)? não

Jacob Evans
fonte
4

Para fazer isso corretamente, o que você realmente deseja fazer é coletar as chaves públicas do host das VMs enquanto você as cria e soltá-las em um arquivo no known_hostsformato. Em seguida, você pode usar o -o GlobalKnownHostsFile=..., apontando para esse arquivo, para garantir que você esteja se conectando ao host em que acredita estar conectado. Entretanto, como você faz isso depende de como você está configurando as máquinas virtuais, mas lê-lo no sistema de arquivos virtual, se possível, ou até mesmo fazer com que o host imprima o conteúdo /etc/ssh/ssh_host_rsa_key.pubdurante a configuração pode ajudar.

Dito isto, isso pode não valer a pena, dependendo do tipo de ambiente em que você está trabalhando e de quem são seus adversários esperados. Fazer um simples "armazenamento na primeira conexão" (por meio de uma varredura ou simplesmente durante a primeira conexão "real"), conforme descrito em várias outras respostas acima, pode ser consideravelmente mais fácil e ainda fornecer um pouco de segurança. No entanto, se você fizer isso, sugiro fortemente que você altere o arquivo hosts conhecidos do usuário ( -o UserKnownHostsFile=...) para um arquivo específico para esta instalação de teste específica; isso evitará poluir seu arquivo de hosts conhecidos pessoais com informações de teste e facilitará a limpeza das chaves públicas agora inúteis quando você excluir suas VMs.

Curt J. Sampson
fonte
4

Esse todo

  • verificação de chave ssh
  • ssh-copy-id
  • Aviso de chave ECSDA

os negócios continuaram me irritando, então optei por

Um script para governar todos eles

Esta é uma variante do script em https://askubuntu.com/a/949731/129227 com a resposta de Amadu Bah https://serverfault.com/a/858957/162693 em um loop.

chamada de exemplo

./schcheck somedomain site1 site2 site3

O script fará um loop nos sites de nomes e modificará o arquivo .ssh / config e .ssh / known_hosts e executará ssh-copy-id mediante solicitação - para o último recurso, deixe as chamadas de teste do ssh falharem, por exemplo, pressionando Enter 3 vezes em a solicitação de senha.

script sshcheck

#!/bin/bash
# WF 2017-08-25
# check ssh access to bitplan servers

#ansi colors
#http://www.csc.uvic.ca/~sae/seng265/fall04/tips/s265s047-tips/bash-using-colors.html
blue='\033[0;34m'  
red='\033[0;31m'  
green='\033[0;32m' # '\e[1;32m' is too bright for white bg.
endColor='\033[0m'

#
# a colored message 
#   params:
#     1: l_color - the color of the message
#     2: l_msg - the message to display
#
color_msg() {
  local l_color="$1"
  local l_msg="$2"
  echo -e "${l_color}$l_msg${endColor}"
}

#
# error
#
#   show an error message and exit
#
#   params:
#     1: l_msg - the message to display
error() {
  local l_msg="$1"
  # use ansi red for error
  color_msg $red "Error: $l_msg" 1>&2
  exit 1
}

#
# show the usage
#
usage() {
  echo "usage: $0 domain sites"
  exit 1 
}

#
# check known_hosts entry for server
#
checkknown() {
  local l_server="$1"
  #echo $l_server
  local l_sid="$(ssh-keyscan $l_server 2>/dev/null)" 
  #echo $l_sid
  if (! grep "$l_sid" $sknown) > /dev/null 
  then
    color_msg $blue "adding $l_server to $sknown"
    ssh-keyscan $l_server >> $sknown 2>&1
  fi
}

#
# check the given server
#
checkserver() {
  local l_server="$1"
  grep $l_server $sconfig > /dev/null
  if [ $? -eq 1 ]
  then
    color_msg $blue "adding $l_server to $sconfig"
    today=$(date "+%Y-%m-%d")
    echo "# added $today by $0"  >> $sconfig
    echo "Host $l_server" >> $sconfig
    echo "   StrictHostKeyChecking no" >> $sconfig
    echo "   userKnownHostsFile=/dev/null" >> $sconfig
    echo "" >> $sconfig
    checkknown $l_server
  else
    color_msg $green "$l_server found in $sconfig"
  fi
  ssh -q $l_server id > /dev/null
  if [ $? -eq 0 ]
  then
    color_msg $green "$l_server accessible via ssh"
  else
    color_msg $red "ssh to $l_server failed" 
    color_msg $blue "shall I ssh-copy-id credentials to $l_server?"
    read answer
    case $answer in
      y|yes) ssh-copy-id $l_server
    esac
  fi
}

#
# check all servers
#
checkservers() {
me=$(hostname -f)
for server in $(echo $* | sort)
do
  os=`uname`
  case $os in
   # Mac OS X
   Darwin*)
     pingoption=" -t1";;
    *) ;;
  esac

  pingresult=$(ping $pingoption -i0.2 -c1 $server)
  echo $pingresult | grep 100 > /dev/null
  if [ $? -eq 1 ]
  then 
    checkserver $server
    checkserver $server.$domain
  else
    color_msg $red "ping to $server failed"
  fi
done
}

#
# check configuration
#
checkconfig() {
#https://askubuntu.com/questions/87449/how-to-disable-strict-host-key-checking-in-ssh
  if [ -f $sconfig ]
  then
    color_msg $green "$sconfig exists"
    ls -l $sconfig
  fi
}

sconfig=~/.ssh/config
sknown=~/.ssh/known_hosts

case  $# in
  0) usage ;;
  1) usage ;;
  *) 
    domain=$1 
    shift 
    color_msg $blue "checking ssh configuration for domain $domain sites $*"
    checkconfig
    checkservers $* 
    #for server in $(echo $* | sort)
    ##do
    #  checkknown $server 
    #done
    ;;
esac
Wolfgang Fahl
fonte
2

Aqui está como fazer uma coleção de hosts

definir uma coleção de hosts

ssh_hosts:
  - server1.domain.com
  - server2.domain.com
  - server3.domain.com
  - server4.domain.com
  - server5.domain.com
  - server6.domain.com
  - server7.domain.com
  - server8.domain.com
  - server9.domain.com

Em seguida, defina duas tarefas para adicionar as chaves aos hosts conhecidos:

- command: "ssh-keyscan {{item}}"
   register: known_host_keys
   with_items: "{{ssh_hosts}}"
   tags:
     - "ssh"

 - name: Add ssh keys to know hosts
   known_hosts:
     name: "{{item.item}}"
     key: "{{item.stdout}}"
     path: ~/.ssh/known_hosts
   with_items: "{{known_host_keys.results}}"
Vackar Afzal
fonte
0

O melhor seria verificar a impressão digital de cada novo servidor / host. Essa é a única maneira de autenticar o servidor. Sem ele, sua conexão SSH pode estar sujeita a um ataque man-in-the-middle .

Se você realmente tem certeza de que deseja ignorar a verificação da impressão digital, a segunda opção melhor e menos segura é usar StrictHostKeyChecking=accept-new, que foi introduzida no OpenSSH versão 7.6 (2017-10-03) :

O primeiro "accept-new" aceitará automaticamente chaves até então invisíveis, mas recusará conexões para chaves de host alteradas ou inválidas.

Não use o valor antigo, StrictHostKeyChecking=noque nunca verifica a autenticidade do servidor. (Embora o significado dessa =noconfiguração seja alterado algumas versões mais tarde .)

Dominik
fonte