Wie kann ich verhindern, dass ansible Passwörter in die Logfiles schreibt?

22

Ich richte einen MySQL-Server ein und möchte, dass Ansible das mysql-rootPasswort während der Installation setzt.

Mit Hilfe des Internets habe ich diese Lösung gefunden:

- 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_pwdist eine Variable, die aus dem Ansible Vault geladen wird. Das läuft gut, aber jetzt gibt es auf dem Server viele Zeilen im Protokoll:

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

Wie kann ich Ansible daran hindern, Klartextkennwörter in die Protokolldateien zu schreiben?

Claus
quelle

Antworten:

27

Um zu verhindern, dass eine Aufgabe mit vertraulichen Informationen in Syslog oder anderen protokolliert wird, legen Sie für die Aufgabe no_log: true fest:

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

Die Ausführung der Aufgabe wird weiterhin protokolliert, jedoch mit wenigen Details. Außerdem muss das verwendete Modul no_log unterstützen. Testen Sie daher benutzerdefinierte Module.

Siehe Ansible FAQ für weitere Details. Es kann auf ein ganzes Playbook angewendet werden, jedoch wird die Ausgabe mit "zensiert!" Mitteilungen.

Bill Carlson
quelle
2
Unter anderem heißt es in dieser Antwort: serverfault.com/a/682823/9517
user9517 unterstützt GoFundMonica am
9

Das beobachtete Verhalten scheint ein Fehler im Debconf-Modul zu sein. Ich habe einen Fehlerbericht eingereicht .

Der Benutzer bcoca bei github wies darauf hin, dass man die no_log: trueDirektive in Tasks verwenden kann, die Passwörter setzen, um die Protokollierung zu verhindern. Dies ist eine Problemumgehung, die für mich funktioniert, bis der Fehler behoben ist.

Claus
quelle
Ich erhalte eine Fehlermeldung, wenn ich diese Direktive verwende. Irgendeine Idee, was ich falsch mache? ERROR: no_log is not a legal parameter in an Ansible task or handler
Bouke Versteegh,
2
Es stellte sich heraus, dass ich eine alte Version von Ansible hatte! Um dies zu beheben (auf Ubuntu): sudo apt-add-repository ppa:ansible/ansible, sudo apt-get update,sudo apt-get install ansible
Bouke Versteegh
Das gleiche Problem für mich, aber ich kann n_log nicht so machen, dass es wie erwartet funktioniert. Meine Ansible-Version ist 1.7.2. Was ist dein ?
jmcollin92
@ jmcollin92 Ich benutze derzeit 2.1. Es ist ein Leitfaden hier , wie Sie die neueste Version von der Quelle zu installieren. Ich benutze das als Ansible das noch reift.
Claus
2

Ich habe das Problem durch ein Upgrade von Ansible auf 1.6.1 gelöst

sudo pip install ansible==1.6.1
0x3bfc
quelle
2

Wie laut Ansible docs :

log_path

Wenn vorhanden und in konfiguriert ansible.cfg, protokolliert Ansible Informationen über die Ausführung am angegebenen Speicherort. Stellen Sie sicher, dass der Benutzer, auf dem Ansible ausgeführt wird, über Berechtigungen für die Protokolldatei verfügt:

log_path=/var/log/ansible.log 

Dieses Verhalten ist nicht standardmäßig aktiviert. Beachten Sie, dass ansible ohne diese Einstellung Modulargumente aufzeichnet, die im Syslog verwalteter Maschinen aufgerufen werden. Passwortargumente sind ausgeschlossen.

Klingt so, als ob die Einstellung log_pathauf Ihrem Steuerknoten dazu führt, dass sich keine Protokolle auf den Zielknoten befinden.

Droopy4096
quelle
Tatsächlich habe ich eine ansible.cfg in meinem lokalen Verzeichnis, in dem ich ansible aufrufe und den log_path einstelle. Das lokale Protokoll wird ordnungsgemäß erstellt und nach einem neuen Durchlauf aktualisiert (Protokollierung funktioniert). Dies hindert den Remote-Host nicht an der Protokollierung (auch wenn das von Ihnen erwähnte Dokument dies verspricht). Auch die Aussage "Passwortargumente sind ausgeschlossen" scheint nicht 100% wahr zu sein? Ist das ein Bug (oder sogar zwei)?
Claus
2
@claus "Kennwortargumente ausgeschlossen" gilt nur für Module, bei denen das Kennwortargument explizit angegeben ist. Es gibt keine Möglichkeit für Ansible zu wissen, welches Argument Passwort wäre und welches nicht mit allgemeinen Befehlen wie Debconf, Shell, Raw, etc.
Droopy4096
Bitte scrolle in meinem ersten Playbook nach rechts. Es heißt vtype='password'. Das sollte IMHO explizit genug sein? Ich gehe davon aus, dass die Protokollnachricht auch vom debconf-Modul erstellt wird.
Claus
Das ist falsch. In der Dokumentation sollte genauer angegeben werden: "Beachten Sie, dass ansible unabhängig von dieser Einstellung Modulargumente aufzeichnet, die im Syslog verwalteter Maschinen aufgerufen werden."
14.
2

Es gibt einen besseren Weg als nur no_log: Richtig

- 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 != ""

Wie Sie sehen, müssen Sie Folgendes hinzufügen:

ignore_errors: true
no_log: true

Und dann machen Sie die Ausgabe des Ergebnisses des Befehls mit regex_replace, wobei:

USER_VAR - Anmeldevariable

PASSWORD_VAR - Kennwortvariable

Mit diesem Ansatz verbergen Sie nicht nur die Kennwörter und Anmeldungen, sondern erhalten auch die Ausgabe Ihres Vorgangs

TheDESTROS
quelle
1

Dies ist eine Ergänzung zur Antwort von TheDESTROS aus diesem Thread:

  1. Schreiben Sie eine Vorlage, die den Befehl mit einem Geheimnis umschließt:

wrapper-script.sh.j2

echo {{ secret_eg_from_ansible_vault }} | su - "ls -l"
  1. Rufen Sie das Wrapper-Skript auf und entfernen Sie es sofort:
- 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

Sie benötigen etwas weniger Code und können die Befehle in Ihren Protokollen ausgeben. Es gibt nur einen Caveeat, wenn das Kommando stdout ein Geheimnis enthält. Wenn Sie die externe Vorlage vermeiden möchten, hilft das copyModul mit dem Parameter contentmöglicherweise dabei, ein kleines Wrapper-Skript im Handumdrehen zu schreiben.

Christian Kaiser
quelle
1

Der no_log: trueAnsatz ist als letzter Ausweg zu verwenden, wenn andere Versuche fehlschlagen, da dadurch die Taskausführung völlig undurchsichtig wird und Sie keine Ahnung haben, wann sie fehlschlägt.

In den Sicherheitspraktiken wird empfohlen, Anmeldeinformationen über stdin oder, wenn dies nicht möglich ist, über Anmeldeinformationsdateien (oder sogar über ausführbare Dateien) anzugeben.

Hier ist ein Beispiel, wie Sie eine sichere Podman-Anmeldung durchführen, indem Sie vermeiden, dass das Kennwort angezeigt wird:

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

Damit wird das Geheimnis nicht enthüllt, resultaber Sie können weiterhin die Ausgabe des Befehls sehen.

Die meisten Tools, die eine Anmeldung benötigen, implementieren einen der genannten sichereren Ansätze. Das Verwenden von Anmeldeinformationen für die CLI im Code entspricht dem Verwenden 123456Ihres Bankkennworts.

Sorin
quelle