Specifica la password sudo per Ansible


225

Come posso specificare una password sudo per Ansible in modo non interattivo?

Sto eseguendo il playbook Ansible in questo modo:

$ ansible-playbook playbook.yml -i inventory.ini \
    --user=username --ask-sudo-pass

Ma voglio eseguirlo in questo modo:

$ ansible-playbook playbook.yml -i inventory.ini \
    --user=username` **--sudo-pass=12345**

C'è un modo? Voglio automatizzare il più possibile la distribuzione del mio progetto.


Risposte:


170

È possibile passare la variabile dalla riga di comando tramite --extra-vars "name=value". La variabile della password del Sudo è ansible_sudo_pass. Quindi il tuo comando sarebbe simile a:

ansible-playbook playbook.yml -i inventory.ini --user=username \
                              --extra-vars "ansible_sudo_pass=yourPassword"

Aggiornamento 2017 : Ansible 2.2.1.0 ora utilizza var ansible_become_pass. O sembra funzionare.


7
Dal punto di vista della sicurezza, la migliore risposta, se si aggiunge quanto segue: history -cdopo l'esecuzione di yml.
Kiltek,

12
@kiltek: o aggiungi uno spazio extra all'inizio della riga (in bash) che * non * scriverà la riga .bash_history.
ccpizza,

44
Non è una buona pratica passare le password dalla riga di comando. Chiunque sarà in grado di vedere la password nell'elenco dei processi, mentre il comando è in esecuzione ...
Pavel Chernikov,

22
ancora, non farlo. --ask-sudo-pass
JasonG

2
@scrutari È perfettamente valido in alcune situazioni: Ad esempio: passa da una password iniziale predefinita, conosciuta in tutto il mondo, per iniettare la chiave ssh pubblica dell'utente ... Pensa alla configurazione iniziale di un sistema appena ripreso.
Ceredig,

236

I documenti sconsigliano vivamente di impostare la password sudo in testo normale e di utilizzarli invece --ask-sudo-passdalla riga di comando durante l'esecuzioneansible-playbook


Aggiornamento 2016:

Ansible 2.0 (non 100% quando) contrassegnato --ask-sudo-passcome obsoleto. I documenti ora consigliano --ask-become-passinvece di usarli, sostituendo al contempo l'uso di sudotutti i tuoi playbook con become.


16
Sì, posso capire perché questo è consigliato. Tuttavia, quando utilizziamo Ansible come parte del processo di distribuzione, qual è il modo migliore per automatizzare questo? Non è molto conveniente fermarsi nel mezzo del processo di distribuzione e chiedere all'utente di inserire la password sudo.
Slava Fomin II,

9
Nota --ask-sudo-pass può essere abbreviato in -K, tuttavia, per quanto posso vedere, non c'è modo di gestire un playbook in esecuzione su più server con password diverse (ti chiede solo una volta), quindi penso che sia senza password sudo è la strada da percorrere.
William Turrell,

1
Non sembra funzionare. ma il prossimo suggerimento ("some-host ansible_sudo_pass = 'foobar'") lo fa
nadavkav

--ask-sudo-pass è stato deprecato in precedenza, in 1.9
Chris Betti,

Mi piacerebbe aggiornare la risposta con un link sorgente se ne hai uno.
Deefour

106

Probabilmente il modo migliore per farlo - supponendo che non sia possibile utilizzare la soluzione NOPASSWD fornita da scottod è utilizzare la soluzione di Mircea Vutcovici in combinazione con Ansible vault .

Ad esempio, potresti avere un playbook simile a questo:

- hosts: all

  vars_files:
    - secret

  tasks:
    - name: Do something as sudo
      service: name=nginx state=restarted
      sudo: yes

Qui stiamo includendo un file chiamato secretche conterrà la nostra password sudo.

Useremo ansible-vault per creare una versione crittografata di questo file:

ansible-vault create secret

Questo ti chiederà una password, quindi apri l'editor predefinito per modificare il file. Puoi metterti ansible_sudo_passqui.

es secret::

ansible_sudo_pass: mysudopassword

Salva ed esci, ora hai un secretfile crittografato che Ansible è in grado di decrittografare quando esegui il tuo playbook. Nota: è possibile modificare il file con ansible-vault edit secret(e immettere la password utilizzata durante la creazione del file)

L'ultimo pezzo del puzzle è fornire ad Ansible un --vault-password-fileoggetto che userà per decrittografare il tuo secretfile.

Crea un file chiamato vault.txte in quello inserisci la password che hai usato durante la creazione del secretfile. La password deve essere una stringa memorizzata come una singola riga nel file.

Dai documenti Ansible:

.. assicurati che le autorizzazioni sul file siano tali che nessun altro possa accedere alla tua chiave e non aggiungere la chiave al controllo del codice sorgente

Finalmente: ora puoi eseguire il tuo playbook con qualcosa del genere

ansible-playbook playbook.yml -u someuser -i hosts --sudo --vault-password-file=vault.txt 

Quanto sopra presuppone il seguente layout di directory:

.
|_ playbook.yml
|_ secret
|_ hosts
|_ vault.txt

Puoi leggere di più su Ansible Vault qui: https://docs.ansible.com/playbooks_vault.html


5
Nota: a partire da ansible 1.9, sembra che non sia più possibile utilizzare la variabile ansible_sudo_pass (o ansible_become_pass): "fatale: [...] => Mancare diventa password"
toast38coza

6
Sto usando questa soluzione in produzione, jenkins memorizza la password del vault come variabile d'ambiente offuscata, la scrive in fase di esecuzione in un file temporaneo e procede alla chiamata ansible.
simone cittadini,

6
o più semplicemente: ansible-vault create group_vars/all/ansible.ymle aggiungi ansible_sudo_pass: yourpasswordlì. Non è necessario modificare i libri di gioco o l'inventario
Bouke Versteegh,

1
Ho provato questo, ma ho avuto questo errore:fatal: [localhost]: FAILED! => {"changed": false, "failed": true, "module_stderr": "sudo: a password is required\n", "module_stdout": "", "msg": "MODULE FAILURE", "parsed": false}
JohnnyQ,

8
A che serve un Vault se si memorizza la password nel Vault in testo normale proprio accanto ad esso?
Erik

44

Guardando il codice ( runner/__init__.py), penso che tu possa probabilmente impostarlo nel tuo file di inventario:

[whatever]
some-host ansible_sudo_pass='foobar'

Sembra che ci sia anche qualche disposizione nel ansible.cfgfile di configurazione, ma non implementata in questo momento ( constants.py).


7
Un ottimo modo per configurarlo in modo sicuro sarebbe quello di archiviarlo nella directory host_varso group_varse quindi crittografare il file usando ansible-vault
Kyle,

44

Non credo che Ansible ti permetterà di specificare una password tra le bandiere come desideri. Potrebbero esserci dei punti nelle configurazioni che possono essere impostati, ma ciò renderebbe l'utilizzo di ansible complessivamente meno sicuro e non sarebbe raccomandato.

Una cosa che puoi fare è creare un utente sul computer di destinazione e concedere loro privilegi sudo senza password a tutti i comandi o a un elenco limitato di comandi.

Se esegui sudo visudoe inserisci una riga come la seguente, l'utente 'privilegedUser' non dovrebbe inserire una password quando esegue qualcosa del tipo sudo service xxxx start:

%privilegedUser ALL= NOPASSWD: /usr/bin/service

7
@bschlueter, quindi stai approvando cattive pratiche?
Stephen

1
Non credo sia una buona idea. L'uso di --ask-sudo-pass ha senso per me.
kgpdeveloper,

@simone cittadini Sono totalmente d'accordo, come in effetti questa è la risposta che stavo per dare. Questo è un rischio per la sicurezza.
einarc,

È meno rischioso per la sicurezza se si utilizza sudo senza password per eseguire la distribuzione in staging / prod, ma si desidera utilizzare queste risposte per evitare di digitare la password di accesso del laptop locale quando si esegue la distribuzione nell'host locale ogni 15 minuti tutto il giorno ogni giorno.
Jonathan Hartley,

Come si aggiunge questa linea usando Ansible?
Matthias,

21

La password sudo è memorizzata come variabile chiamata ansible_sudo_pass. Puoi impostare questa variabile in diversi modi:

Per host, nel file degli host dell'inventario ( inventory/<inventoryname>/hosts)

[server]
10.0.0.0 ansible_sudo_pass=foobar

Per gruppo, nel file dei gruppi di inventario ( inventory/<inventoryname>/groups)

[server:vars]
ansible_sudo_pass=foobar

Per gruppo, in gruppo var ( group_vars/<groupname>/ansible.yml)

ansible_sudo_pass: "foobar"

Per gruppo, crittografato ( ansible-vault create group_vars/<groupname>/ansible.yml)

ansible_sudo_pass: "foobar"

18

È possibile impostare la password per un gruppo o per tutti i server contemporaneamente:

[all:vars]
ansible_sudo_pass=default_sudo_password_for_all_hosts

[group1:vars]
ansible_sudo_pass=default_sudo_password_for_group1

14

Mi stavo strappando i capelli per questo, ora ho trovato una soluzione che fa quello che voglio:

1 file crittografato per host contenente la password sudo

/ etc / hosts: ansible /

[all:vars]
ansible_ssh_connection=ssh ansible_ssh_user=myuser ansible_ssh_private_key_file=~/.ssh/id_rsa

[some_service_group]
node-0
node-1

quindi crei per ogni host un file var crittografato in questo modo:

ansible-vault create /etc/ansible/host_vars/node-0

con contenuto

ansible_sudo_pass: "my_sudo_pass_for_host_node-0"

il modo in cui organizzi la password del vault (inserisci tramite --ask-vault-pass) o tramite cfg dipende da te

in base a questo sospetto che tu possa semplicemente crittografare l'intero file hosts ...


Crittografare usando Vault ha più senso per me, anche se ho faticato a usarli ansible-playback. Ho dovuto usare -e @vault/filename.extper usare il caveau con la mia ansible-playbookchiamata.
Alex

9

Un modo più intelligente per farlo è quello di archiviare la sudopassword in un deposito sicuro come LastPass o KeePass e poi passarlo ansible-playbookall'utilizzo -e@ma invece di codificare il contenuto in un file reale, è possibile utilizzare il costrutto -e@<(...)per eseguire un comando in un sub-shell e reindirizzare il suo output (STDOUT) a un descrittore di file anonimo, fornendo in modo efficace la password al file -e@<(..).

Esempio

$ ansible-playbook -i /tmp/hosts pb.yml \
   -e@<(echo "ansible_sudo_pass: $(lpass show folder1/item1 --password)")

Quanto sopra sta facendo diverse cose, analizziamolo.

  • ansible-playbook -i /tmp/hosts pb.yml - ovviamente eseguendo un playbook tramite ansible-playbook
  • $(lpass show folder1/item1 --password)"- esegue l'interfaccia della riga di comando di LastPass lpasse recupera la password da utilizzare
  • echo "ansible_sudo_pass: ...password..." - accetta la stringa 'ansible_sudo_pass:' e la combina con la password fornita da lpass
  • -e@<(..)- mette insieme quanto sopra e collega la subshell di <(...)come descrittore di file ansible-playbookda consumare.

Ulteriori miglioramenti

Se preferisci non digitarlo ogni volta che puoi semplicemente cose del genere. Per prima cosa crea un alias nel tuo .bashrcmodo così:

$ cat ~/.bashrc
alias asp='echo "ansible_sudo_pass: $(lpass show folder1/item1 --password)"'

Ora puoi eseguire il tuo playbook in questo modo:

$ ansible-playbook -i /tmp/hosts pb.yml -e@<(asp)

Riferimenti


1
L'uso di una subshell è un'idea molto intelligente! Per coloro che si chiedono, ecco come appare con l'interfaccia della riga di comando di 1Password:--extra-vars @<(echo ansible_become_pass: $(op get item <item name> | jq --raw-output '.details.sections[0].fields[] | select(.t=="password").v'))
Diti

1
Mi piace perché quando ho controllato la cronologia di cache, la password non è stata esposta in chiaro. Probabilmente è anche vero che se il controllo del sistema è abilitato, il comando viene registrato come lettura di un file, ad es. /dev/fd/63E quindi la password si trova in un descrittore di file temporaneo, non viene divulgata.
JPvRiel,

5

Se hai dimestichezza con il mantenimento delle password in file di testo semplice, un'altra opzione è quella di utilizzare un file JSON con il parametro --extra-vars (assicurati di escludere il file dal controllo del codice sorgente):

ansible-playbook --extra-vars "@private_vars.json" playbook.yml 

Ansible supporta questa opzione dall'1.3 .


5

puoi scrivere la password sudo per il tuo playbook nel file hosts in questo modo:

[host-group-name]
host-name:port ansible_sudo_pass='*your-sudo-password*'

5

Ansible Vault è stato suggerito un paio di volte qui, ma preferisco git-crypt per crittografare i file sensibili nei miei playbook. Se stai usando git per mantenere i tuoi libri di gioco, è un gioco da ragazzi. Il problema che ho riscontrato con Ansible Vault è che inevitabilmente finisco per imbattermi in copie crittografate del file con cui voglio lavorare e devo decifrarlo prima di poter lavorare. git-cryptoffre un migliore flusso di lavoro IMO.

Usando questo, puoi mettere le tue password in una var nel tuo playbook e contrassegnare il tuo playbook come un file crittografato in .gitattributesquesto modo:

 my_playbook.yml filter=git-crypt diff=git-crypt

Il tuo playbook verrà crittografato in modo trasparente su Github. Quindi devi solo installare la tua chiave di crittografia sull'host che usi per eseguire ansible o seguire le istruzioni sulla documentazione con cui configurarla gpg.

C'è una buona domanda e risposta sull'inoltro di gpgchiavi come le ssh-agentchiavi SSH in avanti qui: /superuser/161973/how-can-i-forward-a-gpg-key-via-ssh-agent .


3

Puoi usare l' sshpassutilità come di seguito,

$ sshpass -p "your pass" ansible pattern -m module -a args \
   -i inventory --ask-sudo-pass

3

Utilizzando ansible 2.4.1.0 e le seguenti funzioni:

[all]
17.26.131.10
17.26.131.11
17.26.131.12
17.26.131.13
17.26.131.14

[all:vars]
ansible_connection=ssh
ansible_user=per
ansible_ssh_pass=per
ansible_sudo_pass=per

Ed esegui il playbook con questo inventario come:

ansible-playbook -i inventory copyTest.yml

3

Il mio trucco per automatizzare questo era usare una variabile d'ambiente e accedervi tramite --extra-vars="ansible_become_pass='{{ lookup('env', 'ANSIBLE_BECOME_PASS') }}'".

Esporta un var env, ma evita la cronologia bash / shell (anteponi con uno spazio o altri metodi). Per esempio:

     export ANSIBLE_BECOME_PASS='<your password>'

Cerca env var mentre passa la ansible_become_passvariabile extra in ansible-playbook, ad esempio:

ansible-playbook playbook.yml -i inventories/dev/hosts.yml -u user --extra-vars="ansible_become_pass='{{ lookup('env', 'ANSIBLE_BECOME_PASS') }}'"

Buone risposte alternative:


2

È possibile utilizzare Ansible Vault che codificherà la password in Vault crittografato. Dopodiché puoi usare la variabile di Vault nei playbook.

Alcuni documenti su Ansible Vault:
http://docs.ansible.com/playbooks_vault.html

Lo stiamo usando come deposito per ambiente. Per modificare il vault abbiamo il comando come:
ansible-vault edit inventories/production/group_vars/all/vault

Se vuoi chiamare la variabile del vault devi usare ansible-playbook con parametri come:
ansible-playbook -s --vault-password-file=~/.ansible_vault.password

Sì, stiamo memorizzando la password del vault nella directory locale in testo normale ma non è più pericolosa come memorizzare la password di root per ogni sistema. La password di root è all'interno del file del vault o puoi averla come file sudoers per il tuo utente / gruppo.

Sto raccomandando di usare il file sudoers sul server. Ecco un esempio per l'amministratore di gruppo:
%admin ALL=(ALL) NOPASSWD:ALL



1

Dopo cinque anni, vedo che questo è ancora un argomento molto rilevante. Rispecchiando in qualche modo la risposta di leucos, che trovo la migliore nel mio caso, usando solo strumenti rispondibili (senza alcuna autenticazione centralizzata, token o altro). Ciò presuppone che tu abbia lo stesso nome utente e la stessa chiave pubblica su tutti i server. In caso contrario, ovviamente dovresti essere più specifico e aggiungere le variabili corrispondenti accanto agli host:

[all:vars]
ansible_ssh_user=ansible
ansible_ssh_private_key_file=home/user/.ssh/mykey
[group]
192.168.0.50 ansible_sudo_pass='{{ myserver_sudo }}'

ansible-vault create mypasswd.yml
ansible-vault edit mypasswd.yml

Inserisci:

myserver_sudo: mysecretpassword

Poi:

ansible-playbook -i inv.ini my_role.yml --ask-vault --extra-vars '@passwd.yml'

Almeno in questo modo non è necessario scrivere più le variabili che puntano alle password.


1

La soluzione sopra di @ toast38coza ha funzionato per me; solo che sudo: sì, ora è deprecato in Ansible. Usa diventano e become_user invece.

tasks:
 - name: Restart apache service
   service: name=apache2 state=restarted
   become: yes
   become_user: root

0

possiamo anche usare EXPECT BLOCK in ansible per generare bash e personalizzarlo secondo le tue esigenze

- name: Run expect to INSTALL TA
  shell: |
    set timeout 100
    spawn /bin/sh -i

    expect -re "$ "
    send "sudo yum remove -y xyz\n"

    expect "$ "
    send "sudo yum localinstall -y {{ rpm_remotehost_path_for_xyz }}\n"

    expect "~]$ "
    send "\n"

    exit 0
  args:
  executable: /usr/bin/expect

0

Molto semplice e aggiungi solo nel file variabile:

Esempio:

$ vim group_vars/all

E aggiungi questi:

Ansible_connection: ssh
Ansible_ssh_user: rafael
Ansible_ssh_pass: password123
Ansible_become_pass: password123

Grazie, ma penso che intendi ansible_become_pass invece di Ansible_become_pass.
Krishnom il

0

Solo un addendum, quindi nessun altro subisce il fastidio che ho recentemente fatto:

AFAIK, la soluzione migliore è quella che segue le linee generali di toast38coza. Se ha senso collegare staticamente i tuoi file di password e il tuo playbook, segui il suo modello con vars_files(o include_vars). Se si desidera mantenerli separati, è possibile fornire i contenuti del Vault sulla riga di comando in questo modo:

ansible-playbook --ask-vault-pass -e@<PATH_TO_VAULT_FILE> <PLAYBOOK_FILE>

Questo è ovvio in retrospettiva, ma qui ci sono i gotcha:

  1. Quel sanguinoso segno @ . Se lo lasci fuori, l'analisi fallirà silenziosamente e ansible-playbook procederà come se non avessi mai specificato il file in primo luogo.

  2. È necessario importare esplicitamente il contenuto del vault, con una riga di comando --extra-vars / -e o nel codice YAML. Il --ask-vault-passflag non fa nulla da solo (oltre a richiedere un valore che può o non può essere utilizzato in seguito).

Che tu possa includere le tue "@" e risparmiare un'ora.


-3

Questo ha funzionato per me ... File creato /etc/sudoers.d/90-init-users file con NOPASSWD

echo "user ALL=(ALL)       NOPASSWD:ALL" > 90-init-users

dove "user" è il tuo userid.

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.