GNU/Linux >> Tutoriels Linux >  >> Linux

Gérer les secrets dans vos playbooks Ansible

C'est finalement arrivé. Vous avez opté pour Ansible. Vous avez lu tous les excellents articles, vu les cas d'utilisation et êtes ravi de commencer à créer une infrastructure reproductible et à gérer votre configuration en tant que code. Il n'y a qu'un seul problème :vous avez un fichier de configuration ou une tâche qui nécessite un mot de passe ou une autre information essentielle à la mission. Vous savez que vous ne devez pas stocker le mot de passe dans vos fichiers en clair, vous ne savez donc pas exactement où il doit aller.

N'ayez crainte, cet article vous guide à travers les différentes options de gestion des informations sensibles dans vos playbooks. Que vous recherchiez des solutions simples, telles que demander à un administrateur de saisir un mot de passe, ou des options plus complexes, telles que l'intégration à un environnement de gestion des secrets existant, Ansible est là pour vous.

[ Vous pourriez également apprécier : Démystifier Ansible pour les administrateurs système Linux ]

Invites

Si vous commencez tout juste votre parcours Ansible et que vous exécutez tous vos playbooks manuellement, l'utilisation d'une invite interactive directement dans votre playbook est une solution simple. Une invite amène Ansible à demander à l'utilisateur les variables souhaitées et à les stocker à chaque exécution d'un playbook. Considérez le playbook suivant, qui garantit qu'une clé API existe dans un fichier de configuration :

---

- hosts: all
  gather_facts: false
  vars_prompt:
    - name: api_key
      prompt: Enter the API key
  tasks:
    - name: Ensure API key is present in config file
      ansible.builtin.lineinfile:
        path: /etc/app/configuration.ini
        line: "API_KEY={{ api_key }}"

Lorsque j'exécute ce playbook, Ansible m'invite sur la ligne de commande en utilisant le message dans le paramètre prompt :

# ansible-playbook -i inventory.ini main.yml
Enter the API key:

L'entrée fournie à la ligne de commande sera stockée dans api_key variable, qui peut ensuite être utilisée dans le jeu comme n'importe quelle variable normale.

Bien que les invites variables soient faciles à mettre en œuvre, vous les dépasserez si vous investissez dans l'utilisation d'Ansible pour une gestion complète de la configuration. Au fur et à mesure que votre gestion de configuration mûrit, vous commencerez à exécuter des playbooks de manière non interactive et il n'y aura personne devant le terminal pour saisir les mots de passe. C'est là qu'Ansible Vault entre en jeu.

Vault Ansible

L'une de mes capacités Ansible préférées est Ansible Vault, qui fournit des capacités de chiffrement de contenu natif. Ansible Vault peut chiffrer et déchiffrer des variables et des fichiers arbitraires, ce qui signifie que vous pouvez l'utiliser pour protéger des fichiers de variables contenant des secrets ou même chiffrer des fichiers de configuration sensibles entiers. Ansible Vaults possède de nombreuses fonctionnalités avancées, mais cet article se concentrera sur les bases.

Les fichiers YAML standard contenant des secrets en clair peuvent être facilement chiffrés avec le ansible-vault encrypt commande :

# Plaintext YAML file
$ cat secrets_file.enc
api_key: SuperSecretPassword

# Encrypt the file with ansible-vault
$ ansible-vault encrypt secrets_file.enc
New Vault password:
Confirm New Vault password:
Encryption successful

# Confirm that the file now contains encrypted content
$ cat secrets_file.enc
$ANSIBLE_VAULT;1.1;AES256
38396162626134393935663839666463306231653861336630613938303662633538633836656465
3637353766613339663032363538626430316135623665340a653961303730353962386134393162
62343936366265353935346336643865643833353737613962643539373230616239346133653464
6435353361373263640a376632613336366430663761363339333737386637383961363833303830
34336535623736313031313162353831666139343662653665366134633832646661

Lorsque j'exécute mon playbook, je peux transmettre le fichier de variables cryptées et dire à Ansible de me demander le mot de passe. Ansible déchiffrera le fichier et utilisera les variables que j'ai définies, comme si j'avais transmis un fichier de variables normal :

$ cat main.yml
---

- hosts: all
  gather_facts: false
  tasks:
    - name: Ensure API key is present in config file
      ansible.builtin.lineinfile:
        path: /etc/app/configuration.ini
        line: "API_KEY={{ api_key }}"


$ ansible-playbook -i inventory.ini -e @secrets_file.enc --ask-vault-pass main.yml
Vault password:

PLAY [all] ***********************************************************************************

TASK [Ensure API key is present in config file] **********************************************
changed: [localhost]

PLAY RECAP ***********************************************************************************
localhost                  : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

