Aller au contenu
Infrastructure as Code medium

Première connexion SSH avec Ansible : ssh-keygen, ssh-copy-id, ping

11 min de lecture

Logo Ansible

Vos VMs tournent et votre inventaire est correct ; il reste à autoriser Ansible à se connecter sans saisir de mot de passe à chaque fois. C’est tout l’enjeu de la première connexion SSH : créer une paire de clés Ed25519, distribuer la clé publique, simplifier la connexion via ~/.ssh/config, et valider la chaîne complète avec ansible all -m ping. À la fin : 4 pong sur les 4 hôtes du lab — la preuve fonctionnelle bout en bout que votre control node parle avec votre fleet. La page couvre le lab fresh (cloud-init a déjà injecté la clé pub) et la fleet existante (clé distribuée via ssh-copy-id).

  • Créer une paire de clés Ed25519 moderne avec ssh-keygen (et pourquoi pas RSA) ;
  • Distribuer la clé publique avec ssh-copy-id sur une fleet existante ;
  • Vérifier côté managed node que ~/.ssh/authorized_keys contient bien la bonne clé ;
  • Simplifier la connexion en posant un fichier ~/.ssh/config ;
  • Valider la chaîne complète avec ansible all -m ping (4 pong attendus) ;
  • Diagnostiquer un Permission denied (publickey) quand ça plante au premier ping.

Ansible peut se connecter par mot de passe avec --ask-pass, mais c’est à éviter pour trois raisons :

  • Pénible à l’usage : vous saisissez le mot de passe à chaque commande, sur chaque hôte ;
  • Faiblesse en sécurité : un mot de passe se devine, se rejoue, se phishe ; une clé Ed25519 256 bits est mathématiquement infaisable à casser ;
  • Inutile pour l’automatisation : un job CI/CD ne peut pas saisir un mot de passe interactif — il faudrait stocker le mot de passe en clair quelque part.

La clé SSH est la norme. Pour les opérations become / sudo, on combine la clé SSH + un compte sudoers NOPASSWD côté managed node (déjà posé par cloud-init dans le lab).

Le lab utilise une clé dédiée stockée dans ssh/id_ed25519. La commande make bootstrap la génère automatiquement la première fois :

Fenêtre de terminal
ssh-keygen -t ed25519 -N "" -f ssh/id_ed25519 -C "ansible-lab@$(hostname)"

Décortiquons les options :

OptionRôle
-t ed25519Algorithme Ed25519 (recommandé en 2026, plus court et plus rapide que RSA-4096)
-N ""Pas de passphrase (pour l’automatisation ; sur une clé personnelle vous mettez une passphrase)
-f ssh/id_ed25519Chemin du fichier privé (le .pub est créé à côté)
-C "ansible-lab@..."Commentaire qui apparaît à la fin de la clé pub — utile pour identifier la clé dans authorized_keys

Vérifiez que les deux fichiers ont été créés :

Fenêtre de terminal
ls -l ssh/id_ed25519*
-rw-------. 1 bob bob 411 Apr 25 14:34 ssh/id_ed25519
-rw-r--r--. 1 bob bob 101 Apr 25 14:34 ssh/id_ed25519.pub

Les permissions 0600 sur la clé privée sont obligatoires : SSH refuse une clé privée trop ouverte.

Fenêtre de terminal
cat ssh/id_ed25519.pub
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJoPZBb8SS7wMcIjnk+sV8rudjsRF1qMMxE9m9rK2Eyh ansible-lab@master1

Une seule ligne, trois champs : type (ssh-ed25519), clé publique encodée, commentaire. C’est cette ligne qu’on copiera dans ~/.ssh/authorized_keys côté managed nodes.

L’empreinte de la clé (fingerprint) :

Fenêtre de terminal
ssh-keygen -lf ssh/id_ed25519.pub
256 SHA256:sablGxeVzXHyIR26fF6ZsWiGV9vkcKpUoMGFnCFGZhY ansible-lab@master1 (ED25519)

Notez ce fingerprint — il vous permettra plus tard de vérifier qu’une clé pub trouvée sur un managed node correspond bien à votre clé privée.

Deux scénarios selon votre situation.

Si le lab a été provisionné par make provision, la clé publique a déjà été injectée par cloud-init au démarrage de chaque VM. Vous n’avez rien à faire. Sautez à l’étape 4.

Vous pouvez vérifier côté managed node que l’authorized_keys est bien posé :

Fenêtre de terminal
ssh -i ssh/id_ed25519 ansible@10.10.20.21 'ls -la ~/.ssh/'
total 4
drwx------. 2 ansible ansible 29 Apr 25 14:34 .
drwx------. 3 ansible ansible 74 Apr 25 14:34 ..
-rw-------. 1 ansible ansible 101 Apr 25 14:34 authorized_keys

Les permissions 0700 sur ~/.ssh/ et 0600 sur authorized_keys sont strictement requises par OpenSSH — sinon la connexion par clé est refusée silencieusement.

