Wie kann ich ansible mit Passwörtern pro Host sicher implementieren?

108

Ich möchte ansible verwenden , um eine Gruppe vorhandener Server zu verwalten. Ich habe eine ansible_hostsDatei erstellt und erfolgreich (mit der -KOption) mit Befehlen getestet , die nur auf einen einzelnen Host abzielen

ansible -i ansible_hosts host1 --sudo -K # + commands ...

Mein Problem ist jetzt, dass die Benutzerkennwörter auf jedem Host unterschiedlich sind, aber ich finde keine Möglichkeit, dies in Ansible zu handhaben.

Unter Verwendung von -Kwird nur ein einziges Sudo-Kennwort im Voraus abgefragt, das dann ohne Aufforderung für alle nachfolgenden Hosts versucht zu werden scheint:

host1 | ...
host2 | FAILED => Incorrect sudo password
host3 | FAILED => Incorrect sudo password
host4 | FAILED => Incorrect sudo password
host5 | FAILED => Incorrect sudo password

Bisherige Forschung:

  • eine StackOverflow-Frage mit einer falschen Antwort ("use -K") und einer Antwort des Autors "Found out I needed passwordless sudo"

  • In den Ansible-Dokumenten heißt es: "Die Verwendung von Sudo ohne Passwort erleichtert die Automatisierung, ist jedoch nicht erforderlich ." (Hervorhebung von mir)

  • Diese Sicherheits-StackExchange-Frage wird als gelesen betrachtet und NOPASSWDist erforderlich

  • Artikel "Skalierbare und verständliche Bereitstellung ...", der besagt:

    "Für die Ausführung von sudo muss möglicherweise ein Kennwort eingegeben werden. Dies ist eine sichere Methode, um Ansible für immer zu blockieren. Eine einfache Lösung besteht darin, visudo auf dem Zielhost auszuführen und sicherzustellen, dass der Benutzer, mit dem sich Ansible anmeldet, kein Kennwort eingeben muss."

  • Artikel "Basic Ansible Playbooks" , in dem es heißt

    "Ansible könnte sich als root auf dem Zielserver anmelden und die Notwendigkeit von sudo vermeiden oder dem ansiblen Benutzer sudo ohne Passwort erlauben, aber der Gedanke daran lässt meine Milz drohen, meine Speiseröhre aufzuspringen und meine Luftröhre zu blockieren, so dass ich nicht "

    Meine Gedanken genau, aber wie soll man sich dann über einen einzelnen Server hinaus erstrecken?

  • ansible Ausgabe # 1227 , "Ansible sollte alle Benutzer in einem Wiedergabebuch nach dem Sudo-Passwort fragen", die vor einem Jahr von mpdehaan mit dem Kommentar "Habe keine große Nachfrage dafür gesehen, ich denke, die meisten Leute reden nur von einem Benutzerkonto oder die meiste Zeit mit Schlüsseln. "

Also ... wie nutzen Menschen Ansible in solchen Situationen? Einstellung NOPASSWDin /etc/sudoers, über Hosts Wiederverwendung Passwort oder ermöglicht Root SSH - Login alle scheinen ziemlich drastische Verringerungen der Sicherheit.

supervacuo
quelle
2
Gibt es einen Grund, warum Sie keine SSH-Schlüssel verwenden?
Trondh
22
Ich verwende bereits SSH-Schlüssel. Sie wirken sich nicht aus sudo(für die noch ein Kennwort erforderlich sein sollte).
Supervacuo
1
Das ist vielleicht nicht genau das, wonach Sie suchen, aber auf Ubuntu-Boxen verwende ich immer noch Schlüssel, dh lege meinen öffentlichen Schlüssel unter / root / authorized_keys ab, um direkt als root einzutreten. Offensichtlicher Nachteil ist das Zulassen von Root-Logins über ssh ... Ich lasse auch keine Passwort-Logins über ssh zu und führe aus Sicherheitsgründen fail2ban aus.
Senorsmile
27
@senorsmile Danke für die Antwort! Würde es Ihnen etwas ausmachen, eine Antwort daraus zu machen, damit ich Sie dafür abstimmen kann, dass Sie die Frage nicht gelesen haben?
supervacuo
4
dh die ansible_ssh_passwordEinstellung gilt nur für das SSH-Passwort (der Hinweis ist im Namen ...). & Ich verwende bereits die schlüsselbasierte SSH-Anmeldung.
supervacuo

