¿Cómo puedo reducir la verbosidad de ciertas tareas de Ansible para no filtrar contraseñas en syslog?

11

A veces me gustaría usar Ansible lineinfileo blockinfilemódulos para escribir una contraseña en algún archivo de configuración. Si lo hago, toda la línea o bloque, incluida la contraseña, termina en mi syslog.

Como no considero syslogun lugar seguro para almacenar mis contraseñas, ¿cómo puedo decirle a Ansible que no filtre mi contraseña syslog? Espero que haya una manera de hacer esto, de lo contrario consideraría que este es un gran problema de seguridad en Ansible.

Puede reproducirlo, por ejemplo, con este comando ad-hoc:

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

Esto es lo que termina en 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

Para el ejemplo utilicé Ansible 2.0.0.2 del Ansible Ubuntu PPA oficial en un sistema Debian "Jessie" 8.

aef
fuente

Respuestas:

3

El no_log atributo oculta datos en syslog. Se puede aplicar a una sola tarea

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

o el libro de jugadas:

- hosts: all
  no_log: True

La depuración no es realmente posible cuando se activa, por lo que se recomienda usarla solo para tareas individuales. Esta característica está disponible desde la versión 1.5 de Ansible . Como se indica en el anuncio de lanzamiento de la versión 1.5:

Las tareas ahora también pueden tomar una opción "no_log = True" para evitar que las tareas delicadas lleguen a syslog. (Los parámetros que parecían contraseñas ya estaban filtrados)

las contraseñas se deben filtrar en la mayoría de los casos.

Henrik Pingel
fuente
Esto efectivamente oculta las contraseñas syslogpero al mismo tiempo deshabilita la salida de registro en la salida de la consola. ¿Hay alguna forma de cambiar eso?
aef
Lo siento. Encontré poca información sobre este tema. Sugeriría establecer el atributo solo para tareas y solo una vez que depuraste tu juego. Como se citó, Ansible ya debe filtrar parámetros que parecen contraseñas. Entonces tal vez es un error. Nuevamente, no sé cómo Ansible determina si un parámetro es una contraseña. Tal vez es una característica de error / falta de ocultar password = XXX.
Henrik Pingel
¿Dónde tuvo la impresión de que se supone que las contraseñas están ocultas por defecto en Ansible? ¿Se menciona esto en algún lugar de la documentación?
aef
Última cita en mi respuesta (los parámetros que parecían contraseñas ya estaban filtrados). Pero no he encontrado ninguna otra fuente para esa funcionalidad
Henrik Pingel
3

Desarrollé un complemento de devolución de llamada para ocultar las contraseñas para las salidas predeterminadas, analiza el diccionario de salida para la clave que contiene la contraseña , para cada una de ellas, reemplaza el valor por ********.

Cree un archivo llamado protect_data.pyen la carpeta ./plugins/callback add agregue este código:

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)

En el archivo ansible.cfg :

  • descomente la línea stdout_callbacky establezca un nombre para este complemento ( stdout_callback=protect_data)
  • descomentar línea callback_pluginsy establecer valor./plugins/callback

La salida solo se modifica para este complemento, si usa otro complemento para mostrar la salida ( logentries, ...), debe hacer lo mismo con él

Nelson G.
fuente
Oh, wow, eso es genial. Sin embargo, esto requiere que establezca un dict con el nombre clave 'contraseña' para todo lo que contiene un secreto. Me hubiera encantado una meta bandera para indicar que una variable contiene un secreto, ¡pero gracias! Otro P: ¿esto también enmascara los secretos en la salida con ansible-playbook --diff(cambios de diferencias de archivo)?
gertvdijk
No sé, nunca lo intenté
Nelson G.
-3

Uno podría sugerir que usar Vault en su lugar evitaría el problema.

usuario19151
fuente
Esto no proporciona una respuesta a la pregunta. Una vez que tenga suficiente reputación , podrá comentar cualquier publicación ; en su lugar, proporcione respuestas que no requieran aclaración del autor de la pregunta . - De la opinión
chicas
1
Vault ayuda a cifrar datos en reposo, pero cuando se usan contraseñas, pueden aparecer fácilmente en los archivos de registro.
Konstantin Suvorov
@chicks Esto parece una respuesta incorrecta , no una no respuesta .
Michael Hampton
No vi esa opción en las herramientas de revisión. Como esto se parece más a un comentario que a una respuesta, siento que lo manejé razonablemente.
pollitos
Mi bandera también fue rechazada, y todavía no veo cómo la oración anterior es una respuesta sobre cómo reducir la verbosidad Ansible . A lo sumo, es un comentario que sugiere otra idea, ciertamente no una respuesta a la pregunta.
Patrick Mevzek