Distribuire le chiavi pubbliche ssh tra gli host


11

Sto configurando alcune macchine con Ansible e devo abilitare connessioni meno password tra di loro. Ho un master di database e diversi slave. Per la replica iniziale, gli slave devono immettere ssh nel master e ottenere una copia del database. Non sono sicuro di quale sia il modo migliore per aggiungere dinamicamente tutte le chiavi pubbliche degli slave al authorized_keysfile master .

Ho già pensato di fornire le chiavi pubbliche degli slave come variabili e di aggiungerle tramite il authorized_keymodulo. Ma poi devo mantenere l'elenco delle chiavi. Sto cercando un approccio in cui aggiungo solo un altro host il gruppo degli schiavi e il resto funzionerà automaticamente.

Qualche idea?

Aggiornare:

Finora ho ottenuto il seguente pseudo codice:

# collect public keys from slave machines
- name: collect slave keys
  {% for host in groups['databases_slave'] %}
     shell: /bin/cat /var/lib/postgresql/.ssh/id_rsa.pub
     register: slave_keys #how to add to an array here?
  {% endfor %}

# Tasks for PostgreSQL master
- name: add slave public key
  sudo: yes
  authorized_key: user=postgres state=present key={{ item }}
  with_items: slave_keys

Il ciclo con il {% %}solo funziona in file modello e non direttamente nei playbook. Un modo per farlo nel mio playbook?

Risposte:


5

Ho trovato una soluzione che funziona per me. Creo le chiavi pubbliche / private sul mio computer da dove viene eseguito Ansible e sulla prima connessione inserisco le chiavi.

Quindi aggiungo le chiavi da tutti gli slave al master con il seguente:

# Tasks for PostgreSQL master
- name: add slave public key
  sudo: yes
  authorized_key: user=postgres state=present key="{{ lookup('file', '../../../keys/' + item + '/id_rsa.pub') }}"
  with_items: groups.databases_slave

L'intero playbook è disponibile su github.com/soupdiver/ansible-cluster .


5

Credo che la seguente soluzione dovrebbe funzionare nel tuo caso. Lo sto usando per uno scenario simile con un server di backup centrale e più client di backup.

Ho un ruolo (diciamo " db_replication_master ") associato al server che riceve le connessioni:

    - role: db_replication_master
      db_slaves: ['someserver', 'someotherserver']
      db_slave_user: 'someuser' # in case you have different users
      db_master_user: 'someotheruser'
      extra_pubkeys: ['files/id_rsa.pub'] # other keys that need access to master

Quindi creiamo le attività effettive nel ruolo db_replication_master :

    - name: create remote accounts ssh keys
      user:
        name: "{{ db_slave_user }}"
        generate_ssh_key: yes
      delegate_to: "{{ item }}"
      with_items: db_slaves

    - name: fetch pubkeys from remote users
      fetch:
        dest: "tmp/db_replication_role/{{ item }}.pub"
        src: "~{{db_slave_user}}/.ssh/id_rsa.pub"
        flat: yes
      delegate_to: "{{ item }}"
      with_items: db_slaves
      register: remote_pubkeys
      changed_when: false # we remove them in "remove temp local pubkey copies" below

    - name: add pubkeys to master server
      authorized_key:
        user: "{{ db_master_user }}"
        key: "{{ lookup('file', item) }}"
      with_flattened:
        - extra_pubkeys
        - "{{ remote_pubkeys.results | default({}) | map(attribute='dest') | list }}"

    - name: remove temp local pubkey copies
      local_action: file dest="tmp/db_replication_role" state=absent
      changed_when: false

Quindi siamo sostanzialmente:

  • creando dinamicamente chiavi ssh su quegli schiavi che ancora non li hanno
  • quindi stiamo usando delegate_to per eseguire il modulo fetch sugli slave e recuperare le loro pubke ssh nell'host che esegue ansible, salvando anche il risultato di questa operazione in una variabile in modo da poter accedere all'elenco effettivo dei file recuperati
  • dopodiché si procede normalmente al push delle pubkeys ssh recuperate (più eventuali pubkeys extra fornite) sul nodo master con il modulo authorized_keys (usiamo un paio di filtri jinja2 per estrarre i percorsi dei file dalla variabile nell'attività sopra)
  • infine rimuoviamo i file pubkey memorizzati nella cache locale sull'host in esecuzione ansible

La limitazione di avere lo stesso utente su tutti gli host può probabilmente essere aggirata, ma da quello che ottengo dalla tua domanda, probabilmente non è un problema per te (è leggermente più rilevante per il mio scenario di backup). Ovviamente potresti anche rendere configurabile il tipo di chiave (rsa, dsa, ecdsa, ecc.).

Aggiornamento : ops, avevo originariamente scritto usando una terminologia specifica per il mio problema, non per il tuo! Dovrebbe avere più senso ora.


0

Ho avuto lo stesso problema e l'ho risolto in questo modo:

---
# Gather the SSH of all hosts and add them to every host in the inventory
# to allow passwordless SSH between them
- hosts: all
  tasks:
  - name: Generate SSH keys
    shell: ssh-keygen -q -t rsa -f /root/.ssh/id_rsa -N ''
    args:
      creates: /root/.ssh/id_rsa

  - name: Allow passwordless SSH between all hosts
    shell: /bin/cat /root/.ssh/id_rsa.pub
    register: ssh_keys

  - name: Allow passwordless SSH between all hosts
    lineinfile:
      dest: /root/.ssh/authorized_keys
      state: present
      line:  " {{ hostvars[item]['ssh_keys']['stdout'] }}"
    with_items: "{{ groups['all']}}"
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.