Antworten:

53

Sie haben sicherlich Ihre Forschung getan ...

Nach all meinen Erfahrungen mit Ansible wird das, was Sie erreichen möchten, nicht unterstützt. Wie Sie bereits erwähnt haben, gibt ansible an, dass kein passwortloses sudo erforderlich ist, und Sie haben Recht, dass dies nicht der Fall ist. Aber ich habe noch keine Methode gefunden, um mehrere sudo-Passwörter in ansible zu verwenden, ohne natürlich mehrere configs auszuführen.

Also, ich kann nicht genau die Lösung anbieten, die Sie suchen, aber Sie haben gefragt ...

"Also ... wie nutzen die Leute Ansible in solchen Situationen? Das Einstellen von NOPASSWD in / etc / sudoers, das Wiederverwenden von Passwörtern auf verschiedenen Hosts oder das Aktivieren der Anmeldung bei Root-SSHs wirken sich alle ziemlich drastisch auf die Sicherheit aus."

Ich kann Ihnen eine Ansicht dazu geben. Mein Anwendungsfall sind 1k-Knoten in mehreren Rechenzentren, die eine globale SaaS-Firma unterstützen, in der ich aufgrund der Art unseres Geschäfts einige wahnsinnig strenge Sicherheitskontrollen entwerfen / implementieren muss. Sicherheit ist immer ein Balanceakt, mehr Benutzerfreundlichkeit und weniger Sicherheit. Dieser Prozess ist nicht anders, wenn Sie 10 Server oder 1.000 oder 100.000 ausführen.

Es ist absolut richtig, dass Sie keine Root-Anmeldungen verwenden, weder über ein Kennwort noch über SSH-Schlüssel. Tatsächlich sollte die Root-Anmeldung vollständig deaktiviert werden, wenn die Server mit einem Netzwerkkabel verbunden sind.

Sprechen wir über die Wiederverwendung von Kennwörtern. Ist es in einem großen Unternehmen sinnvoll, Sysadmins aufzufordern, auf jedem Knoten unterschiedliche Kennwörter zu haben? für ein paar Knoten vielleicht, aber meine Admins / Ingenieure würden meutern, wenn sie auf 1000 Knoten unterschiedliche Passwörter haben müssten. Um dies zu realisieren, müsste jeder Benutzer irgendwo seine eigenen Passwörter speichern, hoffentlich einen Schlüsselpass, keine Tabellenkalkulation. Und jedes Mal, wenn Sie ein Kennwort an einer Stelle ablegen, an der es im Klartext abgerufen werden kann, hat sich die Sicherheit erheblich verringert. Ich würde es vorziehen, wenn sie auswendig ein oder zwei wirklich sichere Kennwörter kennen, als jedes Mal, wenn sie sich bei einem Computer anmelden oder sudo aufrufen müssen, eine Keypass-Datei zu konsultieren.

Daher ist die Wiederverwendung und Standardisierung von Passwörtern auch in einer sicheren Umgebung völlig akzeptabel und Standard. Andernfalls müssten LDAP, KEYSTONE und andere Verzeichnisdienste nicht vorhanden sein.

Wenn wir auf automatisierte Benutzer umsteigen, funktionieren ssh-Schlüssel hervorragend, um Sie einzubinden, aber Sie müssen immer noch durch sudo kommen. Sie können ein standardisiertes Kennwort für den automatisierten Benutzer auswählen (was in vielen Fällen akzeptabel ist) oder NOPASSWD aktivieren, wie Sie bereits erwähnt haben. Die meisten automatisierten Benutzer führen nur wenige Befehle aus, daher ist es durchaus möglich und wünschenswert, NOPASSWD zu aktivieren, jedoch nur für vorab genehmigte Befehle. Ich würde vorschlagen, dass Sie Ihre sudoers-Datei mithilfe Ihrer Konfigurationsverwaltung (in diesem Fall nicht möglich) verwalten, damit Sie die Liste der Befehle ohne Kennwort problemlos aktualisieren können.

