Иногда я хотел бы использовать 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 вместо этого устранит проблему.