Jak ustawić hasło Ansible, jeśli klucz został odrzucony?

14

Moje nowe instancje serwera są skonfigurowane do logowania na root za pośrednictwem ssh z hasłem. Chcę, aby mój podręcznik Ansible ponownie skonfigurował go, aby używał kluczy, i wyłączał logowanie roota hasłem przy pierwszym uruchomieniu, więc potrzebuję czegoś takiego:

  • spróbuj zalogować się za pomocą klucza
  • jeśli nie można się zalogować za pomocą klucza:

    • zaloguj się za pomocą hasła
    • dodaj klucz do uprawnionych kluczy
    • wyłącz logowanie rootem za pomocą hasła
    • opcjonalnie podłącz ponownie za pomocą klucza
  • wykonuj inne zadania

Jak mogę to osiągnąć?

EDYCJA : Żeby było jasne, nie pytam, jak dodać klucz lub wyłączyć root, to tylko dla kontekstu. Pytam, jak wrócić do hasła, jeśli nie można go uwierzytelnić za pomocą klucza. Po ustawieniu --ask-passlub ansible_ssh_passustawieniu Ansible nawet nie spróbuje użyć uwierzytelnienia za pomocą klucza publicznego

petr0
źródło
Dobre pytanie, co próbowałeś do tej pory?
dawud
1
Zabrałem konfigurację ssh do osobnego playbooka i uruchamiam ją z opcją -k, następnie uruchamiam główny playbook bez -k (używając klucza od agenta). Miałem nadzieję, że można go zapakować w jeden podręcznik…
petr0,
@ petr0 Działa to dla mnie, gdy hasło ask-pass jest dla innego użytkownika niż klucz (tj. kiedy zmieniasz użytkownika zdalnego po wyłączeniu hasła ssh). Nie jestem pewien, czy to pomaga.
DylanYoung,

Odpowiedzi:

6

Możesz wypróbować tę PreferredAuthenticationsopcję, ustawiając ją na publickey,password. Domyślnie zawiera je w tej kolejności, wraz z innymi opcjami, więc prawdopodobnie ustawia to ansible. Dodanie go za pośrednictwem -olub klient ssh_configmoże temu zapobiec.

Możesz być w stanie użyć skryptu opakowania. Na przykład, gdy to jest key_or_password.shi a, pass.shktóre podaje hasło, uruchomienie bash key_or_password.sh root@hostspróbuje użyć klucza publicznego, a następnie nieinteraktywnego loginu do hasła.

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

Dziennik wskazuje, która metoda zakończyła się powodzeniem, np

debug1: Authentication succeeded (publickey).
eisd
źródło
7

Oto, co robię, jeśli ansible_userróżni się w przypadku „pierwszego uruchomienia” podręcznika (na przykład, jeśli masz tylko rootużytkownika i zamierzasz skonfigurować nowego użytkownika za pomocą klucza SSH):

  • Przechowuj hasło w ansible_passtaki sam sposób, jakbyś używał loginu do hasła (pamiętaj, aby użyć Vault). Powinno to być hasło użytkownika, którego używasz do „pierwszego uruchomienia” poradnika.
  • Ustaw ansible_usernazwę użytkownika, którego chcesz używać po pierwszym uruchomieniu, gdy użytkownicy prawidłowo skonfigurowali się na serwerze.
  • Ustaw na przykład zmienną ansible_user_first_runużytkownika, którego będziesz używać podczas pierwszego uruchomienia podręcznika root.
  • Użyj polecenia lokalnego, aby spróbować połączyć się z serwerem za pomocą poprawnego klucza SSH, używając ignore_errorsichanged_when: False
  • Jeśli to się nie powiedzie, zaktualizuj ansible_userdo wartościansible_user_first_run

Oto kod:

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

Uwaga: Warto skonfigurować, transport = sshponieważ Paramiko może nieoczekiwanie nie udać się do serwera w niektórych konfiguracjach (np. Gdy serwer jest skonfigurowany tak, aby nie akceptować haseł, a ty próbujesz najpierw z kluczem, a następnie hasłem ... dziwne!) Również transport ssh jest szybszy, więc i tak warto.

Dodatkowa uwaga: Jeśli używasz tej metody, musisz określić gather_facts: falsew pliku definicji Playbook, aby zadania konfiguracji / gromadzenia faktów nie były uruchamiane automatycznie, zanim przejdziesz do etapu testowania haseł. Jeśli potrzebujesz któregoś z wiarygodnych faktów, będziesz musiał wyraźnie zadzwonić setupw swojej roli przed uzyskaniem dostępu do danych normalnie dostępnych w takich miejscach, jak ansible_devicesitp. Jednym z dobrych sposobów jest zadzwonienie setupz whenklauzulą, która sprawdza, czy fakt, którego używasz, jest pusty lub nie, zanim nazwiesz go swoją rolą.

Tom Bull
źródło
Twoje rozwiązanie jest dobre, ale trzeba dodać gather_facts: no, aby zatrzymać ansibl próby połączenia przy uruchamianiu playbook :)
k4cy
Masz rację. Mam ustawione zbierania informacji dla wszystkich moich podręczników, więc muszę jawnie wywołać „setup”. Zapomniałem wspomnieć o tym w odpowiedzi, zaktualizuję to teraz.
Tom Bull
5

Możesz używać --ask-passpodczas uruchamiania ansible-playbook.

W przypadku innych zadanych zadań można to osiągnąć na różne sposoby, np. Przez moduł kopiowania.
Wyłączenie logowania roota można również wykonać np. przez szablon sshd_conflub wstawienie linii w pliku conf.

Tytus
źródło
--ask-pass (czyli to samo co -k) jest tym, co robię i napisałem o tym w powyższym komentarzu
petr0