9

Sometimes I would like to use Ansible's lineinfile or blockinfile modules to write a password into some configuration file. If I do so, the whole line or block, password included, ends up in my syslog.

As I don't consider syslog to be a secure place to have my passwords stored in, how can I tell Ansible not to leak my password into syslog? I hope there is a way to do this, otherwise I would consider this to be a big security problem in Ansible.

You can reproduce it for example with this ad-hoc command:

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

Here is what ends up in 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

For the example I used Ansible 2.0.0.2 from the official Ansible Ubuntu PPA on a Debian "Jessie" 8 system.

3

The no_log attribute hides data in syslog. It can be applied to a single task

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

or the playbook:

- hosts: all
  no_log: True

Debugging is not really possible when activated so it is recommended to use it only for single tasks. This feature is available since version 1.5 of Ansible. As stated in the release announcement for the 1.5 release:

Tasks also can now take a "no_log=True" option to prevent sensitive tasks from hitting syslog. (Parameters that looked like passwords were already filtered)

passwords should be filtered in most cases.

  • This effectively hides the passwords from syslog but it disables the logging output in the console output at the same time. Is there any way to change that? – aef Feb 9 '16 at 9:46
  • I'm sorry. I found little information on this topic. I would suggest to set the attribute only for tasks and only once you debugged your play. As cited Ansible should already filter parameters that look like passwords. So maybe it is a bug. Again I don't know how Ansible determines if a parameter is a password. Maybe it is a bug / missing feature to hide password = XXX. – Henrik Pingel Feb 9 '16 at 9:53
  • Where did you get the impression that passwords are supposed to be hidden by default in Ansible? Is this mentioned somewhere in the documentation? – aef Feb 9 '16 at 12:15
  • Last quote in my answer (Parameters that looked like passwords were already filtered). But I haven't found any other source for that functionality – Henrik Pingel Feb 9 '16 at 12:26
3

I developped a callback plugin to hide passwords for default outputs, it parse ouput dictionary for key that contains password, for each of them, it replace value by ********.

Create a file named protect_data.py in folder ./plugins/callback add add this 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)

In file ansible.cfg:

  • uncomment line with stdout_callback and set this plugin name a value (stdout_callback=protect_data)
  • uncomment line with callback_plugins and set value ./plugins/callback

Output is only modified for this plugin, if you use another plugin to display output (logentries, ...), you have to do the same with it

  • Oh, wow, that's brilliant. However, this requires me to set a dict with key name 'password' for everything that contains a secret. I would have loved a meta flag to indicate a variable contains a secret instead, but thanks! Other Q: does this also mask the secrets in output with ansible-playbook --diff (file diff changes)? – gertvdijk Jul 5 '18 at 8:32
  • I don't know, I never tried – Nelson G. Jul 6 '18 at 8:57
-2

One might suggest that using Vault instead would obviate the problem.

  • This does not provide an answer to the question. Once you have sufficient reputation you will be able to comment on any post; instead, provide answers that don't require clarification from the asker. - From Review – chicks Feb 16 '18 at 2:58
  • Vault helps to encrypt data at rest, but when passwords are in use, they can easily appear in log files. – Konstantin Suvorov Feb 16 '18 at 6:38
  • @chicks This looks like a wrong answer, not a non-answer. – Michael Hampton Feb 16 '18 at 20:07
  • I did not see that option in the review tools. Since this is more like a comment than an answer I feel like I handled this reasonably. – chicks Feb 16 '18 at 20:15
  • My flag was also declined, and I still do not see how the above sentence is an answer about how to reduce Ansible verbosity. It is at most a comment suggesting another idea, certainly not an answer to the question. – Patrick Mevzek Feb 21 '18 at 1:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.