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?)
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.
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).
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 .)
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
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.
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.