2015-05-13 18 views
13

Sto eseguendo il playbook Ansible e funziona perfettamente su una macchina.prompt ssh ansible problema known_hosts

In una nuova macchina quando provo per la prima volta, viene visualizzato il seguente errore.

17:04:34 PLAY [appservers] ************************************************************* 
17:04:34 
17:04:34 GATHERING FACTS *************************************************************** 
17:04:34 fatal: [server02.cit.product-ref.dev] => {'msg': "FAILED: (22, 'Invalid argument')", 'failed': True} 
17:04:34 fatal: [server01.cit.product-ref.dev] => {'msg': "FAILED: (22, 'Invalid argument')", 'failed': True} 
17:04:34 
17:04:34 TASK: [common | remove old ansible-tmp-*] ************************************* 
17:04:34 FATAL: no hosts matched or all hosts have already failed -- aborting 
17:04:34 
17:04:34 
17:04:34 PLAY RECAP ******************************************************************** 
17:04:34   to retry, use: --limit @/var/lib/jenkins/site.retry 
17:04:34 
17:04:34 server01.cit.product-ref.dev  : ok=0 changed=0 unreachable=1 failed=0 
17:04:34 server02.cit.product-ref.dev  : ok=0 changed=0 unreachable=1 failed=0 
17:04:34 
17:04:34 Build step 'Execute shell' marked build as failure 
17:04:34 Finished: FAILURE 

