Rozłóż klucze publiczne ssh między hostami

11

Konfiguruję niektóre maszyny z Ansible i muszę włączyć między nimi połączenia bez hasła. Mam administratora bazy danych i kilku niewolników. W celu wstępnej replikacji urządzenia podrzędne muszą ssh połączyć się z serwerem głównym i uzyskać kopię bazy danych. Nie jestem pewien, jaki jest najlepszy sposób na dynamiczne dodawanie wszystkich kluczy publicznych slave do authorized_keyspliku masters .

Już myślałem o podaniu niewolnikom kluczy publicznych jako zmiennych, a następnie dodaniu ich za pośrednictwem authorized_keymodułu. Ale potem muszę zachować listę kluczy. Szukam podejścia, w którym po prostu dodam innego hosta do grupy niewolników, a reszta będzie działać automatycznie.

Jakieś pomysły?

Aktualizacja:

Do tej pory otrzymałem następujący pseudo kod:

# 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

Pętla z {% %}jedynymi działa w plikach szablonów, a nie bezpośrednio w playbookach. Jakiś sposób to zrobić w moim poradniku?

zupa
źródło

Odpowiedzi:

5

Wymyśliłem rozwiązanie, które działa dla mnie. Tworzę klucze publiczne / prywatne na moim komputerze, z którego uruchamiany jest Ansible i przy pierwszym połączeniu wkładam klucze na miejsce.

Następnie dodaję klucze od wszystkich niewolników do mistrza w następujący sposób:

# 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

Cały podręcznik można znaleźć na github.com/soupdiver/ansible-cluster .

zupa
źródło
5

Uważam, że następujące rozwiązanie powinno działać w twoim przypadku. Użyłem go do podobnego scenariusza z centralnym serwerem kopii zapasowych i wieloma klientami kopii zapasowych.

Mam rolę (powiedzmy „ db_replication_master ”) powiązaną z serwerem odbierającym połączenia:

    - 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

Następnie tworzymy rzeczywiste zadania w roli 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

Jesteśmy w zasadzie:

  • dynamicznie tworząc klucze ssh na tych niewolnikach, którzy wciąż ich nie mają
  • następnie używamy delegate_to, aby uruchomić moduł pobierania na urządzeniach podrzędnych i pobrać ich klucze pub ssh do hosta z uruchomionym programem ansible, również zapisując wynik tej operacji w zmiennej, abyśmy mogli uzyskać dostęp do faktycznej listy pobranych plików
  • potem normalnie wypychamy pobrane klucze pub ssh (plus wszelkie dodatkowe dostarczone klucze pubshow) do węzła głównego z modułem uprawniony_klucz (używamy kilku filtrów jinja2, aby wydobyć ścieżki plików ze zmiennej w powyższym zadaniu)
  • na koniec usuwamy pliki pubkey lokalnie buforowane na hoście z uruchomionym programem ansible

Ograniczenie posiadania tego samego użytkownika na wszystkich hostach prawdopodobnie można obejść, ale z tego, co otrzymałem z twojego pytania, prawdopodobnie nie jest to dla ciebie problem (jest to nieco bardziej odpowiednie dla mojego scenariusza tworzenia kopii zapasowych). Oczywiście możesz również skonfigurować typ klucza (rsa, dsa, ecdsa itp.).

Aktualizacja : Ups, pierwotnie napisałem używając terminologii specyficznej dla mojego problemu, a nie twojej! Teraz powinno to mieć więcej sensu.

Leo Antunes
źródło
0

Mam ten sam problem i rozwiązałem go w ten sposób:

---
# 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
źródło