Назад | Перейти на главную страницу

Как я могу уменьшить многословие некоторых задач Ansible, чтобы пароли не попадали в системный журнал?

Иногда я хотел бы использовать Ansible's lineinfile или blockinfile модули для записи пароля в некоторый файл конфигурации. Если я это сделаю, вся строка или блок, включая пароль, окажется в моем syslog.

Как я не считаю syslog чтобы быть безопасным местом для хранения моих паролей, как я могу сказать Ansible не просачивать мой пароль в syslog? Я надеюсь, что есть способ сделать это, иначе я бы счел это большой проблемой безопасности в Ansible.

Вы можете воспроизвести это, например, с помощью этой специальной команды:

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

Вот что в итоге 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

Для примера я использовал Ansible 2.0.0.2 из официальный Ansible Ubuntu PPA в системе Debian "Jessie" 8.

Я разработал плагин обратного вызова, чтобы скрыть пароли для выходов по умолчанию, он анализирует выходной словарь для ключа, который содержит пароль, для каждого из них значение заменяется на ********.

Создайте файл с именем protect_data.py в папке ./plugins/callback добавить добавить этот код:

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)

В файле ansible.cfg:

  • раскомментировать строку с stdout_callback и установите для этого плагина значение (stdout_callback=protect_data)
  • раскомментировать строку с callback_plugins и установить значение ./plugins/callback

Вывод изменяется только для этого плагина, если вы используете другой плагин для отображения вывода (logentries, ...), вы должны сделать то же самое с ним

В no_log атрибут скрывает данные в системном журнале. Его можно применить к одной задаче

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

или сценарий:

- hosts: all
  no_log: True

При активации отладка невозможна, поэтому рекомендуется использовать ее только для отдельных задач. Эта функция доступна с версии 1.5 Ansible. Как указано в объявлении о выпуске версии 1.5:

Задачи теперь также могут принимать параметр «no_log = True», чтобы важные задачи не попадали в системный журнал. (Параметры, которые выглядели как пароли, уже были отфильтрованы)

пароли следует фильтровать в большинстве случаев.

Можно было бы предположить, что использование Vault вместо этого устранит проблему.