web-dev-qa-db-fra.com

ansible ssh Prompt unknown_hosts issue

J'utilise Ansible Playbook et cela fonctionne bien sur une seule machine.

Lorsque j'essaie pour la première fois sur une nouvelle machine, l'erreur suivante apparaît.

17:04:34 PLAY [appservers] ************************************************************* 
17:04:34 
17:04:34 GATHERING FACTS *************************************************************** 
17:04:34 fatal: [server02.cit.product-ref.dev] => {'msg': "FAILED: (22, 'Invalid argument')", 'failed': True}
17:04:34 fatal: [server01.cit.product-ref.dev] => {'msg': "FAILED: (22, 'Invalid argument')", 'failed': True}
17:04:34 
17:04:34 TASK: [common | remove old ansible-tmp-*] ************************************* 
17:04:34 FATAL: no hosts matched or all hosts have already failed -- aborting
17:04:34 
17:04:34 
17:04:34 PLAY RECAP ******************************************************************** 
17:04:34            to retry, use: --limit @/var/lib/jenkins/site.retry
17:04:34 
17:04:34 server01.cit.product-ref.dev      : ok=0    changed=0    unreachable=1    failed=0   
17:04:34 server02.cit.product-ref.dev      : ok=0    changed=0    unreachable=1    failed=0   
17:04:34 
17:04:34 Build step 'Execute Shell' marked build as failure
17:04:34 Finished: FAILURE

Cette erreur peut être résolue si je vais d’abord sur la machine source (à partir de laquelle j’exécute le livre de jeu ansible) et manuellement sur SSH sur la machine cible (en tant qu’utilisateur donné) et saisissez "oui" pour l’entrée de fichier known_hosts.

Maintenant, si je lance le même livre de jeu ansible une seconde fois, cela fonctionne sans erreur.

Par conséquent, comment puis-je supprimer l'invite que SSH donne lors de la première entrée ssh known_hosts pour un utilisateur donné (dossier ~/.ssh, fichier known_hosts)?

J'ai trouvé que je pouvais le faire si j'utilisais les entrées de configuration suivantes dans le fichier ~/.ssh/config.

~/.ssh/config

# For vapp virtual machines
Host *
  StrictHostKeyChecking no
  UserKnownHostsFile=/dev/null
  User kobaloki
  LogLevel ERROR

c'est-à-dire que si je place le code ci-dessus dans le fichier ~/.ssh/config de l'ordinateur distant et que je teste Ansible playbook pour la première fois, je ne serai pas invité à entrer "oui" et playbook s'exécutera correctement (sans nécessiter la créer manuellement une entrée de fichier known_hosts de la machine source à la machine cible/distante).