$ cat /etc/app/configuration.ini
API_KEY=SuperSecretPassword

J'ai décrit précédemment pourquoi utiliser un vars_prompt n'est pas idéal dans un environnement automatisé car il nécessite une intervention manuelle de l'utilisateur. Alors, en quoi Ansible Vault est-il différent ? Ansible Vault vous permet de spécifier un fichier de mot de passe contenant le mot de passe de déchiffrement pour le coffre :

$ cat password_file 
password

$ ansible-playbook -i inventory.ini -e @secrets_file.enc --vault-password-file password_file main.yml

PLAY [all] ***********************************************************************************

TASK [Ensure API key is present in config file] **********************************************
changed: [localhost]

PLAY RECAP ***********************************************************************************
localhost                  : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 

Assurez-vous de définir les autorisations appropriées sur le fichier de mot de passe de déchiffrement afin que seul l'utilisateur exécutant le playbook puisse y accéder. Vous pouvez également envisager d'utiliser un script pour accéder au mot de passe lors de l'exécution à partir d'un système de stockage de mot de passe externe.

Maintenant que mon fichier variable est crypté, j'ai besoin d'un moyen de le modifier. Il existe deux façons de modifier un Ansible Vault chiffré. Vous pouvez soit modifier le fichier sur place, soit le déchiffrer entièrement, le modifier, puis le rechiffrer. Les deux méthodes sont présentées ci-dessous.

# The edit command will launch a text editor, such as vim
$ ansible-vault edit secrets_file.enc 
Vault password: 

# The decrypt command will fully decrypt the file, allowing you to manipulate it how you see fit.
$ ansible-vault decrypt secrets_file.enc 
Vault password: 
Decryption successful

# Notice that the file has been decrypted
$ cat secrets_file.enc 
api_key: SuperSecretPassword

# Don't forget to re-encrypt the file when you're done!
$ ansible-vault encrypt secrets_file.enc 
New Vault password: 
Confirm New Vault password: 
Encryption successful
$ cat secrets_file.enc 
$ANSIBLE_VAULT;1.1;AES256
33373832393864613335393836616538373639353538306462366464303939303838316337336662
6235303936636465366363643761383462356335336239640a356161653166643134663762323136
34616431303434646338343265666135666263633162383662323164396266616638313936303863
3337626365313666630a326465663239653731613637303437666164346531636361653837326166
34396232623138616364393130303036653564643435636639316264636531336161

L'utilisation d'un coffre-fort Ansible pour les secrets est l'une de mes méthodes préférées de stockage de données sensibles. L'avantage de cette approche est que vous pouvez réellement stocker vos données sensibles dans le contrôle des sources, côte à côte avec vos playbooks habituels. Étant donné que ces fichiers sont cryptés, il y a peu de risques dans cette approche tant que vous choisissez un mot de passe fort. Comme tout secret partagé, c'est une bonne idée de changer fréquemment le mot de passe de cryptage. Ansible propose également plusieurs fonctionnalités avancées pour les coffres, telles que la possibilité d'avoir différents mots de passe pour différents coffres. Assurez-vous de consulter la documentation pour découvrir d'excellents moyens de sécuriser vos secrets à l'aide des fonctionnalités natives d'Ansible.

Utiliser un gestionnaire de mots de passe existant

Les deux approches précédentes sont des approches purement Ansible pour aborder la gestion des secrets. Cependant, de nombreuses organisations disposent déjà d'outils, tels que HashiCorp Vault ou Thycotic Secret Server. La communauté Ansible a écrit un certain nombre de modules personnalisés pour interagir avec ces types de systèmes.

Le playbook suivant utilise une recherche pour obtenir un secret de HashiCorp Vault, puis utilise ce secret dans une tâche :


---

- hosts: all
  gather_facts: false
  tasks:
    - name: Ensure API key is present in config file
      ansible.builtin.lineinfile:
        path: /etc/app/configuration.ini
        line: "API_KEY={{ lookup('hashi_vault', 'secret=config-secrets/data/app/api-key:data token=s.FOmpGEHjzSdxGixLNi0AkdA7 url=http://localhost:8201')['key'] }}"

Vous pouvez trouver une variété de plugins pour différents outils de gestion de secrets sur Ansible Galaxy. Comme pour tout projet soutenu par la communauté, il est judicieux d'auditer le code afin de comprendre comment il gère vos données et vos secrets. Vous voudrez peut-être même écrire le vôtre.

L'utilisation d'un plug-in ou d'un module de recherche convient parfaitement aux organisations qui disposent déjà d'un outil de gestion des secrets mature et qui souhaitent simplement qu'Ansible utilise les secrets de ce système existant. Le compromis évident est la simplicité réduite :les exécutions de Playbook dépendent désormais de la disponibilité d'un système externe, et s'appuyer sur un module pris en charge par la communauté (ou écrire le vôtre) peut prendre du temps.