Sobald Sie mit der Skalierung beginnen, können Sie einige Schritte ausführen, um das Risiko weiter einzugrenzen. Zwar haben wir etwa 1000 Knoten, aber nicht alle sind Produktionsserver, einige sind Testumgebungen usw. Nicht alle Administratoren können auf Produktionsserver zugreifen, obwohl sie denselben SSO-Benutzer / Pass-Schlüssel verwenden können wie an anderer Stelle . Automatisierte Benutzer sind jedoch etwas sicherer. So verfügt beispielsweise ein automatisiertes Tool, auf das Administratoren außerhalb der Produktion zugreifen können, über Benutzer- und Berechtigungsnachweise, die in der Produktion nicht verwendet werden können. Wenn Sie ansible auf allen Knoten starten möchten, müssen Sie dies in zwei Stapeln tun, einmal für die Nicht-Produktion und einmal für die Produktion.

Wir verwenden jedoch auch Puppet, da es sich um ein erzwingendes Konfigurationsmanagement-Tool handelt, sodass die meisten Änderungen an allen Umgebungen dadurch herausgedrückt würden.

Wenn die von Ihnen angegebene Featureanforderung erneut geöffnet / abgeschlossen wird, wird das, was Sie tun möchten, selbstverständlich vollständig unterstützt. Sicherheit ist jedoch ein Prozess der Risikobewertung und des Kompromisses. Wenn Sie nur wenige Knoten haben, für die Sie sich die Kennwörter merken können, ohne auf eine Post-It-Notiz zurückzugreifen, sind separate Kennwörter etwas sicherer. Für die meisten von uns ist dies jedoch keine praktikable Option.

Zeb
quelle
Danke, @Zeb - Ich hatte mir vorgestellt, dass Benutzer mit Dutzenden bis Tausenden von Servern NOPASSWDsowieso aus Gründen der Sicherheit (wahrscheinlich unterstützt durch strengere Firewall-Regeln usw. ) verwenden würden, aber es ist gut, Ihren Anwendungsfall und Ihre Gedanken zur Bedrohung zu lesen Modell.
Supervacuo
16
Ein Kommentar zu Ihrem Vorschlag, sich auf "vorab genehmigte" sudoBefehle zu beschränken (was mir einfiel, als ich feststellte, dass dies NOPASSWDziemlich notwendig ist). Leider scheint dies auch völlig ununterstützt zu sein - Ansible macht keine Zusagen, zB chown oder mkdirBinaries direkt aufzurufen , und muss in der Lage sein, sudo /bin/shdamit die meisten Module funktionieren.
Supervacuo
Ich erinnere mich an einen meiner Ingenieure, der sich vor einiger Zeit darüber beschwert hat. Das ist ärgerlich.
Zeb
36

Ab Ansible 1.5 ist es möglich, ein verschlüsseltes Depot für host_vars und andere Variablen zu verwenden. Auf diese Weise können Sie zumindest eine ansible_sudo_passVariable pro Host (oder pro Gruppe) sicher speichern . Leider --ask-vault-passwird nur ein einziges Tresorkennwort pro anzeigbarem Aufruf abgefragt, sodass Sie weiterhin für alle Hosts, die Sie zusammen verwenden, auf ein einziges Tresorkennwort beschränkt sind.

Für einige Anwendungen kann dies jedoch eine Verbesserung gegenüber der Verwendung eines einzigen Sudo-Kennworts für mehrere Hosts sein, da ein Angreifer ohne Zugriff auf Ihre verschlüsselten host_vars weiterhin ein separates Sudo-Kennwort für jede Maschine (oder Maschinengruppe) benötigt, die er oder sie angreift.