Mes questions: 1. Quels problèmes de sécurité je devrais prendre soin si je vais ~/.ssh/config moyen 2. Comment puis-je passer les paramètres (ce qui est dans le fichier de configuration) comme paramètres/options à ansible en ligne de commande afin qu'il s'exécutera pour la première fois sur une nouvelle machine (sans demander/en fonction de l'entrée du fichier known_hosts sur la machine source pour la machine cible?)

33
Arun Sangal

Les documents ansible ont ne section à ce sujet . Citant:

Ansible 1.2.1 et ultérieur ont la vérification de clé d’hôte activée par défaut.

Si un hôte est réinstallé et que sa clé est différente dans "known_hosts", il en résultera un message d'erreur jusqu'à ce qu'il soit corrigé. Si un hôte ne se trouve pas initialement dans ‘connus_hôtes’, il en résultera une confirmation de la clé, ce qui donnera lieu à une expérience interactive si vous utilisez Ansible, par exemple cron. Vous pourriez ne pas vouloir cela.

Si vous comprenez les implications et souhaitez désactiver ce comportement, vous pouvez le faire en modifiant /etc/ansible/ansible.cfg ou ~/.ansible.cfg:

[defaults]
Host_key_checking = False

Cela peut aussi être défini par une variable d’environnement:

$ export ANSIBLE_Host_KEY_CHECKING=False

Notez également que la vérification de la clé d’hôte en mode paramiko est relativement lente. Par conséquent, il est recommandé de basculer sur ‘ssh’ lorsque vous utilisez cette fonction.

38
Ben Whaley

Pour mettre à jour local known_hosts fichier, j’ai utilisé une combinaison de ssh-keyscan (avec Dig pour résoudre un nom d’hôte en adresse IP) et le module ansible known_hosts comme suit: (nom_fichier ssh-known_hosts.yml)

- name: Store known hosts of 'all' the hosts in the inventory file
  hosts: localhost
  connection: local

  vars:
    ssh_known_hosts_command: "ssh-keyscan -T 10"
    ssh_known_hosts_file: "{{ lookup('env','HOME') + '/.ssh/known_hosts' }}"
    ssh_known_hosts: "{{ groups['all'] }}"

  tasks:

  - name: For each Host, scan for its ssh public key
    Shell: "ssh-keyscan {{ item }},`Dig +short {{ item }}`"
    with_items: "{{ ssh_known_hosts }}"
    register: ssh_known_Host_results
    ignore_errors: yes

  - name: Add/update the public key in the '{{ ssh_known_hosts_file }}'
    known_hosts:
      name: "{{ item.item }}"
      key: "{{ item.stdout }}"
      path: "{{ ssh_known_hosts_file }}"
    with_items: "{{ ssh_known_Host_results.results }}"

Pour exécuter un tel yml, faites

ANSIBLE_Host_KEY_CHECKING=false ansible-playbook path/to/the/yml/above/ssh-known_hosts.yml

En conséquence, pour chaque hôte dans le inventaire, tous les algorithmes pris en charge seront ajoutés/mis à jour dans le known_hosts fichier sous nom d'hôte, adresse IP enregistrement de paire; tel que

atlanta1.my.com,10.0.5.2 ecdsa-sha2-nistp256 AAAAEjZHN ... NobYTIGgtbdv3K+w=
atlanta1.my.com,10.0.5.2 ssh-rsa AAAAB3NaC1y ... JTyWisGpFeRB+VTKQ7
atlanta1.my.com,10.0.5.2 ssh-ed25519 AAAAC3NaCZD ... UteryYr
denver8.my.com,10.2.13.3 ssh-rsa AAAAB3NFC2 ... 3tGDQDSfJD
...

(À condition que le fichier inventaire ressemble à ceci:

[master]
atlanta1.my.com
atlanta2.my.com

[slave]
denver1.my.com
denver8.my.com

)

Contrairement à la réponse de Xiong, cela permettrait de gérer correctement le contenu de la known_hosts fichier.

Ce jeu est particulièrement utile si vous utilisez un environnement virtualisé dans lequel les hôtes cibles sont ré-imagés (les clés de publication ssh sont donc modifiées).

29
Stepan Vavra

Désactiver entièrement la vérification de la clé de l'hôte est une mauvaise idée du point de vue de la sécurité, car cela vous expose à des attaques de type "man-in-the-middle".

Si vous pouvez supposer que le réseau actuel n'est pas compromis (c'est-à-dire, lorsque vous vous connectez à la machine pour la première fois et que vous lui présentez une clé, cette clé est en fait celle de la machine et non celle d'un attaquant), alors vous pouvez utiliser - ssh-keyscan et le module Shell pour ajouter les clés des nouveaux serveurs à votre fichier hosts connu (edit: la réponse de Stepan le fait mieux):

- name: accept new ssh fingerprints
  Shell: ssh-keyscan -H {{ item.public_ip }} >> ~/.ssh/known_hosts
  with_items: ec2.instances

(Démontré ici comme vous le trouverez après provisioning ec2 .)

16
Xiong Chiamiov

Suite à la réponse correcte de @Stepan Vavra. Une version plus courte est:

- known_hosts:
    name: "{{ item }}"
    key: "{{ lookup('pipe', 'ssh-keyscan {{ item }},`Dig +short {{ item }}`') }}"
  with_items:
   - google.com
   - github.com
7
user1634074

Ne faites pas quelque chose comme ce travail pour amorcer le fichier known_hosts

ANSIBLE_Host_KEY_CHECKING=false ansible all -m ping

Cela devrait vous connecter à chaque hôte de l'inventaire, mettre à jour le fichier known_hosts pour chaque hôte sans avoir à entrer "oui" pour chaque invite, puis lance le module "ping" sur chaque hôte?

Un test rapide (suppression de mon fichier known_hosts puis exécution de ce qui précède, effectué sur une instance Ubuntu 16.04) semble renseigner le fichier known_hosts avec leurs empreintes digitales actuelles.

La solution de @Stepan Vavra ne fonctionnait pas pour moi car j'utilisais des hôtes avec alias (la connexion à des adresses IP internes dépourvues de DNS, je voulais donc que les noms plus descriptifs fassent référence à chaque hôte de l'inventaire et que la variable ansible_Host soit utilisée. pointez sur l'IP réelle pour chacun). L'exécution de ce qui précède était beaucoup plus simple et amorçait mon fichier known_hosts sans avoir à désactiver la vérification de la clé de l'hôte dans ansible ou ssh.

5
Nick Istre

vous pouvez également le définir à partir du niveau du serveur. vous devrez configurer le fichier de configuration ssh afin d'éviter que ssh ne vérifie l'invite suivante:

éditer le chemin du fichier:

/etc/ssh/ssh_config

maintenant décommentez la ligne:

StrictHostKeyChecking no

enregistrer les modifications et c'est tout

Attention: Ansible n'effectuera plus la vérification de la clé de l'hôte SSH avec les connexions ayant les paramètres ci-dessus.

1
dsaydon