GNU/Linux >> Tutoriels Linux >  >> Linux

Authentification SSH Ansible et escalade des privilèges

Dans cet article, nous allons nous concentrer sur deux concepts Ansible importants. Le premier concept sera de savoir comment l'authentification basée sur la clé SSH et le mot de passe fonctionne dans Ansible. Le deuxième concept est de savoir comment élever le privilège lorsque vous travaillez avec des commandes ad hoc et des playbooks.

J'ai une configuration de laboratoire à trois nœuds exécutant des machines Ubuntu 20.04 LTS utilisant VirtualBox et Vagrant. Il existe un article détaillé sur la configuration du laboratoire que vous pouvez lire à partir du lien ci-dessous.

  • Configuration automatisée d'Ansible Lab avec Vagrant et Virtualbox sous Linux

Authentification basée sur une clé dans Ansible

La première chose que vous devez comprendre lors de l'apprentissage d'ansible est la manière dont la communication se passe 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 la tâche.

Chaque fois que vous exécutez un playbook ou des commandes ad hoc, vous devez fournir le mot de passe SSH pour qu'il 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 à l'aide de 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 pour la 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" [email protected]$val
done

Donnez l'autorisation d'exécution au script et exécutez-le.

$ chmod +x path/to/create_keypair.sh
$ ./create_keypair.sh

J'ai créé ce script pour la configuration de mon 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.pub

Lorsque vous avez des clés créées avec des noms différents autres que le nom par défaut (id_rsa), ssh essaiera de trouver les noms de clé par défaut et s'il ne les trouve pas, il 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
[email protected]'s password:

Dans ce cas, vous devez mentionner explicitement le fichier de clé privée en utilisant le -i drapeau.

$ ssh -v -i /home/vagrant/.ssh/first_key [email protected]

Lorsque vous exécutez une commande ad hoc ou un playbook, vous pouvez utiliser le --key-file ou --private-key flag et transmettez le fichier de clé privée comme 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 ansible.cfg fichier de configuration qui sera appliqué aux commandes ad hoc et à toutes les tâches du playbook.

$ vim ansible.cfg

Ajoutez la ligne suivante :

Private_key_file = /home/vagrant/.ssh/first_key

Remplacez /home/vagrant/.ssh/first_key avec le vôtre.

Vous pouvez également ajouter "ansible_ssh_private_key" paramètre dans votre fichier d'inventaire qui aura la priorité sur ansible.cfg dossier. Voici comment mon inventaire est maintenant configuré. Nœud géré1 utilisera "first_key" et géré2 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_key

Maintenant, si vous exécutez à nouveau la commande ad hoc 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 entrée.

$ ansible -vvv all -m ping

Vous devriez maintenant avoir une bonne compréhension du fonctionnement de l'authentification par clé dans ansible. Il est important de comprendre la priorité lors de l'ajout du paramètre dans différents fichiers. L'option de ligne de commande est prioritaire, suivie du fichier d'inventaire et de ansible.cfg fichier de configuration.

Authentification basée sur un mot de passe SSH dans Ansible

Lorsque vous exécutez une tâche, ansible utilisera l'utilisateur actuel dans le nœud du contrôleur pour communiquer avec les nœuds gérés via SSH. Vous pouvez utiliser le module shell et exécuter le "whoami " commande pour vérifier le nom d'utilisateur dans les nœuds gérés. Dans mon cas, le nom d'utilisateur est "vagrant" . L'utilisateur vagabond s'authentifie à l'aide 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 --u ou --user flag et passez nom d'utilisateur comme argument. Si vous voyez l'image ci-dessous, j'essaie d'utiliser l'utilisateur "karthick" qui n'a pas de configuration de clé SSH et aucune clé distribuée aux nœuds gérés, de sorte que la connectivité échoue.

$ ansible all -m shell -a "whoami" -u karthick
$ ansible all -m shell -a "whoami" --user karthick

Pour utiliser l'authentification par mot de passe, vous pouvez utiliser le -k ou --ask-pass drapeau. Il vous demandera d'entrer 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-pass

