Come rendere Ansible utilizzare la password se la chiave è stata rifiutata?


14

Le mie nuove istanze del server sono configurate per il login su root tramite ssh con password. Voglio che il mio Playbook Ansible lo riconfiguri per utilizzare le chiavi e disabilitare l'accesso root con password al primo avvio, quindi ho bisogno di qualcosa del genere:

  • prova ad accedere con la chiave
  • se non riesci ad accedere con la chiave:

    • accedi con password
    • aggiungi la chiave a authorized_keys
    • disabilita l'accesso root con password
    • facoltativamente riconnettersi usando la chiave
  • fare altri compiti

Come posso farlo?

EDIT : Per essere chiari, non sto chiedendo come aggiungere chiave o disabilitare root, questo è solo per il contesto. Sto chiedendo come eseguire il fallback alla password se non è stato possibile eseguire l'autenticazione con la chiave. Con --ask-passo ansible_ssh_passimpostato, Ansible non tenterà nemmeno di utilizzare l'autenticazione con chiave pubblica


Bella domanda, cosa hai provato finora?
Dawud,

1
Ho portato la configurazione di ssh in un playbook separato e l'ho eseguita con l'opzione -k, quindi ho eseguito il playbook principale senza -k (usando key dall'agente). Speravo che potesse essere racchiuso in un unico playbook ...
Petr0

@ petr0 Questo funziona per me quando la password ask-pass è per un utente diverso rispetto alla chiave (cioè quando si cambia utente remoto dopo aver disabilitato ssh con password). Non sono sicuro se questo aiuta.
DylanYoung,

Risposte:


6

Potresti provare l' PreferredAuthenticationsopzione, impostandola su publickey,password. Il valore predefinito include questi in questo ordine, insieme ad altre opzioni, quindi è probabile che questo sia impostato. L'aggiunta tramite -oo il client ssh_configpotrebbe impedirlo.

Potresti essere in grado di utilizzare uno script wrapper. Ad esempio, con questo in key_or_password.she un pass.shche fornisce la password, l'esecuzione bash key_or_password.sh root@hostproverà una chiave pubblica seguita da un accesso con password non interattivo.

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

Il registro indica quale metodo è riuscito, ad es

debug1: Authentication succeeded (publickey).

7

Ecco cosa faccio se ansible_userè diverso per la "prima esecuzione" del playbook (ad esempio se hai solo un rootutente e hai intenzione di impostare un nuovo utente con una chiave SSH):

  • Memorizza la password ansible_passcome faresti se stessi utilizzando gli accessi password (ricordati di utilizzare Vault), questa dovrebbe essere la password dell'utente che stai utilizzando per la "prima esecuzione" del playbook.
  • Impostato ansible_usersul nome utente dell'utente che si desidera utilizzare dopo la prima esecuzione quando gli utenti sono impostati correttamente sul server.
  • Ad esempio, imposta una variabile ansible_user_first_runper l'utente che intendi utilizzare per la "prima esecuzione" del playbook root.
  • Utilizzare un comando locale per tentare di connettersi al server con la chiave SSH corretta, utilizzando ignore_errorsechanged_when: False
  • Se fallisce, aggiorna ansible_useral valore diansible_user_first_run

Ecco il codice:

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

Nota: vale la pena configurarlo transport = sshpoiché paramiko può inaspettatamente non riuscire ad accedere al server in alcune configurazioni (ad es. Quando il server è impostato per non accettare le password, e stai provando prima con una chiave poi una password ... strano!) Anche il trasporto ssh è più veloce, quindi ne vale la pena comunque.

Nota ulteriore: se si utilizza questo metodo, è necessario specificare gather_facts: falsenel file di definizione del playbook in modo che le attività di impostazione / raccolta dati non vengano eseguite automaticamente prima di arrivare alla fase di test delle password. Se hai bisogno di uno dei fatti sensibili, dovrai chiamare esplicitamente il setuptuo ruolo prima di accedere a uno qualsiasi dei dati normalmente disponibili in luoghi come ansible_devices, ecc. Un buon modo per farlo è chiamare setupcon una whenclausola che controlla se il fatto che stai usando è vuoto o no prima di chiamarlo nel tuo ruolo.


La tua soluzione è buona, ma devi aggiungere un gather_facts: noper smettere di rispondere cercando di connetterti quando
avvii

Hai ragione. Ho gather_facts impostato su off per tutti i miei playbook, quindi devo chiamare esplicitamente 'setup'. Ho dimenticato di menzionarlo nella risposta, lo aggiornerò ora.
Tom Bull,

5

Puoi usarlo --ask-passquando esegui ansible-playbook.

Per le altre attività che hai chiesto, è realizzabile con vari mezzi, ad esempio il modulo di copia.
Anche la disabilitazione dell'accesso root può essere eseguita ad es. modellando sshd_confo inserendo la riga nel file conf.


--ask-pass (che è lo stesso di -k) è quello che sto facendo e ne ho scritto nel commento sopra
petr0
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.