Daniel Neades
quelle
3
Die ansible_sudo_passOption scheint ebenfalls neu zu sein - und scheint das zu tun, wonach ich gefragt habe. Ein einziges Tresorkennwort ist auch für meine Zwecke ideal. Vielen Dank!
Supervacuo
Gibt es eine Möglichkeit zur Vermeidung von Verschlüsselung aller host_vars mit dieser Methode? (eine mögliche Einschränkung von Alex Dupuy bemerkt)
supervacuo
1
@supervacuo - Um zu vermeiden , dass all Host - Vars Verschlüsselung verwendet nur ein Host - var - Verzeichnis enthält main.yml (unverschlüsselt) und secret.yml (verschlüsselt) - siehe letzten Teil dieses doc Abschnitt , wo es über die „raleigh“ Gruppe spricht - gleiche Technik Funktioniert für Host-Vars und Gruppen-Vars. Ich benutze dies oft, die einzige Variante ist, dass es nützlich sein kann, wenn ein Geheimnis nur für einige Playbooks benötigt wird, es in einem anderen Baum zu speichern und über einen Pfad einzuschließen, der den Host- oder Var-Namen enthält.
RichVel
1
Wenn ich den Wert 'ansible_ssh_pass' im Tresor verschlüsselt habe, muss ich dann auch den Wert 'ansible_sudo_pass' duplizieren? Gibt es eine Möglichkeit für den zweiten sudo_pass-Wert, den ersten 'ssh_pass'-Wert zu referenzieren?
Smaragdjava
Eine gute Abdeckung für die Verwendung von vaulted-
CODE-REaD
22

Mit Ansible 1.5 ist es möglich, die Variable ansible_sudo_pass wie folgt festzulegenlookup('password', …) :

ansible_sudo_pass: "{{ lookup('password', 'passwords/' + inventory_hostname) }}"

Ich finde das host_vars/aus mehreren Gründen praktischer als die Verwendung von Dateien in :

  • Ich verwende eigentlich, with_password: "passwords/{{ inventory_hostname}} encrypt=sha256_crypt" um die Passwörter für den Deploy- Remote-Benutzer (der dann für sudo benötigt wird) bereitzustellen , damit sie bereits in den Dateien vorhanden sind (obwohl bei diesen Klartext-Suchen der in der Datei gespeicherte Salt-Wert verloren geht, wenn der Hash-Wert generiert wird). .

  • Dies behält nur die Passwörter in der Datei (kein ansible_sudo_pass:bekannter Klartext) bei, um die kryptografische Sicherheit zu erhöhen. Insbesondere bedeutet dies, dass Sie nicht alle anderen hostspezifischen Variablen verschlüsseln, sodass sie ohne das Tresorkennwort gelesen werden können.

  • Wenn Sie die Passwörter in einem separaten Verzeichnis ablegen, können Sie die Quellcodeverwaltung für die Dateien aufheben oder mithilfe eines Tools wie git-crypt verschlüsselt speichern. Ich verwende git-crypt und da ich das Repository nur in entschlüsselter Form auf verschlüsselten Dateisystemen auschecke, kümmere ich mich nicht um den Tresor und muss daher kein Tresorkennwort eingeben. (Beides wäre natürlich sicherer.)

Sie können auch die Verwendung Lookup - Funktion mit ansible_ssh_pass ; Dies ist möglicherweise sogar mit früheren Versionen von Ansible möglich, die keinen ansible_sudo_pass haben .

Alex Dupuy
quelle
2
Ich habe es endlich versucht (danke!), Kann aber nicht sehen, wie es ohne funktionieren würde git-crypt; soweit ich das beurteilen kann. Es scheint, dass Ansible noch keine Unterstützung für die Verwendung lookupin einem verschlüsselten Tresor hat. Die passwordDokumentation des Moduls besagt , dass es eine noch nicht dokumentierte Unterstützung für verschlüsselte Speicherung gibt, aber ich habe noch keine Details gefunden. Irgendwelche Hinweise?
Supervacuo
19