Questo errore può essere risolto, se prima di andare alla macchina sorgente (da cui sto correndo il playbook ansible) e ssh manualmente al computer di destinazione (come l'utente data) e immettere "sì" per la voce del file known_hosts.

Ora, se eseguo la seconda volta lo stesso ansible playbook, funziona senza errori.

Pertanto, come posso sopprimere il prompt che cosa fornisce SSH durante la prima volta che si effettua la voce ssh known_hosts per un dato utente (cartella ~/.ssh, file known_hosts)?

Ho trovato che posso farlo se uso le seguenti voci di configurazione nel file ~/.ssh/config.

~/.ssh/config

# For vapp virtual machines 
Host * 
    StrictHostKeyChecking no 
    UserKnownHostsFile=/dev/null 
    User kobaloki 
    LogLevel ERROR 

cioè se metto il codice di cui sopra nel file ~/.ssh/config da parte dell'utente di un computer remoto e provare Ansible playbook per la prima volta, ho vinto' t viene richiesto di inserire "sì" e il playbook verrà eseguito correttamente (senza richiedere all'utente di creare manualmente una voce di file known_hosts dalla macchina di origine al computer di destinazione/remoto).

Le mie domande: 1. Quali problemi di sicurezza devo prendere cura se vado ~/.ssh/config modo 2. Come posso passare le impostazioni (quello che c'è nel file di configurazione) come parametri/opzioni per ansible a linea di comando in modo che venga eseguito prima volta su una nuova macchina (senza chiedere conferma/a seconda della voce di file known_hosts sul computer di origine per la macchina di destinazione

risposta

22

la documentazione ansible hanno a section on this Citando:?.

Ansible 1.2.1 e versioni successive hanno abilitato il controllo della chiave dell'host abilitato di default

Se un host viene reinstallato e ha una chiave diversa in "known_hosts", verrà visualizzato un messaggio di errore fino alla correzione. Se un host non è inizialmente in "known_hosts", ciò comporterà la richiesta di conferma della chiave, che si tradurrà in un'esperienza interattiva se si utilizza Ansible, ad esempio cron. Potresti non volerlo.

Se si comprendono le implicazioni e desidera disattivare questo comportamento, è possibile farlo modificando /etc/ansible/ansible.cfg o ~/.ansible.cfg:

[defaults] 
host_key_checking = False 

alternativa questo può essere impostata una variabile di ambiente:

$ export ANSIBLE_HOST_KEY_CHECKING=False 

noti inoltre che hos Il controllo del tasto t in modalità paramiko è ragionevolmente lento, pertanto si consiglia di passare a 'ssh' quando si utilizza questa funzione.

+0

Funziona. Se non voglio cambiare ~/.ansible.cfg, posso ancora usare quella variabile di esportazione. L'unica cosa che guardo a questo punto è: se il mio file di inventario ha un host come xxxx cioè IP, ansible è in grado di eseguire correttamente il playbook sul computer di origine (dove è disponibile l'ansible) MA, se uso hostname.company. fqdn.or.short.hostname.com nel file di inventario, quindi ansible non è in grado di risolvere il nome host sul computer di origine. Se aggiungo la mia voce del server DNS (nameserver 10.11.12.133) a /etc/resolv.conf, allora funziona bene. Qualche idea ? Come posso passare la voce del server DNS ad ansible a linea di comando? –

+0

Si può provare anche questo: ansible-playbook -e 'host_key_checking = False' yourplaybook.yml –

+0

Ansible usa la risoluzione DNS del tuo host, come hai notato. Se il nome host si risolve in un IP funzionerà, ma Ansible non ha (e non dovrebbe) un altro meccanismo per questo. Un trucco che uso per questo genere di cose è inserire una voce in/etc/hosts se il sistema non è nel DNS. –

14

Disabilitare completamente il controllo della chiave dell'host è una cattiva idea dal punto di vista della sicurezza, poiché ti apre agli attacchi man-in-the-middle.

Se si può supporre che la rete corrente non sia compromessa (ovvero, quando si esegue il ssh sulla macchina per la prima volta e viene presentata una chiave, quella chiave è di fatto della macchina e non di un utente malintenzionato), quindi è possibile utilizzare ssh-keyscan e the shell module aggiungere le chiavi i nuovi server al file degli host conosciuti (edit: Stepan's answer fa questo un modo migliore): (. dimostrato qui come si farebbe trovare dopo ec2 provisioning)

- name: accept new ssh fingerprints 
    shell: ssh-keyscan -H {{ item.public_ip }} >> ~/.ssh/known_hosts 
    with_items: ec2.instances 

+0

Accetto, Sarebbe bene usarlo con: become_user "{{someUser}}" –

+2

Decisamente migliore e più sicuro. C'è anche un modulo per farlo http://docs.ansible.com/ansible/known_hosts_module.html –

+0

Vedere la mia risposta http://stackoverflow.com/a/39083724/3114959 (qui sotto) dove uso il modulo 'known_hosts' al contrario di una semplice concatenazione al file 'known_hosts' come suggerito qui. –

17

Per aggiornare il file locale known_hosts, ho finito per usare una combinazione di ssh-keyscan (con per risolvere un nome host a indirizzo IP) e il modulo ansible known_hosts come segue: (nome del file ssh-known_hosts.yml)

- name: Store known hosts of 'all' the hosts in the inventory file 
    hosts: localhost 
    connection: local 

    vars: 
    ssh_known_hosts_command: "ssh-keyscan -T 10" 
    ssh_known_hosts_file: "{{ lookup('env','HOME') + '/.ssh/known_hosts' }}" 
    ssh_known_hosts: "{{ groups['all'] }}" 

    tasks: 

    - name: For each host, scan for its ssh public key 
    shell: "ssh-keyscan {{ item }},`dig +short {{ item }}`" 
    with_items: "{{ ssh_known_hosts }}" 
    register: ssh_known_host_results 
    ignore_errors: yes 

    - name: Add/update the public key in the '{{ ssh_known_hosts_file }}' 
    known_hosts: 
     name: "{{ item.item }}" 
     key: "{{ item.stdout }}" 
     path: "{{ ssh_known_hosts_file }}" 
    with_items: "{{ ssh_known_host_results.results }}" 

Per eseguire tali yml, fare

ANSIBLE_HOST_KEY_CHECKING=false ansible-playbook path/to/the/yml/above/ssh-known_hosts.yml 

Di conseguenza, per ciascun host nell'inventario , tutti gli algoritmi supportati verranno aggiunti/aggiornati nel file known_hosts in nomehost, indirizzo IP record di coppia; come ad esempio

atlanta1.my.com,10.0.5.2 ecdsa-sha2-nistp256 AAAAEjZHN ... NobYTIGgtbdv3K+w= 
atlanta1.my.com,10.0.5.2 ssh-rsa AAAAB3NaC1y ... JTyWisGpFeRB+VTKQ7 
atlanta1.my.com,10.0.5.2 ssh-ed25519 AAAAC3NaCZD ... UteryYr 
denver8.my.com,10.2.13.3 ssh-rsa AAAAB3NFC2 ... 3tGDQDSfJD 
... 

(fornito l'inventario lima assomiglia:

[master] 
atlanta1.my.com 
atlanta2.my.com 

[slave] 
denver1.my.com 
denver8.my.com 

)

A differenza di risposta del Xiong, questo sarebbe di gestire correttamente il contenuto del file known_hosts.

Questa riproduzione è particolarmente utile se si utilizza l'ambiente virtualizzato in cui gli host di destinazione vengono nuovamente ripresi (quindi le chiavi di ssh pub vengono modificate).

2

è inoltre possibile impostarlo dal livello os del server. è necessario configurare il file ssh di configurazione in modo da evitare di controllo ssh per richiedere:

modificare il percorso del file:

/etc/ssh/ssh_config 

ora il commento dalla riga:

StrictHostKeyChecking no 

salvare le modifiche e questo è il

5

Seguire @Stepan la risposta corretta di Vavra.Una versione più breve è:

- known_hosts: 
    name: "{{ item }}" 
    key: "{{ lookup('pipe', 'ssh-keyscan {{ item }},`dig +short {{ item }}`') }}" 
    with_items: 
    - google.com 
    - github.com 
0

Non sarebbe fare qualcosa di simile lavoro per l'innesco del file known_hosts:

ANSIBLE_HOST_KEY_CHECKING=false ansible all -m ping 

Questo dovrebbe collegarsi a ciascun host nell'inventario, l'aggiornamento del file known_hosts per ogni host senza dover inserire "sì" per ciascun prompt, quindi esegue il modulo "ping" su ciascun host?

Un test rapido (l'eliminazione del mio file known_hosts che eseguiva il precedente, eseguito su un'istanza di Ubuntu 16.04) sembrava popolare nel file known_hosts con i loro fingerprint correnti.

@Stepan La soluzione di Vavra non ha funzionato per me poiché stavo usando host con alias (era connesso a IP interni che non avevano DNS disponibile per loro, quindi volevo nomi più descrittivi da riferire a ciascun host nell'inventario e con punto variabile ansible_host sull'IP attuale per ciascuno). Esecuzione di quanto sopra è stato molto più semplice e innescato il mio file known_hosts senza dover disabilitare la verifica della chiave host in ansible o ssh.