Remarque sur la journalisation

Il est important de se rappeler que le chiffrement des données au repos (par exemple, dans un coffre-fort Ansible ou un système de secrets externes) ne signifie pas que les données sont protégées contre la sortie accidentelle dans un fichier journal Ansible. Si le module que vous appelez enregistre votre secret pendant ses opérations normales ou lorsqu'une erreur se produit, ce secret peut être exposé dans vos fichiers journaux. Que vous stockiez ces journaux dans un système central ou que vous utilisiez simplement la vue de sortie standard par défaut, il est important de protéger vos secrets contre toute exposition accidentelle.

La sortie ci-dessous provient du même playbook Ansible que j'ai utilisé pour ce didacticiel. Cependant, j'ai augmenté le niveau de débogage d'Ansible avec -vvv . Notez que mon secret (API_KEY=SuperSecretPassword ) est directement exposé dans la sortie de débogage. J'ai un peu nettoyé cet extrait, alors ne vous inquiétez pas si vous essayez ceci, et votre sortie semble légèrement différente.

TASK [Ensure API key is present in config file] ***********************************************************************************************************************************************
fatal: [localhost]: FAILED! => changed=false 
  ansible_facts:
    discovered_interpreter_python: /usr/bin/python
  invocation:
    module_args:
      attributes: null
      backrefs: false
      backup: false
      content: null
      create: false
      delimiter: null
      directory_mode: null
      firstmatch: false
      follow: false
      force: null
      group: null
      insertafter: null
      insertbefore: null
      line: API_KEY=SuperSecretPassword
      mode: null
      owner: null
      path: /etc/app/configuration.ini
      regexp: null
      remote_src: null
      selevel: null
      serole: null
      setype: null
      seuser: null
      src: null
      state: present
      unsafe_writes: null
      validate: null
  msg: Destination /etc/app/configuration.ini does not exist !
  rc: 257

Ce n'est certainement pas idéal :mon secret est là, bien en vue. Heureusement, Ansible fournit un paramètre no_log pour les tâches qui protège les données sensibles :

---

- hosts: all
  gather_facts: false
  tasks:
    - name: Ensure API key is present in config file
      ansible.builtin.lineinfile:
        path: /etc/app/configuration.ini
        line: "API_KEY={{ api_key }}"
      no_log: True

En ajoutant ce paramètre à la tâche qui interagit avec les données sensibles, la sortie de la tâche ayant échoué est supprimée et la confidentialité de mon secret est préservée :

TASK [Ensure API key is present in config file] ***********************************************************************************************************************************************
fatal: [localhost]: FAILED! => changed=false 
  censored: 'the output has been hidden due to the fact that ''no_log: true'' was specified for this result'

C'est une bonne idée d'utiliser no_log sur toute tâche qui interagit avec des données sensibles. Vous devez également être conscient de ses limites :cela n'empêchera pas la journalisation si le débogage Ansible est activé.

[ Vous souhaitez en savoir plus sur l'automatisation du système ? Démarrez avec The Automated Enterprise, un livre gratuit de Red Hat. ] 

Réflexions finales

La gestion correcte des secrets est un premier défi commun auquel de nombreux administrateurs système sont confrontés lorsqu'ils travaillent sur le déploiement de l'automatisation. Dans cet article, j'ai décrit et démontré trois méthodes différentes que vous pouvez utiliser pour protéger les données sensibles lors de l'utilisation d'Ansible dans votre environnement. Cet article n'a fait qu'effleurer la surface des possibilités, alors assurez-vous de consulter la documentation que j'ai liée tout au long de cette discussion. La sécurité est l'affaire de tous. En tant qu'administrateur système, vous pouvez faire votre part en vous assurant que vous traitez les données privées avec la sensibilité qu'elles méritent dans vos pipelines d'automatisation.


Linux
  1. Guide Ansible :Gérer les fichiers à l'aide d'Ansible

  2. Huit façons de protéger l'accès SSH sur votre système

  3. 6 compétences de dépannage pour les playbooks Ansible

  4. Configurez votre démon Chrony avec un playbook Ansible

  5. Comment modifier votre fichier Hosts dans Windows 10

Premiers pas avec les commandes ansibles ad hoc

Fichiers d'inventaire et de configuration Ansible

Une brève introduction à Ansible Vault

Choisissez le meilleur système de fichiers pour votre Linux

RHCE Ansible Series #3 :Playbooks Ansible

RHCE Ansible Series #12 :Dépannage Ansible