Si vos managed nodes existent déjà (création manuelle, VMs Vagrant non re-provisionnées, hôtes physiques), distribuez la clé avec ssh-copy-id :

Fenêtre de terminal
ssh-copy-id -i ssh/id_ed25519.pub ansible@10.10.20.21

Au premier appel, le mot de passe du compte ansible est demandé une fois. La commande crée ~/.ssh/ avec les bonnes permissions et ajoute votre clé publique à authorized_keys.

À répéter sur chaque hôte cible, ou en boucle :

Fenêtre de terminal
for host in 10.10.20.21 10.10.20.22 10.10.20.31; do
ssh-copy-id -i ssh/id_ed25519.pub ansible@$host
done

Avant même de passer par Ansible, vérifiez que SSH fonctionne sur un seul hôte :

Fenêtre de terminal
ssh -i ssh/id_ed25519 ansible@10.10.20.21 'uptime; hostname'

Sortie attendue (sur le lab) :

14:38:14 up 4 min, 3 users, load average: 0.47, 0.19, 0.07
web1.lab

Aucune saisie de mot de passe : la clé Ed25519 a fait le travail. Si vous obtenez Permission denied (publickey), sautez à la section Dépannage ci-dessous.

Maintenant que SSH fonctionne, validez la chaîne inventaire + clé + sudo avec un ping Ansible :

Fenêtre de terminal
ansible all -m ping

Sortie attendue :

web1.lab | SUCCESS => {
"changed": false,
"ping": "pong"
}
db1.lab | SUCCESS => {
"changed": false,
"ping": "pong"
}
web2.lab | SUCCESS => {
"changed": false,
"ping": "pong"
}
control-node.lab | SUCCESS => {
"changed": false,
"ping": "pong"
}

4 pong sur les 4 hôtes — c’est le signal que tout est aligné : inventaire correct, clé SSH distribuée, Python 3 présent côté cible, compte ansible valide. Vous êtes prêt à exécuter des commandes réelles.

Étape 6 — Simplifier avec ~/.ssh/config (optionnel)

Section intitulée « Étape 6 — Simplifier avec ~/.ssh/config (optionnel) »

Sur une fleet existante (hors lab cloud-init), vous pouvez factoriser les options SSH dans ~/.ssh/config :

Host 10.10.20.* *.lab
User ansible
IdentityFile ~/Projets/ansible-training/ssh/id_ed25519
StrictHostKeyChecking accept-new
UserKnownHostsFile ~/.ssh/known_hosts.lab

Avec ce bloc, vous pouvez taper directement ssh web1.lab sans préciser -i ssh/id_ed25519 ni ansible@. Ansible consomme aussi cette config — c’est l’un des gros avantages de l’agentless sur SSH.

SymptômeCauseFix
Permission denied (publickey)Clé pub absente côté managed node, ou mauvaise clé pub injectéessh-copy-id ou regénérer le lab (make destroy && make bootstrap && make provision)
Permission denied même avec --ask-passCompte SSH inexistantVérifier le users: du cloud-init ; sur fleet existante : useradd ansible côté managed node
Permissions 0644 for 'ssh/id_ed25519' are too openClé privée trop permissivechmod 0600 ssh/id_ed25519
Host key verification failedLe fingerprint a changé (VM recréée)Nettoyer ~/.ssh/known_hosts (ou poser host_key_checking = False dans ansible.cfg)
sudo: a password is requiredLe compte n’a pas NOPASSWD dans /etc/sudoers.d/Vérifier le cloud-init ; ou poser become_ask_pass = True dans ansible.cfg (déconseillé)
Failed to connect to the host via ssh: Connection timed outFirewall ou hijacking par ~/.ssh/configssh -vvv pour voir l’IP cible réelle ; vérifier les règles firewalld côté managed node
MODULE FAILURE: No module named ansiblePython 3 absent côté managed nodeBootstrap via le module raw (cf. Préparer les nœuds gérés)
  • Une clé Ed25519 sans passphrase est la base d’un lab pédagogique ; sur production, utilisez une passphrase + ssh-agent.
  • La distribution de la clé pub se fait via cloud-init (lab fresh) ou ssh-copy-id (fleet existante).
  • Les permissions 0700 sur ~/.ssh/ et 0600 sur authorized_keys côté managed node sont strictement requises.
  • Le module ansible.builtin.ping valide la chaîne SSH + Python + transfert — pas un ping ICMP.
  • ~/.ssh/config factorise les options SSH ; Ansible les consomme directement.
  • Le hijacking par un Host 10.* trop large dans votre config SSH est le piège classique sur un poste qui sert à plusieurs labs.

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracing. Aujourd'hui, ce site ne couvre même pas mes frais d'hébergement, d'électricité, de matériel, de logiciels, mais surtout de cafés.

Un soutien régulier, même symbolique, m'aide à garder ces ressources gratuites et à continuer de produire des guides de qualité. Merci pour votre appui.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn