Verteilen Sie die öffentlichen ssh-Schlüssel auf die Hosts

11

Ich richte einige Computer mit Ansible ein und muss kennwortlose Verbindungen zwischen ihnen aktivieren. Ich habe einen Datenbankmaster und mehrere Slaves. Für die erste Replikation müssen die Slaves in den Master ssh und eine Kopie der Datenbank erhalten. Ich bin mir nicht sicher, wie ich am besten alle öffentlichen Slaves-Schlüssel dynamisch zur Master- authorized_keysDatei hinzufügen kann.

Ich habe bereits darüber nachgedacht, die öffentlichen Slaves-Schlüssel als Variablen bereitzustellen und sie dann über das authorized_keyModul hinzuzufügen . Aber dann muss ich die Liste der Schlüssel pflegen. Ich suche nach einem Ansatz, bei dem ich einfach einen weiteren Host zur Slaves-Gruppe hinzufüge und der Rest automatisch funktioniert.

Irgendwelche Ideen?

Aktualisieren:

Bisher habe ich folgenden Pseudocode erhalten:

# 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

Die Schleife {% %}funktioniert nur in Vorlagendateien und nicht direkt in Playbooks. Wie kann ich das in meinem Spielbuch machen?

Suppentaucher
quelle

Antworten:

5

Ich habe eine Lösung gefunden, die für mich funktioniert. Ich erstelle die öffentlichen / privaten Schlüssel auf meinem Computer, von dem aus Ansible ausgeführt wird, und bei der ersten Verbindung setze ich die Schlüssel ein.

Dann füge ich dem Master die Schlüssel aller Slaves wie folgt hinzu:

# 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

Das gesamte Spielbuch finden Sie unter github.com/soupdiver/ansible-cluster .

Suppentaucher
quelle
5

Ich glaube, die folgende Lösung sollte in Ihrem Fall funktionieren. Ich habe es für ein ähnliches Szenario mit einem zentralen Sicherungsserver und mehreren Sicherungsclients verwendet.

Ich habe eine Rolle (sagen wir " db_replication_master "), die dem Server zugeordnet ist, der die Verbindungen empfängt:

    - 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

Dann erstellen wir die eigentlichen Aufgaben in der Rolle 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

Wir sind also im Grunde:

  • Dynamisches Erstellen von SSH-Schlüsseln auf den Slaves, die sie noch nicht haben
  • dann verwenden wir delegate_to die laufen holen Modul auf den Slaves und ihre ssh Pubkeys ansible zum Host holen laufen, auch das Ergebnis dieser Operation in einem variablen Speichern , damit wir die aktuelle Liste der abgerufenen Dateien zugreifen können ,
  • Danach schieben wir normalerweise die abgerufenen ssh-Pubkeys (plus alle zusätzlichen bereitgestellten Pubkeys) an den Masterknoten mit dem Modul " authorized_keys" (wir verwenden einige jinja2-Filter, um die Dateipfade aus der Variablen in der obigen Aufgabe herauszuarbeiten).
  • Schließlich entfernen wir die Pubkey-Dateien, die lokal auf dem Host zwischengespeichert sind, auf dem ansible ausgeführt wird

Die Einschränkung, auf allen Hosts denselben Benutzer zu haben, kann wahrscheinlich umgangen werden, aber was ich aus Ihrer Frage erhalte, ist wahrscheinlich kein Problem für Sie (es ist für mein Sicherungsszenario etwas relevanter). Sie können natürlich auch den Schlüsseltyp (rsa, dsa, ecdsa usw.) konfigurierbar machen.

Update : Hoppla, ich hatte ursprünglich mit einer für mein Problem spezifischen Terminologie geschrieben , nicht mit Ihrer! Sollte jetzt mehr Sinn machen.

Leo Antunes
quelle
0

Ich habe das gleiche Problem und habe es folgendermaßen gelöst:

---
# 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']}}"
Julen Larrucea
quelle