it-swarm-pt.tech

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

Estou configurando um servidor MySQL e quero que o Ansible defina o mysql-root senha 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?

22
claus

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

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

9
claus

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.

Veja 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.

31
Bill Carlson

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

3
TheDESTROS

Eu resolvi atualizando a versão Ansible para 1.6.1

Sudo pip install ansible==1.6.1
2
0x3bfc

Conforme Documentos Ansible :

log_path

Se presente e configurado em 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 ao syslog das máquinas gerenciadas. Os argumentos da senha são excluídos.

Parece configuração log_path no seu nó de controle resultará em não tendo logs nos nós de destino.

2
Droopy4096

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 módulo copy com o parâmetro content pode ajudar a escrever um pequeno script de wrapper rapidamente.

1
Christian Kaiser

O no_log: true A abordagem 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, em result, mas 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 have 123456 como sua senha bancária.

1
sorin

O argumento ambiente no manual é adequado para manter um segredo oculto. O segredo não é impresso, mesmo com -vvvv. Está disponível para toda a peça.

- hosts: control_Host
  gather_facts: no
  become: no
  environment:
    PASSWORD: "{{ password }}"
  tasks:

   - local_action: "Shell ./foobar.sh ${PASSWORD}"

   - local_action: "Shell echo ${PASSWORD}"

resultado:

ansible-playbook -i ... playbooks/demo.yml -v

PLAY [control_Host] *********************************************************************************

TASK [Shell] *********************************************************************************
changed: [localhost -> localhost] => {
    "changed": true,
    "cmd": "./foobar.sh ${PASSWORD}",
    "delta": "0:00:00.013467",
    "end": "2020-04-03 17:42:03.950534",
    "rc": 0,
    "start": "2020-04-03 17:42:03.937067"
}

TASK [Shell] *********************************************************************************
changed: [localhost -> localhost] => {
    "changed": true,
    "cmd": "echo ${PASSWORD}",
    "delta": "0:00:00.005925",
    "end": "2020-04-03 17:42:04.319085",
    "rc": 0,
    "start": "2020-04-03 17:42:04.313160"
}

STDOUT:

my_secret_password
0
selle