Defina a opção StrictHostKeyChecking
para no
, no arquivo de configuração ou via -o
:
ssh -o StrictHostKeyChecking=no [email protected]
Esta é a 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, em seguida, executa comandos nelas via ssh
. As máquinas virtuais terão nomes de host e endereços IP não usados anteriormente, portanto, eles não estarão no arquivo ~/.ssh/known_hosts
no cliente central.
O problema que estou tendo é que o primeiro comando ssh
executado contra 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 eu ignorar isso e fazer com que o novo host já seja conhecido na máquina cliente, talvez usando uma chave pública que já esteja integrada na imagem da máquina virtual? Eu realmente gostaria de evitar ter que usar o Expect ou o que for para responder ao prompt interativo se eu puder.
Defina a opção StrictHostKeyChecking
para no
, no arquivo de configuração ou via -o
:
ssh -o StrictHostKeyChecking=no [email protected]
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 garante que não haja entradas duplicadas, que você esteja coberto para o nome do host e o endereço IP e também para a saída hash, uma medida de segurança extra.
Para os mais preguiçosos:
ssh-keyscan <host> >> ~/.ssh/known_hosts
Como mencionado, o uso do key-scan seria o & maneira 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 texto acima fará o truque para adicionar um host, SOMENTE se ainda não tiver sido adicionado. Também não é seguro de concorrência; 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 roubado, levando o arquivo known_hosts a ficar inchado ...
Você pode usar o comando ssh-keyscan
para pegar a chave pública e anexá-la ao seu arquivo known_hosts
.
É assim que você pode incorporar ssh-keyscan ao 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 }}'
Eu tive um problema semelhante e descobri que algumas das respostas fornecidas só me ajudaram a encontrar uma solução automatizada. O seguinte é o que acabei usando, espero que ajude:
ssh -o "StrictHostKeyChecking no" -o PasswordAuthentication=no 10.x.x.x
Adiciona a chave a known_hosts
e não solicita a senha.
esta seria uma solução completa, aceitando apenas a chave do host pela primeira vez
#!/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([]) }}'
Então, eu estava procurando uma maneira mundana de contornar a interação manual do host desconhecido da clonagem de um repositório do git, conforme 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 o git sobre o 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 - verificando manualmente as impressões digitais do SSH. Mas voltemos ao que estamos fazendo.
Bom. Estou comprometido em vários lugares e máquinas que verifiquei - ou a explicação mais plausível de que tudo é ótimo é o que está acontecendo.
Essa "impressão digital" é apenas uma string encurtada com um algoritmo unidirecional para a nossa conveniência humana, com o risco de mais de uma string se resolver na mesma impressão digital. Acontece, eles são chamados de colisões.
Independentemente, voltemos à 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, antecipadamente, temos uma maneira de solicitar uma forma de identificação do host original.
Neste ponto, estamos manualmente tão vulneráveis quanto automaticamente - as sequências de caracteres 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, use essa string de uma forma que evite perguntar sobre a autenticidade de um host ...
O arquivo known_hosts, neste caso, não usa entradas de texto sem formatação. Você saberá entradas com hash quando as vir, elas parecerão 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ários aparece de maneira irritante - mas você pode se livrar dela com um simples redirecionamento por meio do ">" ou "> >" convenção.
Como eu fiz o meu melhor para obter dados não contaminados para serem usados para identificar um "host" e confiança, eu adicionarei essa identificação ao meu arquivo known_hosts no meu diretório ~ / .ssh. Uma vez que agora será identificado como um host conhecido, não receberei o prompt mencionado acima quando você era um jovem.
Obrigado por ficar comigo, aqui vai você. Estou adicionando a chave bitbucket RSA 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 você 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ê fica virgem por hoje. Você pode fazer o mesmo com o github seguindo instruções semelhantes em seu próprio tempo.
Eu vi muitos posts de estouro de pilha dizendo para que você programaticamente adicione a chave às cegas sem qualquer tipo de verificação. Quanto mais você verificar a chave de diferentes máquinas em diferentes redes, mais confiança você pode ter de que o host é aquele que diz que é - e é 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 que alguém escute 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 legítimo e agora você sabe como obter essas informações para compará-las, para poder confiar na conexão. Basta lembrar mais comparações de diferentes computadores & as redes geralmente aumentam sua capacidade de confiar na conexão.
Eu faço um script de uma linha, um pouco longo, mas útil para fazer essa tarefa para hosts com múltiplos IPs, usando dig
e bash
(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
O seguinte evita 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
Esse todo
negócios continuavam me irritando, então optei por
Um script para governar todos eles
Esta é uma variante do script no link com a resposta do Amadu Bah link em um loop.
chamada de exemplo
./ sshcheck somedomain site1 site2 site3
O script fará um loop pelos sites de nomes e modificará o arquivo .ssh / config e .ssh / known_hosts e fará o ssh-copy-id sob solicitação - para o último recurso, apenas as chamadas de teste ssh deixarão falhar, por exemplo clicando em entrar 3 vezes no pedido 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='3[0;34m'
red='3[0;31m'
green='3[0;32m' # '\e[1;32m' is too bright for white bg.
endColor='3[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://sobrelinux.info/questions/774/how-to-disable-strict-host-key-checking-in-ssh"$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
Para fazer isso corretamente, o que você realmente quer fazer é coletar as chaves públicas do host das VMs à medida que você as cria e soltá-las em um arquivo no formato known_hosts
. Em seguida, você pode usar o -o GlobalKnownHostsFile=...
, apontando para esse arquivo, para garantir que esteja se conectando ao host no qual acredita estar se conectando. No entanto, a maneira como você faz isso depende de como você está configurando as máquinas virtuais, mas lê-lo do sistema de arquivos virtual, se possível, ou até mesmo fazer com que o host imprima o conteúdo de /etc/ssh/ssh_host_rsa_key.pub
durante a configuração. / p>
Dito isso, 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 previstos. Fazer um simples "armazenamento na primeira conexão" (por meio de uma digitalização 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 algum mínimo de segurança. No entanto, se você fizer isso, sugiro que você altere o arquivo de hosts conhecidos do usuário ( -o UserKnownHostsFile=...
) para um arquivo específico
para esta instalação de teste em particular; isso evitará poluir o seu arquivo hosts conhecido pessoal com informações de teste e facilitará a limpeza das chaves públicas agora inúteis quando você excluir suas VMs.
Como você está construindo essas máquinas? você pode executar um script de atualização do DNS? você pode participar de um domínio IPA?
O FreeIPA faz isso automaticamente, mas essencialmente tudo que você precisa é de SSHFP registros de DNS 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 IN SSHFP 1 1 4d8589de6b1a48e148d8fc9fbb967f1b29f53ebc jersey.jacobdevans.com IN SSHFP 1 2 6503272a11ba6d7fec2518c02dfed88f3d455ac7786ee5dbd72df63307209d55 jersey.jacobdevans.com IN SSHFP 3 1 5a7a1e8ab8f25b86b63c377b303659289b895736 > jersey.jacobdevans.com IN SSHFP 3 2 1f50f790117dfedd329dbcf622a7d47551e12ff5913902c66a7da28e47de4f4b
depois de publicado, você adicionaria VerifyHostKeyDNS yes
ao seu ssh_config ou ~ / .ssh / config
Se / Quando o Google decide ativar o DNSSEC, você pode ssh sem um prompt de hostkey.
ssh jersey.jacobdevans.com
MAS meu domínio ainda não está assinado, por enquanto você veria ....
debug1: Server host key: ecdsa-sha2-nistp256 SHA256:H1D3kBF9/t0ynbz2IqfUdVHhL/WROQLGan2ijkfeT0s
debug1: found 4 insecure fingerprints in DNS
debug1: matching host key fingerprint
found in DNS The authenticity of host 'jersey.jacobdevans.com (2605:6400:10:434::10)' can't be established. ECDSA key fingerprint is SHA256:H1D3kBF9/t0ynbz2IqfUdVHhL/WROQLGan2ijkfeT0s. Matching host key fingerprint found in DNS. Are you sure you want to continue connecting (yes/no)? no
Aqui está como fazer uma coleção de hosts
defina 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}}"