Como posso impedir que o ansible escreva senhas nos arquivos de log?

22

Estou configurando um servidor MySQL e quero que o Ansible defina a mysql-rootsenha durante a instalação.

Com a ajuda da internet, eu vim com esta solução:

- name: Set MySQL root password before installing
  debconf: name='mysql-server' question='mysql-server/root_password' value='{{mysql_root_pwd | quote}}' vtype='password'
- name: Confirm MySQL root password before installing
  debconf: name='mysql-server' question='mysql-server/root_password_again' value='{{mysql_root_pwd | quote}}' vtype='password'
- name: Install Mysql
  apt: pkg=mysql-server state=latest

mysql_root_pwdé uma variável carregada do Ansible Vault. Isso funciona bem, mas agora no servidor existem muitas linhas no log:

Apr 10 14:39:59 servername ansible-debconf: Invoked with value=THEPASSWORD vtype=password question=mysql-server/root_password name=mysql-server unseen=None
Apr 10 14:39:59 servername ansible-debconf: Invoked with value=THEPASSWORD vtype=password question=mysql-server/root_password_again name=mysql-server unseen=None

Como posso impedir que o Ansible grave senhas em texto não criptografado nos arquivos de log?

claus
fonte

Respostas:

28

Para impedir que uma tarefa com informações confidenciais seja registrada, em syslog ou outro, defina no_log: true na tarefa:

- name: secret stuff
  command: "echo {{secret_root_password}} | sudo su -"
  no_log: true

A execução da tarefa ainda será registrada, mas com pequenos detalhes. Além disso, o módulo usado deve suportar no_log, portanto, teste os módulos personalizados.

Consulte Ansible FAQ para mais detalhes. Pode ser aplicado a um manual inteiro, no entanto, a saída fica um pouco desagradável com "censurado!" mensagens.

Bill Carlson
fonte
2
Entre outras coisas, é isso que esta resposta diz serverfault.com/a/682823/9517
user9517 suporta GoFundMonica
9

O comportamento observado parece ser um bug no módulo debconf. Eu enviei um relatório de erro .

O usuário bcoca no github apontou que é possível usar a no_log: truediretiva em tarefas, que definem senhas, para impedir o registro. Esta é uma solução alternativa, que funciona para mim até que o bug seja corrigido.

claus
fonte
Estou recebendo um erro ao usar essa diretiva. Alguma idéia do que estou fazendo de errado? ERROR: no_log is not a legal parameter in an Ansible task or handler
Bouke Versteegh
2
Acontece que eu tinha uma versão antiga do ansible! Para corrigir (no Ubuntu): sudo apt-add-repository ppa:ansible/ansible, sudo apt-get update,sudo apt-get install ansible
Bouke Versteegh
Mesmo problema para mim, mas não consigo fazer com que n_log: true funcione conforme o esperado. Minha versão Ansible é 1.7.2. Qual é a sua?
jmcollin92
@ jmcollin92 Eu atualmente uso 2.1. Há um guia aqui sobre como instalar a versão mais recente da fonte. Eu uso isso como ansível ainda está amadurecendo.
claus
2

Eu resolvi atualizando a versão Ansible para 1.6.1

sudo pip install ansible==1.6.1
0x3bfc
fonte
2

De acordo com os documentos Ansible :

log_path

Se presente e configurado ansible.cfg, o Ansible registrará informações sobre execuções no local designado. Verifique se o usuário que está executando o Ansible tem permissões no arquivo de log:

log_path=/var/log/ansible.log 

Esse comportamento não está ativado por padrão. Observe que o ansible, sem essa configuração, registra os argumentos do módulo chamados para o syslog das máquinas gerenciadas. Os argumentos da senha são excluídos.

Parece que a configuração log_pathno nó de controle resultará em não ter logs nos nós de destino.