Die Verwendung von pass ist eine einfache Methode, um sudo-Passwörter ansible zu machen. pass speichert ein Passwort pro Datei, was das Teilen von Passwörtern über git oder andere Methoden vereinfacht. Es ist auch sicher (mit GnuPG) und wenn Sie gpg-agent verwenden, können Sie ansible verwenden, ohne bei jeder Verwendung ein Passwort einzugeben.

Verwenden Sie dieses Kennwort in einer Inventardatei wie der folgenden, um das servers/foofür den Server gespeicherte Kennwort foosichtbar zu machen:

[servers]
foo ansible_sudo=True \
    ansible_sudo_pass="{{ lookup('pipe', 'pass servers/foo') }}"

Vorausgesetzt, Sie haben den Schlüssel für gpg-agent früher entsperrt, läuft dies ohne Eingabe eines Passworts anzeigbar.

fqxp
quelle
3

Dies ist jedoch ein ziemlich alter Thread:

  • Wir verwenden intern zwei verschiedene Authentifizierungssysteme. Die Verwaltung der Maschinen erfolgt von lokalen Arbeitsplätzen in meinem Team aus.
  • Ich habe ein vars_pluginfür Ansible geschrieben (eine ziemlich vollständige Implementierung finden Sie unter https://gist.github.com/mfriedenhagen/e488235d732b7becda81 ), das verschiedene Authentifizierungssysteme unterscheidet:
  • Der Name des Authentifizierungssystems ist gruppenspezifisch.
  • Der verwendete Benutzer login / sudo ist gruppen- und adminspezifisch.
  • Also ziehe ich den Benutzer aus der Admin-Umgebung und das entsprechende Passwort über die Python-Schlüsselbund-Bibliothek aus einem Passwort-Safe (wir verwenden den Schlüsselbund von Mac OS X, aber aus der Dokumentation werden auch kwallet Gnome und _win_crypto unterstützt).
  • Ich habe Berechtigungen für die Kennwörter im Schlüsselbund von Mac OS X festgelegt, um darauf hinzuweisen, dass die Sicherheit des Befehlszeilenprogramms für jedes von den Hosts verwendete Authentifizierungssystem den Zugriff auf ein Kennwort anfordert. Daher führe ich "ansible -s all -m ping" aus. und bekomme zwei Eingabeaufforderungen (eine für jedes Authentifizierungssystem), bei denen ich die Leertaste drücke und ansible die Passwörter aufnimmt.
Mirko Friedenhagen
quelle
Das sieht sehr ordentlich aus, danke - ich mag die Idee, keine Passwörter an zwei Stellen speichern zu müssen. Im Moment benutze ich KeepassX nicht mehr (weil der GNOME-Schlüsselring nicht sehr portabel zu sein scheint), aber vielleicht kann ich es schaffen, dass es python-keepassfunktioniert?
supervacuo
Soweit ich weiß, ist der Python-Schlüsselbund eine Abstraktion dafür, sodass Ihre Kollegen möglicherweise andere Betriebssysteme verwenden. Oder speichern Sie Ihre keepassx db auf einem USB-Stick und müssen von Arbeitsstationen mit unterschiedlichen Betriebssystemen aus administrieren?
Mirko Friedenhagen
verstanden; Ich wollte damit sagen, dass ich KeepassX bereits verwenden muss, um auf Kennwörter auf Nicht-GNOME-Systemen zugreifen zu können. Wenn Sie diese also speichern gnome-keyring, müssen Sie doppelte Aufzeichnungen führen. Immer noch viel schöner als mit NOPASSWD, obwohl ...
supervacuo
0

Ein möglicher Weg, dies zu tun, ist die Verwendung von Umgebungsvariablen.

z.B

pass1=foo pass2=bar ansible-playbook -i production servers.xml

Dann können Sie in den Spielen das sudo-Passwort nachschlagen mit:

lookup('env', 'pass1') 
lookup('env', 'pass2') 
Paul Calabro
quelle