350 votes

Puis-je ajouter automatiquement un nouvel hôte à known_hosts ?

Voici ma situation : Je suis en train de mettre en place un harnais de test qui, à partir d'un client central, lancera un certain nombre d'instances de machines virtuelles, puis exécutera des commandes sur celles-ci par l'intermédiaire de ssh . Les machines virtuelles auront des noms d'hôtes et des adresses IP précédemment inutilisés, elles ne seront donc pas dans la liste des machines virtuelles. ~/.ssh/known_hosts sur le client central.

Le problème que j'ai, c'est que la première ssh exécutée contre une nouvelle instance virtuelle aboutit toujours à une invite interactive :

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-t-il un moyen de contourner ce problème et de faire en sorte que le nouvel hôte soit déjà connu de la machine cliente, peut-être en utilisant une clé publique qui est déjà intégrée dans l'image de la machine virtuelle ? J'aimerais vraiment éviter d'avoir à utiliser Expect ou autre pour répondre à l'invite interactive si je le peux.

9 votes

Pour un environnement de test autonome et physiquement sécurisé, l'acceptation automatique des clés peut fonctionner parfaitement. Mais l'acceptation automatique des clés publiques dans un environnement de production ou sur un réseau non sécurisé (tel qu'Internet) contourne complètement toute protection contre les attaques de type "man-in-the-middle" que SSH pourrait offrir. Le site sólo Le moyen le plus sûr de s'assurer que vous êtes protégé contre les attaques MITM est de vérifier la clé publique de l'hôte par un canal de confiance hors bande. Il n'y a pas de moyen sûr d'automatiser cela sans mettre en place une infrastructure de signature de clé modérément compliquée.

6voto

Jacob Evans Points 7455

Comment construisez-vous ces machines ? pouvez-vous exécuter une mise à jour dns script ? pouvez-vous rejoindre un domaine IPA ?

FreeIPA le fait automatiquement, mais tout ce dont vous avez besoin est de SSHFP enregistrements dns et DNSSEC sur votre zone (freeipa fournit comme options configurables (dnssec désactivé par défaut)).

Vous pouvez obtenir les enregistrements SSHFP existants de votre hôte en exécutant .

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

puis, une fois publié, vous ajouterez VerifyHostKeyDNS yes à votre ssh_config ou ~/.ssh/config

Si/quand google décidera d'adopter le DNSSEC, vous pourrez vous connecter sans demander de clé d'hôte.

ssh jersey.jacobdevans.com

MAIS mon domaine n'est pas encore signé, donc pour l'instant vous verrez.....

debug1 : Clé hôte du serveur : ecdsa-sha2-nistp256 SHA256:H1D3kBF9/t0ynbz2IqfUdVHhL/WROQLGan2ijkfeT0s

debug1 : trouvé 4 empreintes digitales non sécurisées dans le DNS

debug1 : correspondance de l'empreinte de la clé de l'hôte

trouvé dans le DNS L'authenticité de l'hôte 'jersey.jacobdevans.com (2605:6400:10:434::10)' ne peut être établie. L'empreinte de la clé ECDSA est SHA256:H1D3kBF9/t0ynbz2IqfUdVHhL/WROQLGan2ijkfeT0s. Empreinte de clé d'hôte correspondante trouvée dans le DNS. Êtes-vous sûr de vouloir continuer à vous connecter (oui/non) ? non

5voto

VenomFangs Points 489

J'ai eu un problème similaire et j'ai constaté que certaines des réponses fournies ne m'ont permis de trouver qu'une partie de la solution automatique. Voici ce que j'ai fini par utiliser, j'espère que cela vous aidera :

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

Il ajoute la clé à known_hosts et ne demande pas le mot de passe.

5voto

Amadu Bah Points 209

Les éléments suivants évitent les entrées en double dans ~/.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

4voto

Wolfgang Fahl Points 555

Cet ensemble

  • ssh-key-scan
  • ssh-copy-id
  • Avertissement clé de l'ECSDA

ne cessait de m'ennuyer, alors j'ai opté pour

Un script pour les gouverner tous.

C'est une variante du script à https://askubuntu.com/a/949731/129227 avec la réponse de Amadu Bah https://serverfault.com/a/858957/162693 dans une boucle.

exemple d'appel

./sshcheck somedomain site1 site2 site3

Le script bouclera sur les sites de noms et modifiera le fichier .ssh/config et .ssh/known_hosts et fera ssh-copy-id sur demande - pour la dernière fonctionnalité, il suffit de laisser les appels de test ssh échouer, par exemple en appuyant 3 fois sur entrée lors de la demande de mot de passe.

sshcheck script

#!/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

4voto

Sharcoux Points 169

Si vous souhaitez vérifier la clé avant de l'ajouter en aveugle, vous pouvez utiliser ce code :

# verify github and gitlab key
# GitHub
github=SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8
ssh-keyscan github.com >> githubKey
read bit githubkey host <<< $(ssh-keygen -lf githubKey)
if [ "$githubkey" != "$github" ]
then
  echo "The GitHub fingerprint is incorrect"
  exit 1
fi
echo "github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==" | sudo tee -a /etc/ssh/ssh_known_hosts

# GitLab
gitlab=SHA256:ROQFvPThGrW4RuWLoL9tq9I9zJ42fK4XywyRtbOz/EQ
ssh-keyscan gitlab.com >> gitlabKey
read bit gitlabkey host <<< $(ssh-keygen -lf gitlabKey)
if [ "$githubkey" != "$github" ]
then
  echo "The GitLab fingerprint is incorrect"
  exit 1
fi
echo "gitlab.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCsj2bNKTBSpIYDEGk9KxsGh3mySTRgMtXL583qmBpzeQ+jqCMRgBqB98u3z++J1sKlXHWfM9dyhSevkMwSbhoR8XIq/U0tCNyokEi/ueaBMCvbcTHhO7FcwzY92WK4Yt0aGROY5qX2UKSeOvuP4D6TPqKF1onrSzH9bx9XUf2lEdWT/ia1NEKjunUqu1xOB/StKDHMoX4/OKyIzuS0q/T1zOATthvasJFoPrAjkohTyaDUz2LN5JoH839hViyEG82yB+MjcFV5MU3N1l1QL3cVUCh93xSaua1N85qivl+siMkPGbO5xR/En4iEY6K2XPASUEMaieWVNTRCtJ4S8H+9" | sudo tee -a /etc/ssh/ssh_known_hosts

Les clés GitHub et GitLab peuvent changer si elles sont compromises. Dans ce cas, vérifiez les plus récentes ici y

Remarque : Vous devrez peut-être vous assurer que la clé n'est pas ajoutée deux fois. Pour cela, reportez-vous aux autres réponses.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X