Wie verwende ich das Passwort von Ansible, wenn der Schlüssel abgelehnt wurde?

14

Meine neuen Serverinstanzen sind so konfiguriert, dass sie sich über ssh mit Passwort bei root anmelden. Ich möchte, dass mein Ansible-Playbook es so konfiguriert, dass es stattdessen Schlüssel verwendet, und die Root-Anmeldung mit Passwort beim ersten Start deaktiviert.

  • Versuche dich mit dem Schlüssel einzuloggen
  • wenn ich mich nicht mit schlüssel einloggen kann:

    • Mit Passwort einloggen
    • Schlüssel zu authorized_keys hinzufügen
    • Deaktivieren Sie die root-Anmeldung mit dem Passwort
    • Optional können Sie die Verbindung mit der Taste wiederherstellen
  • andere aufgaben erledigen

Wie kann ich das erreichen?

EDIT : Um klar zu sein, ich frage nicht, wie man einen Schlüssel hinzufügt oder root deaktiviert, das ist nur für den Kontext. Ich frage, wie ich auf ein Passwort zurückgreifen soll, wenn es sich nicht mit einem Schlüssel authentifizieren kann. Mit --ask-passoder ansible_ssh_passset versucht Ansible nicht einmal, die Authentifizierung mit öffentlichen Schlüsseln zu verwenden

petr0
quelle
Gute Frage, was hast du bisher versucht?
Dawud
1
Ich habe die ssh-Konfiguration in ein separates Playbook verschoben und es mit der Option -k ausgeführt. Anschließend habe ich das Haupt-Playbook ohne -k ausgeführt (mithilfe des Schlüssels vom Agenten). Ich hatte gehofft, dass es in ein einziges Spielbuch gewickelt werden kann ...
petr0
@ petr0 Dies funktioniert bei mir, wenn das Passwort für einen anderen Benutzer als den Schlüssel festgelegt ist (dh, wenn Sie den Remote-Benutzer wechseln, nachdem Sie passwortgeschütztes ssh deaktiviert haben). Ich bin mir nicht sicher, ob das hilft.
DylanYoung

Antworten:

6

Sie können die PreferredAuthenticationsOption ausprobieren und auf einstellen publickey,password. In der Standardeinstellung sind diese Optionen zusammen mit anderen Optionen in dieser Reihenfolge enthalten, sodass dies vermutlich von ansible festgelegt wird. Das Hinzufügen über -ooder den Client ssh_configkann dies verhindern.

Möglicherweise können Sie ein Wrapper-Skript verwenden. Wenn Sie zum Beispiel this in key_or_password.shund a angeben pass.sh, das das Kennwort bash key_or_password.sh root@hostangibt , wird beim Ausführen ein publickey gefolgt von einer nicht interaktiven Kennwortanmeldung ausgeführt.

export DISPLAY=dummy:0
export SSH_ASKPASS=$PWD/pass.sh
exec setsid ssh -v -o 'PreferredAuthentications publickey,password' "$@"

Das Protokoll gibt an, welche Methode erfolgreich war, z

debug1: Authentication succeeded (publickey).
eisd
quelle
7

Folgendes mache ich, wenn ansible_useres beim ersten Ausführen des Playbooks anders ist (zum Beispiel, wenn Sie nur einen rootBenutzer haben und einen neuen Benutzer mit einem SSH-Schlüssel einrichten):

  • Speichern Sie das Kennwort so, ansible_passals ob Sie Kennwortanmeldungen verwenden würden (denken Sie daran, Vault zu verwenden). Dies sollte das Kennwort des Benutzers sein, den Sie für den 'ersten Lauf' des Wiedergabebuchs verwenden.
  • Stellen Sie ansible_userden Benutzernamen des Benutzers ein, den Sie nach der ersten Ausführung verwenden möchten, wenn Sie Benutzer korrekt auf dem Server eingerichtet haben.
  • Legen Sie eine Variable für ansible_user_first_runden Benutzer fest, den Sie zum Beispiel für den 'ersten Lauf' des Playbooks verwenden möchten root.
  • Verwenden Sie einen lokalen Befehl , zu versuchen , auf den Server mit dem richtigen SSH - Schlüssel zu verbinden, mit ignore_errorsundchanged_when: False
  • Wenn dies fehlschlägt, aktualisieren Sie ansible_userauf den Wert vonansible_user_first_run

Hier ist der Code:

---
- name: Check if connection is possible
  command: ssh -o User={{ ansible_user }} -o ConnectTimeout=10 -o PreferredAuthentications=publickey -o PubkeyAuthentication=yes {{ inventory_hostname }} echo "Worked"
  register: result
  connection: local
  ignore_errors: yes
  changed_when: False
- name: If no connection, change user_name
  connection: local
  set_fact:
    ansible_user: "{{ ansible_user_first_run }}"
  when: result|failed

Hinweis: Es lohnt sich einzurichten, transport = sshda sich paramiko in einigen Konfigurationen unerwartet nicht am Server anmelden kann (z. B. wenn der Server so eingerichtet ist, dass keine Passwörter akzeptiert werden und Sie zuerst einen Schlüssel und dann ein Passwort eingeben ... komisch!). Auch der SSH-Transport ist schneller, es lohnt sich also trotzdem.

Weiterer Hinweis: Wenn Sie diese Methode verwenden, müssen Sie gather_facts: falsein Ihrer Playbook-Definitionsdatei angeben , dass die Setup- / Faktensammlungsaufgaben nicht automatisch ausgeführt werden, bevor Sie mit dem Testen von Kennwörtern beginnen. Wenn Sie einen der wesentlichen Fakten benötigen, müssen Sie setupIhre Rolle explizit aufrufen, bevor Sie auf die Daten zugreifen, die normalerweise an Orten wie ansible_devicesusw. verfügbar sind. Eine gute Möglichkeit besteht darin, setupmit einer whenKlausel aufzurufen , die prüft, ob dies der Fall ist Die Tatsache, die Sie verwenden, ist leer oder nicht, bevor Sie es in Ihrer Rolle aufrufen.

Tom Bull
quelle
Ihre Lösung ist gut, aber Sie müssen ein hinzufügen gather_facts: no, um den Verbindungsversuch zu beenden, wenn Sie das Playbook starten :)
k4cy
Du hast Recht. Ich habe gather_facts für alle meine Playbooks deaktiviert, so dass ich explizit 'setup' aufrufen muss. Ich habe vergessen, dies in der Antwort zu erwähnen, ich werde es jetzt aktualisieren.
Tom Bull
5

Sie können --ask-passansible-playbook verwenden, wenn Sie es ausführen.

Für andere Aufgaben, die Sie gestellt haben, ist dies auf verschiedene Weise möglich, z. B. durch Kopieren eines Moduls.
Das Deaktivieren des Root-Logins kann zB auch erfolgen. durch Vorlage sshd_confoder Einfügen einer Zeile in eine Conf-Datei.

Titus
quelle
--ask-pass (das ist das gleiche wie -k) ist, was ich tue und ich schrieb darüber in dem Kommentar oben
petr0