Vous pouvez également stocker le mot de passe dans un fichier et passer le nom du fichier comme argument à --connection-password-file ou --conn-pass-file drapeau. Ce n'est pas une méthode recommandée puisque vous stockez le mot de passe dans un fichier texte brut. Vous pouvez utiliser le coffre-fort ansible pour chiffrer le fichier de mot de passe, mais il s'agit d'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.txt

Vous pouvez également transmettre 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 >>
karthick

Attention : J'exécute peut-être les exemples à l'aide de commandes ad hoc, mais les mêmes indicateurs s'appliquent également au playbook.

Élévation des privilèges dans Ansible

Il arrive que votre tâche nécessite des privilèges élevés (racine) pour s'exécuter avec succès. Par exemple, la gestion des packages. Vous ne pouvez installer, supprimer ou mettre à jour des packages qu'en tant que root utilisateur ou avec sudo privilège.

Lorsque vous exécutez l'indicateur d'aide avec ansible ou ansible-playbook, vous trouverez une section d'escalade de privilèges, comme indiqué dans l'image.

$ ansible --help
$ ansible-playbook --help

Lorsque vous souhaitez exécuter une tâche avec root privilège, vous devez utiliser -b ou --become drapeau.

$ 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'escalade de privilèges. Vous pouvez changer la méthode en définissant le --become-method drapeau. 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 donner un sudo mot de passe pour les nœuds gérés en fonction de la configuration de l'utilisateur. Dans mon cas, j'ai configuré l'utilisateur vagrant pour exécuter sudo sans demander de mots de passe.

Si votre sudo l'utilisateur a besoin d'un mot de passe pour fonctionner, alors vous devez utiliser le -K ou --ask-become-pass drapeau qui demandera le sudo le mot de passe.

Comme vous pouvez le voir dans l'erreur ci-dessous, lorsque j'essaie de m'exécuter sans fournir de sudo mot de passe pour l'utilisateur "karthick", il me renvoie une erreur disant "Missing sudo password" .

$ 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 -K

Le mot de passe Sudo peut être stocké dans un fichier et passé en argument au --become-password-file ou --become-pass-file drapeau. Le coffre-fort Ansible 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.txt

Vous pouvez également inclure le "devenir" directive dans le playbook au niveau de la tâche ou du jeu.

L'image ci-dessous représente comment le "devient" la directive est utilisée au niveau de lecture .

L'image ci-dessous représente comment le "devient" la directive est utilisée au niveau de la tâche .

Comme vous pouvez le voir sur la sortie, le ssh le service est bien redémarré dans le managed1 nœud.

$ 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 ansible.cfg fichier de configuration et 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 ansible.cfg fichier à partir du lien ci-dessous.

  • Devenir directif

Si vous souhaitez 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 --become-user drapeau. Par défaut, il est défini sur root utilisateur.

Conclusion

Dans cet article, nous avons vu comment fonctionne l'authentification par clé et par mot de passe dans Ansible et les différents indicateurs pris en charge pour l'authentification. Nous avons également vu comment fonctionne l'escalade de privilèges dans Ansible.

Pour approfondir, vous devez avoir une bonne compréhension du fonctionnement des différentes méthodes d'escalade de privilèges et, en fonction de vos besoins, définir l'environnement sans compromettre la sécurité.

Lire la suite :

  • Premiers pas avec les commandes ad hoc Ansible

Linux
  1. Comment Linux gère-t-il plusieurs séparateurs de chemins consécutifs (/home////nom d'utilisateur///fichier) ?

  2. Debian – Déplacer /var, /home vers une partition séparée ?

  3. Comment changer les points de montage ?

  4. Linux :Différence entre /dev/console , /dev/tty et /dev/tty0

  5. Les sites Web doivent-ils vivre dans /var/ ou /usr/ selon l'utilisation recommandée ?

Linux :Différence entre /dev/console , /dev/tty et /dev/tty0 ?

Bash =~ Regex et Https://regex101.com/?

Quelle est la portabilité de /dev/stdin, /dev/stdout et /dev/stderr ?

Ssh ne fonctionne pas à partir d'un ordinateur spécifique ?

"Impossible de créer un répertoire de cache /home//.composer/cache/repo/https—packagist.org/, ou le répertoire n'est pas accessible en écriture. Procéder sans cache ?

Comprendre les fichiers /proc/mounts, /etc/mtab et /proc/partitions