Распределить открытые ключи SSH среди хостов

11

Я настраиваю некоторые машины с помощью Ansible, и мне нужно разрешить пароли без соединений между ними. У меня есть хозяин базы данных и несколько рабов. Для первоначальной репликации ведомые устройства должны войти в ssh и получить копию базы данных. Я не уверен, каков наилучший способ динамически добавлять все открытые ключи подчиненных в authorized_keysфайл master.

Я уже думал о предоставлении открытых ключей подчиненных в качестве переменных, а затем добавить их через authorized_keyмодуль. Но тогда я должен вести список ключей. Я ищу подход, в котором я просто добавляю другой хост, группу slaves, а остальные будут работать автоматически.

Есть идеи?

Обновить:

До сих пор я получил следующий псевдокод:

# 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

Цикл с {% %}единственным работает в файлах шаблонов, а не в плейбуках напрямую. Есть ли способ сделать это в моей пьесе?

soupdiver
источник

Ответы:

5

Я пришел к решению, которое работает для меня. Я создаю открытый / закрытый ключи на своем компьютере, с которого запускается Ansible, и при первом подключении я помещаю ключи на место.

Затем я добавляю ключи от всех рабов к мастеру со следующим:

# 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

Весь сборник игр можно найти на github.com/soupdiver/ansible-cluster .

soupdiver
источник
5

Я считаю, что следующее решение должно работать в вашем случае. Я использовал его для аналогичного сценария с центральным сервером резервного копирования и несколькими клиентами резервного копирования.

У меня есть роль (скажем, « db_replication_master »), связанный с сервером, получающим соединения:

    - 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

Затем мы создаем актуальные задачи в роли 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

Итак, мы в основном:

  • динамически создавать SSH-ключи на тех рабов, которые до сих пор не имеют их
  • затем мы используем Delegate_to, чтобы запустить модуль fetch на ведомых устройствах и извлечь их ssh pubkeys на хост, на котором выполняется ansible, а также сохранить результат этой операции в переменной, чтобы мы могли получить доступ к фактическому списку полученных файлов.
  • после этого мы продолжаем нормально отправлять извлеченные ssh-публикации (плюс любые дополнительные предоставляемые публикации) на главный узел с модулем авторизованным ключом (мы используем пару фильтров jinja2, чтобы выкопать пути к файлам из переменной в задаче выше)
  • наконец, мы удаляем файлы pubkey, локально кэшированные на хосте, на котором выполняется ansible

Ограничение наличия одного и того же пользователя на всех хостах, вероятно, можно обойти, но из того, что я понял из вашего вопроса, это, вероятно, не проблема для вас (это немного более актуально для моего сценария резервного копирования). Конечно, вы также можете настроить тип ключа (rsa, dsa, ecdsa и т. Д.).

Обновление : ой, я изначально писал с использованием терминологии, специфичной для моей проблемы, а не для вашей Должно быть больше смысла сейчас.

Лев Антунес
источник
0

Я получил ту же проблему, и я решил ее следующим образом:

---
# 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
источник