Dépannage des échecs de connexion SSH dans les playbooks Ansible
Ce guide expert propose une approche systématique pour dépanner les échecs de connexion SSH courants lors de l'exécution de playbooks Ansible. Apprenez à exploiter la verbosité maximale (`-vvv`) pour le diagnostic, résoudre les erreurs d'authentification liées aux clés privées et aux permissions, corriger les problèmes de « Host key verification failed » et diagnostiquer les blocages réseau. Des étapes pratiques et des exemples en ligne de commande vous permettent d'isoler et de résoudre rapidement la cause racine des timeouts de connexion et des messages d'autorisation refusée, rétablissant ainsi une automatisation fiable.
Dépannage des échecs de connexion SSH dans les playbooks Ansible
Ansible utilise le plus souvent Secure Shell (SSH) pour communiquer avec les nœuds gérés Linux et Unix. Il peut utiliser d'autres plugins de connexion, et l'automatisation Windows utilise souvent WinRM, mais SSH est le chemin que la plupart des équipes déboguent au quotidien. Lorsqu'un playbook Ansible échoue avec une erreur de connectivité, cela pointe presque toujours vers un problème sous-jacent dans la configuration SSH standard entre la machine de contrôle et l'hôte cible. Comprendre comment diagnostiquer systématiquement ces échecs est crucial pour maintenir une automatisation fiable.
Phase 1 : Activation de la verbosité et vérifications initiales
Le moyen le plus rapide d'arrêter de deviner est d'augmenter la verbosité de la sortie. Les erreurs SSH sont souvent masquées, mais la verbosité maximale révèle les paramètres exacts utilisés par Ansible et le message d'erreur spécifique renvoyé par le client OpenSSH sous-jacent.
Utiliser les indicateurs de verbosité
Exécutez votre commande de test ou votre playbook avec trois ou quatre indicateurs de verbosité (-v, -vv, -vvv, -vvvv). La plupart des problèmes de connexion sont résolus en examinant la sortie de -vvv.
# Tester la connectivité vers un hôte nommé 'webserver' défini dans votre inventaire
ansible webserver -m ansible.builtin.ping -vvv
# Exécuter un playbook avec un débogage maximal
ansible-playbook site.yml -i inventory.ini -vvvv
Vérifier l'inventaire et l'état de l'hôte
Assurez-vous que l'hôte que vous ciblez est correctement défini et accessible.
- Le nom de l'hôte est-il correct ? Vérifiez l'orthographe dans votre fichier d'inventaire (
/etc/ansible/hostsou inventaire personnalisé). - La cible est-elle allumée ? Assurez-vous que le nœud géré est sous tension et accessible sur le réseau.
- Les variables d'inventaire sont-elles correctes ? Confirmez que les variables essentielles comme
ansible_host(adresse IP ou nom d'hôte) etansible_user(nom d'utilisateur distant) sont correctement définies pour le groupe ou l'hôte cible.
# Exemple d'extrait d'inventaire
[webservers]
web1 ansible_host=192.168.1.100 ansible_user=deploy_user ansible_port=22
Phase 2 : Vérification de la connectivité manuelle de base
Si Ansible ne peut pas se connecter, la première étape doit toujours être de confirmer que le SSH standard fonctionne manuellement, en utilisant exactement le même utilisateur, la même clé et le même port qu'Ansible est configuré pour utiliser.
Test SSH manuel
Si vous utilisez un utilisateur spécifique (ansible_user) et une clé privée spécifique (ansible_ssh_private_key_file), reproduisez cette connexion manuellement.
# Test SSH standard (si utilisation du port et de la clé par défaut)
ssh <ansible_user>@<ansible_host>
# Test avec une clé privée et un port non par défaut
ssh -i /chemin/vers/cle/privee -p 2222 [email protected]
Si le test SSH manuel échoue, corrigez-le d'abord. Ansible ne fait qu'envelopper le même chemin SSH, donc déboguer la syntaxe du playbook avant que le SSH ne fonctionne fait généralement perdre du temps.
Phase 3 : Diagnostic des échecs d'authentification
Les échecs d'authentification sont la cause la plus courante des problèmes de connexion Ansible. Ils se manifestent généralement par des erreurs Authentication failed ou Permission denied.
3.1 Permissions et emplacement des clés
Si Ansible utilise des clés SSH, assurez-vous que le fichier de clé privée a les permissions correctes et restreintes sur la machine de contrôle. SSH rejette souvent les clés trop permissives.
# Définir les permissions correctes sur le fichier de clé privée
chmod 600 /chemin/vers/cle/privee
De plus, si vous utilisez un agent SSH, assurez-vous que votre clé est ajoutée :
# Démarrer l'agent si nécessaire
eval "$(ssh-agent -s)"
# Ajouter votre clé à l'agent
ssh-add /chemin/vers/cle/privee
3.2 Échecs de demande de mot de passe (Timeout/Mot de passe manquant)
Si votre configuration nécessite un mot de passe (déconseillé en production mais courant dans les laboratoires), Ansible doit le recevoir. Si la connexion se bloque ou expire, Ansible attend probablement un mot de passe qui n'a jamais été fourni.
Utilisez l'indicateur --ask-pass ou -k pour demander le mot de passe de connexion SSH :
ansible webserver -m ansible.builtin.ping -k
3.3 Clés autorisées distantes
Vérifiez que la clé publique correspondant à votre clé privée est correctement installée dans le fichier ~/.ssh/authorized_keys sur le nœud géré, et que les permissions du fichier et du répertoire côté distant sont correctes (700 pour .ssh et 600 pour authorized_keys).
Phase 4 : Résolution des erreurs de clé d'hôte
Ansible respecte le fichier known_hosts, qui stocke l'empreinte numérique des serveurs distants. Si la clé d'hôte d'un nœud géré change (par exemple, en raison d'une reconstruction ou d'une réaffectation d'IP), les tentatives de connexion SSH échoueront avec un avertissement qui ressemble à une attaque Man-in-the-Middle.
L'erreur Host key verification failed
Lorsque cette erreur se produit, vous devez mettre à jour ou supprimer l'entrée de clé conflictuelle.
- Identifiez le numéro de ligne dans
~/.ssh/known_hostsmentionné dans la sortie d'erreur. - Supprimez l'entrée en utilisant
ssh-keygen.
# Remplacez <hostname_or_ip> par l'hôte réel qui échoue
ssh-keygen -R <hostname_or_ip>
⚠️ Avertissement de sécurité : Désactivation de la vérification d'hôte
Pour des tests temporaires ou dans des environnements de laboratoire hautement contrôlés où l'instabilité de l'hôte est attendue, vous pouvez configurer Ansible pour ignorer la vérification de la clé d'hôte. Ceci est fortement déconseillé pour les environnements de production car cela vous expose à des attaques MITM.
Dans votre
ansible.cfg(ou variable d'environnement temporaire) :[defaults] host_key_checking = False
Phase 5 : Problèmes de réseau, de pare-feu et d'environnement distant
Parfois, SSH se connecte, mais la connexion se bloque ou échoue en raison de la configuration réseau ou de restrictions sur la machine cible.
5.1 Blocage par pare-feu
Si la connexion expire sans invite, un pare-feu bloque probablement la tentative de connexion. Vérifiez le pare-feu à trois endroits :
- Local (Machine de contrôle) : Assurez-vous que le trafic sortant sur le port 22 (ou un port personnalisé) est autorisé.
- Chemin réseau : Assurez-vous qu'aucune ACL réseau intermédiaire ou pare-feu d'entreprise ne bloque le trafic.
- Distant (Nœud géré) : Vérifiez que le pare-feu de l'hôte distant (
firewalld,ufw, etc.) a le SSH (généralement le port 22) ouvert et configuré pour la bonne interface réseau.
5.2 Erreurs d'interpréteur Python
Ansible nécessite un interpréteur Python sur le nœud géré pour exécuter les modules. Bien qu'il ne s'agisse pas strictement d'un échec SSH, la phase de connexion initiale d'Ansible implique la collecte de faits, qui est une exécution de script Python. Si la machine cible est une installation minimale sans Python 3, la connexion peut échouer pendant la phase de configuration.
Si votre cible utilise Python 3 mais que le chemin de l'interpréteur est non standard (par exemple, python3.8 au lieu de python3), spécifiez le chemin correct dans votre inventaire :
[target_host]
ansible_python_interpreter=/usr/bin/python3.8
5.3 Contexte SELinux ou AppArmor
Dans de rares cas, des modules de sécurité trop stricts comme SELinux (sur RHEL/CentOS/Fedora) ou AppArmor (sur Ubuntu/Debian) peuvent empêcher l'accès correct au profil shell ou aux permissions de répertoire de l'utilisateur distant pendant la session SSH. Vérifiez les journaux d'audit de l'hôte distant (/var/log/audit/audit.log ou équivalent) pour les refus AVC liés à SSH ou à l'accès au répertoire personnel de l'utilisateur.
Modèles courants issus d'échecs Ansible réels
Le texte d'erreur vous indique généralement quelle couche inspecter. UNREACHABLE! avec Permission denied (publickey) n'est pas le même problème que Failed to connect to the host via ssh: Connection timed out. Le premier signifie que le démon SSH a répondu mais n'a pas accepté le chemin d'identification. Le second signifie que la connexion TCP n'a pas abouti, ou qu'un pare-feu l'a silencieusement abandonnée.
Si vous gérez des instances cloud, vérifiez le nom d'utilisateur par défaut avant de changer les clés. Amazon Linux utilise couramment ec2-user, Ubuntu utilise ubuntu, Debian utilise souvent admin ou debian, et les images personnalisées peuvent utiliser quelque chose de complètement différent. Une clé valide avec un mauvais nom d'utilisateur distant vous donne toujours un échec de clé publique. La vérification la plus rapide est :
ssh -i key.pem [email protected]
ssh -i key.pem [email protected]
Pour les bastions, rendez le chemin de saut explicite dans l'inventaire afin que chaque exécution utilise la même route :
[private_web]
web1 ansible_host=10.0.10.25 ansible_user=ubuntu
[private_web:vars]
ansible_ssh_common_args='-o [email protected]'
Si cela fonctionne sur votre ordinateur portable mais échoue dans le CI, comparez la version SSH de l'exécuteur CI, les permissions de la clé privée, le fichier known_hosts et si l'exécuteur peut atteindre le bastion. Les échecs CI ne sont souvent pas des problèmes Ansible du tout ; l'exécuteur n'a tout simplement pas le même chemin réseau ou la même clé chargée dans l'agent.
Un autre modèle est la confusion entre l'élévation de privilèges et l'échec de connexion. SSH réussit, puis le playbook se bloque parce que become a besoin d'un mot de passe sudo ou parce que l'utilisateur distant n'est pas autorisé à exécuter la commande. Testez cela séparément :
ansible web1 -m ansible.builtin.command -a "whoami" -vvv
ansible web1 -b -m ansible.builtin.command -a "whoami" -vvv
Si la première commande renvoie l'utilisateur de connexion et que la seconde échoue, la couche SSH est saine. Corrigez sudoers, ansible_become_password ou votre modèle de privilège au lieu de modifier les clés.
Variables d'inventaire à vérifier deux fois
Ansible a plusieurs noms de variables qui se ressemblent, et les anciens exemples sur Internet peuvent rendre cela plus compliqué. Préférez les noms actuels ansible_user, ansible_host, ansible_port, ansible_private_key_file et ansible_ssh_common_args dans les nouveaux inventaires. Si l'inventaire contient à la fois des noms anciens et nouveaux, ou si le même hôte apparaît dans plusieurs groupes, utilisez ansible-inventory --host web1 pour voir le résultat résolu au lieu de lire les fichiers à l'œil.
Vérifiez également si ansible_connection a été défini à un endroit inattendu. Les périphériques réseau, les conteneurs, les tâches de provisionnement local et les hôtes Windows peuvent utiliser des plugins de connexion autres que le SSH par défaut. Un hôte avec ansible_connection=local ne testera pas du tout le SSH distant. Un hôte Windows utilisant WinRM ne doit pas être débogué comme un problème SSH, sauf si vous avez intentionnellement configuré OpenSSH sur Windows.
Pour les grands inventaires, isolez un hôte avant d'exécuter le playbook complet :
ansible web1 -i inventory.ini -m ansible.builtin.ping -vvv
ansible-playbook site.yml -i inventory.ini --limit web1 --check -vvv
Cela maintient la sortie lisible et empêche une exécution par lots bruyante de cacher la seule ligne qui compte.
Résumé des erreurs de connexion courantes et solutions
| Message d'erreur | Cause probable | Correctif applicable |
|---|---|---|
Permission denied (publickey). |
Clé non reconnue ou mauvaises permissions de clé. | chmod 600 sur la clé privée ; vérifier la clé publique sur l'hôte distant. |
Host key verification failed. |
Clé d'hôte modifiée ou fichier known_hosts corrompu. | Utilisez ssh-keygen -R hostname pour supprimer l'ancienne entrée. |
Connection timed out. |
Blocage par pare-feu ou hôte hors ligne/inaccessible. | Vérifiez la connectivité manuelle (ping, ssh) ; vérifiez les règles de pare-feu sur l'hôte cible. |
| La connexion se bloque/stagne. | Attente d'une saisie de mot de passe qui n'a pas été fournie. | Exécutez avec -k ou configurez l'authentification par clé. |
Un ordre pratique des opérations
Lorsque je débogue des échecs SSH Ansible, j'essaie de prouver une couche à la fois. D'abord, j'exécute ansible-inventory --host <nom> ou ansible-inventory --graph pour savoir quelles variables Ansible voit réellement. Les surprises d'inventaire sont courantes : une variable de groupe écrase ansible_user, un inventaire dynamique renvoie une adresse privée, ou un hôte a été déplacé vers un groupe avec un ansible_port différent.
Ensuite, je copie la commande SSH exacte impliquée par -vvv. Si la sortie montre -o Port=2222 -o IdentityFile=/keys/deploy.pem -l ubuntu 10.0.4.18, je teste cette combinaison exacte manuellement. Un ssh [email protected] réussi ne suffit pas si Ansible utilise une clé, un port, un nom d'hôte ou une configuration SSH différents.
Si le SSH manuel fonctionne mais qu'Ansible échoue, je recherche un comportement spécifique à Ansible : des sockets de multiplexage SSH obsolètes sous ~/.ansible/cp, une variable d'inventaire pointant vers le mauvais interpréteur, une invite become qui est confondue avec un blocage de connexion, ou un playbook exécuté depuis CI sans le même agent SSH qui existe sur mon ordinateur portable. Supprimer ~/.ansible/cp/* est un test sûr lorsque la sortie de débogage mentionne ControlMaster ou ControlPath ; cela force une nouvelle session SSH.
Une astuce utile consiste à séparer la connexion de l'exécution du module. ansible host -m ansible.builtin.raw -a "whoami" -vvv nécessite moins de support Python distant que les modules normaux. Si raw fonctionne mais que ping échoue, votre réseau et votre chemin SSH sont probablement corrects, et le problème est probablement la découverte de Python, les permissions ou un problème d'environnement shell sur la cible.
Pour les inventaires de production, documentez les hypothèses de connexion à côté du groupe d'hôtes : utilisateur distant attendu, source de la clé, chemin du bastion, port SSH et si la vérification de la clé d'hôte est appliquée. La prochaine panne est plus facile lorsque tout le monde peut comparer l'exécution défaillante au chemin prévu au lieu de le rétro-ingénierer à partir des journaux de débogage.