Droopy4096
fonte
Na verdade, tenho um ansible.cfg no meu diretório local, onde chamo ansible, configurando o log_path. O log local é criado corretamente e atualizado após uma nova execução (o log funciona). Isso não impede (apesar de o documento que você apontou prometer) impedir o registro do host remoto. Além disso, a declaração "Argumentos de senha são excluídos" parece não ser 100% verdadeira? Isso é um bug (ou até dois)?
Noel
2
@claus "argumentos de senha excluídos" se aplica apenas a módulos onde o argumento de senha é explícito. Não há nenhuma maneira para ansible saber qual argumento seria senha e que não iria com comandos gerais como debconf, shell, cru, etc.
Droopy4096
Role para a direita no meu manual inicial. Diz vtype='password'. Isso deve ser suficientemente explícito IMHO? Presumo que a mensagem de log também seja criada pelo módulo debconf.
claus
Isto está incorreto. A documentação deve dizer com mais precisão "Observe que o ansible, independentemente dessa configuração , registra os argumentos do módulo chamados ao syslog das máquinas gerenciadas".
augurar
2

Existe uma maneira melhor do que apenas no_log: True

- name: write in string variables login and password
  set_fact:
    temp_user: "{{ USER_VAR }}"
    temp_pass: "{{ PASSWORD_VAR }}"


- name: Your operation with password in output
  shell: '/opt/hello.sh'
  ignore_errors: True
  no_log: True
  register: myregister

- debug:
    msg: '{{ myregister.stderr | regex_replace(temp_user) | regex_replace(temp_pass) }}'
  when: myregister.stderr != ""

- debug:
    msg: '{{ myregister.stdout | regex_replace(temp_user) | regex_replace(temp_pass) }}'
  when: myregister.stdout != ""

- fail:
    msg: "error shell /opt/hello.sh"
  when: myregister.stderr != ""

Como você pode ver, você precisa adicionar:

ignore_errors: true
no_log: true

E, em seguida, faça a saída do resultado do comando com regex_replace, em que:

USER_VAR - variável de login

PASSWORD_VAR - variável de senha

Com essa abordagem, você não apenas ocultará as senhas e logins, mas também obterá o resultado da sua operação

TheDESTROS
fonte
1

Este é um complemento para a resposta de TheDESTROS a partir deste tópico:

  1. escreva um modelo, que agrupe o comando com um segredo:

wrapper-script.sh.j2

echo {{ secret_eg_from_ansible_vault }} | su - "ls -l"
  1. Chame o script do wrapper e remova-o imediatamente:
- name: create template
  template:
    src: wrapper-script.sh.j2
    dest: /tmp/wrapper-script.sh
    mode: 0700
  no_log: True
- name: invoke command with secret and remove it
  shell: /tmp/wrapper-script.sh; rm -f /tmp/wrapper-script.sh

Você precisa de um pouco menos de código e pode descobrir os comandos em seus logs. Existe apenas uma caverna, se houver um segredo nos comandos stdout. Se você deseja evitar o modelo externo, o copymódulo com o parâmetro contentpode ajudar a escrever um pequeno script de wrapper rapidamente.

Christian Kaiser
fonte
1

A no_log: trueabordagem deve ser usada como último recurso se outras tentativas falharem, pois tornará a execução da tarefa totalmente opaca e você não terá idéia de quando falhar.

As práticas de segurança recomendam fornecer credenciais do stdin ou, quando não for possível, usar arquivos de credenciais (ou mesmo executáveis).

Aqui está um exemplo de como executar um login podman seguro, evitando expor a senha:

- name: secured login
  become: true
  command: >
    podman login --username={{ user }} --password-stdin ...
  args:
    stdin: "{{ secret }}"
  register: result

Com isso, o segredo não será exposto, resultmas você ainda poderá ver a saída do comando.

A maioria das ferramentas que precisam de login implementam uma das abordagens mais seguras mencionadas. O uso de credenciais na CLI no código é como ter 123456como sua senha do banco.

sorin
fonte