Bagikan kunci publik ssh di antara host

11

Saya menyiapkan beberapa mesin dengan Ansible dan perlu mengaktifkan koneksi yang lebih sedikit di antara mereka. Saya punya master database dan beberapa budak. Untuk replikasi awal, budak perlu ssh ke master dan mendapatkan salinan database. Saya tidak yakin apa cara terbaik untuk secara dinamis menambahkan semua kunci publik budak ke authorized_keysfile master .

Saya sudah berpikir tentang memberikan kunci publik budak sebagai variabel dan kemudian menambahkannya melalui authorized_keymodul. Tetapi kemudian saya harus mempertahankan daftar kunci. Saya mencari pendekatan di mana saya hanya menambahkan host lain pada grup slave dan sisanya akan bekerja secara otomatis.

Ada ide?

Memperbarui:

Sejauh ini saya mendapat kode pseudo berikut:

# 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

Loop dengan {% %}satu - satunya berfungsi dalam file template dan tidak di playbook secara langsung. Adakah cara untuk melakukan ini di buku pedoman saya?

supdiver
sumber

Jawaban:

5

Saya telah menemukan solusi yang bekerja untuk saya. Saya membuat kunci publik / pribadi pada mesin saya dari mana Ansible dijalankan dan pada koneksi pertama saya meletakkan kunci di tempatnya.

Lalu saya menambahkan kunci dari semua budak ke master dengan yang berikut:

# 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

Seluruh playbook dapat ditemukan di github.com/soupdiver/ansible-cluster .

supdiver
sumber
5

Saya percaya solusi berikut ini bisa digunakan untuk Anda. Saya telah menggunakannya untuk skenario serupa dengan server cadangan pusat dan beberapa klien cadangan.

Saya memiliki peran (misalkan " db_replication_master ") yang terkait dengan server yang menerima koneksi:

    - 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

Kemudian kita membuat tugas aktual di peran 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

Jadi kita pada dasarnya:

  • secara dinamis membuat ssh-keys pada budak yang masih belum memilikinya
  • kemudian kita menggunakan delegate_to untuk menjalankan modul fetch pada slave dan mengambil pubkey ssh mereka ke host yang menjalankan ansible, juga menyimpan hasil operasi ini dalam sebuah variabel sehingga kita dapat mengakses daftar aktual file yang diambil
  • setelah itu kita melanjutkan untuk secara normal mendorong ssh pubkeys yang diambil (ditambah setiap pubkeys tambahan yang disediakan) ke node master dengan modul Authorized_keys (kita menggunakan beberapa filter jinja2 untuk menggali filepath dari variabel dalam tugas di atas)
  • akhirnya kami menghapus file-file pubkey yang di-cache di host yang dijalankan

Keterbatasan memiliki pengguna yang sama di semua host mungkin dapat diselesaikan, tetapi dari apa yang saya dapatkan dari pertanyaan Anda, itu mungkin bukan masalah bagi Anda (itu sedikit lebih relevan untuk skenario cadangan saya). Anda tentu saja dapat membuat tipe kunci (rsa, dsa, ecdsa, dll) dapat dikonfigurasi.

Pembaruan : oops, saya awalnya menulis menggunakan terminologi khusus untuk masalah saya , bukan milik Anda! Seharusnya lebih masuk akal sekarang.

Leo Antunes
sumber
0

Saya mendapatkan masalah yang sama, dan saya menyelesaikannya dengan cara ini:

---
# 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
sumber