Authentification SSH et escalade de privilèges Ansible
Dans cet article, nous allons nous concentrer sur deux concepts importants d'Ansible. Le premier concept sera comment fonctionne l'authentification par clé SSH et par mot de passe dans Ansible. Le deuxième concept est comment élever les privilèges lors de l'utilisation de commandes ad hoc et de playbooks.
J'ai un environnement de laboratoire à trois nœuds fonctionnant sur des machines Ubuntu 20.04 LTS utilisant VirtualBox et Vagrant. Il y a un article détaillé sur la configuration du laboratoire que vous pouvez lire via le lien ci-dessous.
- Configuration automatisée d'un laboratoire Ansible avec Vagrant et VirtualBox sous Linux
Authentification par clé dans Ansible
La première chose que vous devez comprendre lorsque vous apprenez Ansible est la manière dont la communication se fait entre le contrôleur et les nœuds gérés. Ansible utilise le protocole SSH pour se connecter aux nœuds gérés et exécuter les tâches.
Chaque fois que vous exécutez un playbook ou des commandes ad hoc, vous devez fournir le mot de passe SSH pour qu'Ansible puisse s'authentifier auprès des nœuds gérés via SSH.
Pour éliminer cela, il est recommandé de créer une paire de clés SSH et de partager la clé publique avec tous les nœuds afin qu'Ansible puisse communiquer en utilisant la paire de clés.
J'ai créé deux paires de clés nommées first_key et second_key en utilisant le script ci-dessous à des fins de démonstration.
Créez un fichier texte appelé create_keypair.sh avec le contenu suivant.
#!/usr/bin/env bash
# THIS SCRIPT WILL CREATE SSH KEY PAIR AND DISTRIBUTE ACROSS ALL NODES
read -p "Enter the name for the key : " KEY_NAME
ssh-keygen -b 2048 -t rsa -f /home/vagrant/.ssh/${KEY_NAME} -q -N ""
# LOOPING THROUGH AND DISTRIBUTING THE KEY
for val in controller managed1 managed2; do
echo "-------------------- COPYING KEY TO ${val^^} NODE ------------------------------"
sshpass -p 'vagrant' ssh-copy-id -f -i /home/vagrant/.ssh/${KEY_NAME}.pub -o "StrictHostKeyChecking=no" vagrant@$val
doneDonnez la permission d'exécution au script et exécutez-le.
$ chmod +x path/to/create_keypair.sh$ ./create_keypair.shJ'ai créé ce script pour ma configuration de laboratoire. Vous pouvez modifier la section de la boucle for et ajouter vos noms de nœuds gérés en conséquence.
$ tree .ssh/
.ssh/
├── authorized_keys
├── first_key
├── first_key.pub
├── known_hosts
├── second_key
└── second_key.pubLorsque vous avez des clés créées avec des noms différents du nom par défaut (id_rsa), ssh essaiera de trouver les noms de clés par défaut et, si elle n'est pas trouvée, elle demandera une authentification par mot de passe.
debug1: SSH2_MSG_SERVICE_ACCEPT received
debug1: Authentications that can continue: publickey,password
debug1: Next authentication method: publickey
debug1: Trying private key: /home/vagrant/.ssh/id_rsa
debug1: Trying private key: /home/vagrant/.ssh/id_dsa
debug1: Trying private key: /home/vagrant/.ssh/id_ecdsa
debug1: Trying private key: /home/vagrant/.ssh/id_ecdsa_sk
debug1: Trying private key: /home/vagrant/.ssh/id_ed25519
debug1: Trying private key: /home/vagrant/.ssh/id_ed25519_sk
debug1: Trying private key: /home/vagrant/.ssh/id_xmss
debug1: Next authentication method: password
vagrant@managed1's password:Dans ce cas, vous devez mentionner explicitement le fichier de clé privée en utilisant le paramètre -i.
$ ssh -v -i /home/vagrant/.ssh/first_key vagrant@managed1Lorsque vous exécutez une commande ad hoc ou un playbook, vous pouvez utiliser l'option --key-file ou --private-key et passer le fichier de clé privée en argument. Dans l'exemple ci-dessous, vous pouvez voir que j'ai utilisé les deux clés (first_key et second_key) pour communiquer avec succès avec les nœuds gérés.
# USING --key-file FLAG
$ ansible managed1 -m ping --key-file /home/vagrant/.ssh/second_key
managed1 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false,
"ping": "pong"
}# USING --private-key FLAG
$ ansible managed1 -m ping --private-key /home/vagrant/.ssh/first_key
managed1 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false,
"ping": "pong"
}Vous pouvez également ajouter le paramètre « private_key_file » dans le fichier de configuration ansible.cfg, qui sera appliqué aux commandes adhoc et à toutes les tâches du playbook.
$ vim ansible.cfgAjoutez la ligne suivante :
Private_key_file = /home/vagrant/.ssh/first_keyRemplacez /home/vagrant/.ssh/first_key par le vôtre.
Vous pouvez également ajouter le paramètre "ansible_ssh_private_key" dans votre fichier d'inventaire, ce qui aura une priorité plus élevée que le fichier ansible.cfg. Ci-dessous est comment mon inventaire est maintenant configuré. Le nœud managed1 utilisera "first_key" et managed2 utilisera "second_key".
[ubuntu1]
managed1 ansible_ssh_private_key_file=/home/vagrant/.ssh/first_key
[ubuntu2]
managed2 ansible_ssh_private_key_file=/home/vagrant/.ssh/second_keyMaintenant, si vous exécutez à nouveau la commande adhoc ou le playbook, vous pouvez voir que les deux clés s'authentifieront avec succès. Vous pouvez augmenter la verbosité pour vérifier si les clés appropriées sont utilisées conformément à notre saisie.
$ ansible -vvv all -m pingVous devriez maintenant avoir une bonne compréhension de la façon dont l'authentification par clé fonctionne dans Ansible. Il est important de comprendre la priorité lors de l'ajout du paramètre dans différents fichiers. L'option en ligne de commande a une priorité plus élevée, suivie du fichier d'inventaire et du fichier de configuration ansible.cfg.
Authentification par mot de passe SSH dans Ansible
Lorsque vous exécutez une tâche, Ansible utilisera l'utilisateur actuel sur le nœud contrôleur pour communiquer avec les nœuds gérés via SSH. Vous pouvez utiliser le module shell et exécuter la commande "whoami" pour vérifier le nom d'utilisateur sur les nœuds gérés. Dans mon cas, le nom d'utilisateur est "vagrant". L'utilisateur vagrant s'authentifie en utilisant des clés que j'ai configurées dans la section précédente.
$ whoami
vagrant$ ansible all -m shell -a "whoami"
managed2 | CHANGED | rc=0 >>
vagrant
managed1 | CHANGED | rc=0 >>
vagrant
Si vous souhaitez vous connecter aux nœuds gérés en tant qu'utilisateur différent, vous pouvez utiliser l'option --u ou --user et passer le nom d'utilisateur en argument. Si vous regardez l'image ci-dessous, j'essaie d'utiliser l'utilisateur "karthick" qui n'a pas de clé SSH configurée et aucune clé distribuée aux nœuds gérés, donc la connexion échoue.
$ ansible all -m shell -a "whoami" -u karthick
$ ansible all -m shell -a "whoami" --user karthickPour utiliser l'authentification basée sur le mot de passe, vous pouvez utiliser l'option -k ou --ask-pass. Cela vous demandera de saisir le mot de passe SSH pour l'utilisateur (karthick). Assurez-vous que le mot de passe est le même sur tous les nœuds pour l'utilisateur.
$ ansible all -m shell -a "whoami" -u karthick -k
$ ansible all -m shell -a "whoami" -u karthick --ask-passVous pouvez également stocker le mot de passe dans un fichier et passer le nom du fichier comme argument à l'option --connection-password-file ou --conn-pass-file. Ce n'est pas une méthode recommandée car vous stockez le mot de passe dans un fichier en texte clair. Vous pouvez utiliser Ansible Vault pour chiffrer le fichier de mot de passe, mais c'est un sujet distinct à discuter.
$ ansible all -m shell -a "whoami" -u karthick --connection-password-file pass.txt
$ ansible all -m shell -a "whoami" -u karthick --conn-pass-file pass.txtVous pouvez également passer le nom d'utilisateur et le mot de passe en tant que paramètres dans le fichier d'inventaire. Encore une fois, ce n'est pas la meilleure façon de stocker le mot de passe. Voici comment mon fichier d'inventaire est maintenant configuré.
[ubuntu1]
managed1 ansible_ssh_private_key_file=/home/vagrant/.ssh/first_key ansible_user=vagrant
[ubuntu2]
managed2 ansible_user=karthick ansible_ssh_pass=password$ ansible all -m shell -a "whoami" -u karthick
managed1 | CHANGED | rc=0 >>
vagrant
managed2 | CHANGED | rc=0 >>
karthickAttention : Je peux exécuter les exemples en utilisant des commandes ad hoc, mais les mêmes options sont également applicables au playbook.
Élévation de privilèges dans Ansible
Il y a des moments où votre tâche nécessite des privilèges élevés (root) pour s'exécuter avec succès. Par exemple, la gestion des paquets. Vous ne pouvez installer, supprimer ou mettre à jour des paquets qu'en tant qu'utilisateur root ou avec des privilèges sudo.
Lorsque vous exécutez l'option d'aide avec ansible ou ansible-playbook, vous trouverez une section sur l'escalade de privilèges comme montré sur l'image.
$ ansible --help
$ ansible-playbook --helpLorsque vous souhaitez exécuter une tâche avec les privilèges root, vous devez utiliser le drapeau -b ou --become.
$ ansible ubuntu1 -m service -a "name=sshd state=restarted" -b
managed1 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": true,
"name": "sshd",
"state": "started",Par défaut, sudo sera utilisé comme méthode d'élévation de privilèges. Vous pouvez changer la méthode en définissant l'option --become-method. Vous pouvez obtenir la liste des méthodes prises en charge en exécutant la commande suivante.
$ ansible-doc -t become -l
ansible.netcommon.enable Switch to elevated permissions on a network device
community.general.doas Do As user
community.general.dzdo Centrify's Direct Authorize
community.general.ksu Kerberos substitute user
community.general.machinectl Systemd's machinectl privilege escalation
community.general.pbrun PowerBroker run
community.general.pfexec profile based execution
community.general.pmrun Privilege Manager run
community.general.sesu CA Privileged Access Manager
community.general.sudosu Run tasks using sudo su -
runas Run As user
su Substitute User
sudo Substitute User DO Vous pouvez ou non fournir un mot de passe sudo pour les nœuds gérés en fonction de la façon dont l'utilisateur est configuré. Dans mon cas, j'ai configuré l'utilisateur vagrant pour exécuter sudo sans demander de mot de passe.
Si votre utilisateur sudo nécessite un mot de passe pour fonctionner, vous devez alors utiliser l'option -K ou --ask-become-pass qui demandera le mot de passe sudo.
Comme vous pouvez le voir dans l'erreur ci-dessous, lorsque j'essaie d'exécuter sans fournir de mot de passe sudo pour l'utilisateur "karthick", cela me donne une erreur disant "Mot de passe sudo manquant".
$ ansible ubuntu1 -m service -a "name=sshd state=restarted" -i inventory -u karthick -k -b
SSH password:
managed1 | FAILED! => {
"msg": "Missing sudo password"
}$ ansible ubuntu1 -m service -a "name=sshd state=restarted" -i inventory -u karthick -k -b -KLe mot de passe sudo peut être stocké dans un fichier et passé comme argument aux options --become-password-file ou --become-pass-file. Ansible Vault peut être utilisé pour chiffrer ce fichier mais ce n'est pas une pratique recommandée.
$ ansible ubuntu1 -m service -a "name=sshd state=restarted" -i inventory -u karthick -k -b --become-password-file pass.txt
$ ansible ubuntu1 -m service -a "name=sshd state=restarted" -i inventory -u karthick -k -b --become-pass-file pass.txtVous pouvez également inclure la directive « become » dans le playbook au niveau de la tâche ou du play.
L'image ci-dessous montre comment la directive "become" est utilisée au niveau du play.
L'image ci-dessous représente comment la directive "become" est utilisée au niveau de la tâche.
Comme vous pouvez le voir à partir de la sortie, le service ssh est redémarré correctement sur le nœud managed1.
$ ansible-playbook restart_service.yml
PLAY [Restart SSHD service] ***************************************************************************
TASK [Restart SSHD in managed1.anslab.com] ************************************************************
changed: [managed1]
PLAY RECAP ********************************************************************************************
managed1 : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 La directive "become" peut également être définie dans le fichier de configuration ansible.cfg et dans le fichier d'inventaire. Mais il est recommandé de définir la directive dans le playbook. Vous pouvez obtenir les différents paramètres pour le fichier ansible.cfg à partir du lien ci-dessous.
- Devenir directif
Si vous voulez exécuter la tâche en tant qu'utilisateur différent après vous être connecté aux nœuds gérés, vous devez utiliser le paramètre --become-user. Par défaut, il est défini sur l'utilisateur root.
Conclusion
Dans cet article, nous avons vu comment fonctionne l'authentification par clé et par mot de passe dans Ansible ainsi que les différents indicateurs pris en charge pour l'authentification. Nous avons également vu comment fonctionne l'élévation de privilèges dans Ansible.
Pour plonger en profondeur, vous devriez avoir une bonne compréhension de la façon dont fonctionnent les différentes méthodes d'escalade de privilèges et, selon vos besoins, configurer l'environnement sans compromettre la sécurité.
Lire ensuite :
- Commencer avec les commandes Ansible Ad Hoc







