Comment puis-je réduire la verbosité de certaines tâches Ansible pour ne pas divulguer les mots de passe dans syslog?

11

Parfois, je voudrais utiliser Ansible lineinfileou des blockinfilemodules pour écrire un mot de passe dans un fichier de configuration. Si je le fais, toute la ligne ou le bloc, mot de passe inclus, se retrouve dans mon syslog.

Comme je ne considère syslogpas être un endroit sûr pour stocker mes mots de passe, comment puis-je dire à Ansible de ne pas divulguer mon mot de passe syslog? J'espère qu'il existe un moyen de le faire, sinon je considérerais cela comme un gros problème de sécurité dans Ansible.

Vous pouvez le reproduire par exemple avec cette commande ad-hoc:

ansible localhost -m blockinfile -a 'dest=/tmp/ansible_password_leak create=yes block="Password = {{password}}"' -e 'password=secret'

Voici ce qui finit par syslog:

ansible-blockinfile: Invoked with directory_mode=None force=None remote_src=None insertafter=None owner=None follow=False marker=# {mark} ANSIBLE MANAGED BLOCK group=None insertbefore=None create=True setype=None content=None serole=None state=present dest=/tmp/ansible_password_leak selevel=None regexp=None validate=None src=None seuser=None delimiter=None mode=None backup=False block=Password = secret

Pour l'exemple, j'ai utilisé Ansible 2.0.0.2 du PPA officiel d'Ansible Ubuntu sur un système Debian "Jessie" 8.

aef
la source

Réponses:

3

L' no_log attribut masque les données dans syslog. Il peut être appliqué à une seule tâche

- name: secret task
  shell: /usr/bin/do_something --value={{ secret_value }}
  no_log: True

ou le playbook:

- hosts: all
  no_log: True

Le débogage n'est pas vraiment possible lorsqu'il est activé, il est donc recommandé de ne l'utiliser que pour des tâches uniques. Cette fonctionnalité est disponible depuis la version 1.5 d' Ansible . Comme indiqué dans l'annonce de la version 1.5:

Les tâches peuvent désormais également prendre une option "no_log = True" pour empêcher les tâches sensibles de frapper syslog. (Les paramètres qui ressemblaient à des mots de passe ont déjà été filtrés)

les mots de passe doivent être filtrés dans la plupart des cas.

Henrik Pingel
la source
Cela masque efficacement les mots de passe syslogmais désactive la sortie de journalisation dans la sortie de la console en même temps. Y a-t-il un moyen de changer cela?
aef
Je suis désolé. J'ai trouvé peu d'informations sur ce sujet. Je suggère de définir l'attribut uniquement pour les tâches et uniquement une fois que vous avez débogué votre jeu. Comme indiqué, Ansible devrait déjà filtrer les paramètres qui ressemblent à des mots de passe. C'est peut-être un bug. Encore une fois, je ne sais pas comment Ansible détermine si un paramètre est un mot de passe. C'est peut-être un bug / une fonction manquante à cacher password = XXX.
Henrik Pingel
Où avez-vous eu l'impression que les mots de passe sont censés être cachés par défaut dans Ansible? Est-ce mentionné quelque part dans la documentation?
aef
Dernière citation dans ma réponse (les paramètres qui ressemblaient à des mots de passe étaient déjà filtrés). Mais je n'ai trouvé aucune autre source pour cette fonctionnalité
Henrik Pingel
3

J'ai développé un plugin de rappel pour cacher les mots de passe pour les sorties par défaut, il analyse le dictionnaire de sortie pour la clé qui contient le mot de passe , pour chacun d'eux, il remplace la valeur par ********.

Créez un fichier nommé protect_data.pydans le dossier ./plugins/callback add ajoutez ce code:

from ansible.plugins.callback.default import CallbackModule as CallbackModule_default
import os, collections

class CallbackModule(CallbackModule_default):
    CALLBACK_VERSION = 2.0
    CALLBACK_TYPE = 'stdout'
    CALLBACK_NAME = 'protect_data'

    def __init__(self, display=None):
        super(CallbackModule, self).__init__(display)

    def hide_password(self, result):
        ret = {}
        for key, value in result.iteritems():
            if isinstance(value, collections.Mapping):
                ret[key] = self.hide_password(value)
            else:
                if "password" in key:
                    ret[key] = "********"
                else:
                    ret[key] = value
        return ret

    def _dump_results(self, result, indent=None, sort_keys=True, keep_invocation=False):
        return super(CallbackModule, self)._dump_results(self.hide_password(result), indent, sort_keys, keep_invocation)

Dans le fichier ansible.cfg :

  • décommenter la ligne avec stdout_callbacket définir ce nom de plugin une valeur ( stdout_callback=protect_data)
  • décommenter la ligne avec callback_pluginset définir la valeur./plugins/callback

La sortie n'est modifiée que pour ce plugin, si vous utilisez un autre plugin pour afficher la sortie ( logentries, ...), vous devez en faire de même

Nelson G.
la source
Oh, wow, c'est génial. Cependant, cela m'oblige à définir un dict avec le nom de clé «mot de passe» pour tout ce qui contient un secret. J'aurais aimé un méta-drapeau pour indiquer qu'une variable contient un secret à la place, mais merci! Autre Q: cela masque-t-il également les secrets de la sortie avec ansible-playbook --diff(modifications des différences de fichier)?
gertvdijk
Je ne sais pas, je n'ai jamais essayé
Nelson G.
-3

On pourrait suggérer que l'utilisation de Vault à la place permettrait d'éviter le problème.

user19151
la source
Cela ne fournit pas de réponse à la question. Une fois que vous avez une réputation suffisante, vous pourrez commenter n'importe quel message ; fournissez plutôt des réponses qui ne nécessitent pas de clarification de la part du demandeur . - De l'avis
chicks
1
Vault permet de crypter les données au repos, mais lorsque des mots de passe sont utilisés, ils peuvent facilement apparaître dans les fichiers journaux.
Konstantin Suvorov
@chicks Cela ressemble à une mauvaise réponse , pas à une non-réponse .
Michael Hampton
Je n'ai pas vu cette option dans les outils d'examen. Comme cela ressemble plus à un commentaire qu'à une réponse, j'ai l'impression d'avoir géré cela raisonnablement.
poussins
Mon indicateur a également été refusé, et je ne vois toujours pas en quoi la phrase ci-dessus est une réponse sur la façon de réduire la verbosité d' Ansible . C'est tout au plus un commentaire suggérant une autre idée, certainement pas une réponse à la question.
Patrick Mevzek