Distribuir chaves públicas ssh entre hosts

10

Estou configurando algumas máquinas com Ansible e preciso ativar menos conexões de senha entre elas. Eu tenho um mestre de banco de dados e vários escravos. Para a replicação inicial, os escravos precisam ssh no mestre e obter uma cópia do banco de dados. Não tenho certeza qual é a melhor maneira de adicionar dinamicamente todas as chaves públicas dos escravos ao arquivo authorized_keys dos mestres.

Já pensei em fornecer as chaves públicas dos escravos como variáveis e adicioná-las por meio do módulo authorized_key . Mas então devo manter a lista de chaves. Eu estou procurando uma abordagem onde eu apenas adicione outro host ao grupo de escravos e o resto funcionará automaticamente.

Alguma idéia?

Atualização:

Até agora eu peguei o seguinte pseudo código:

# 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

O loop com o {% %} só funciona nos arquivos de modelo e não nos livros didáticos diretamente. Qualquer maneira de fazer isso no meu manual?

    
por soupdiver 15.06.2014 / 11:56

3 respostas

5

Eu encontrei uma solução que funciona para mim. Eu crio as chaves públicas / privadas na minha máquina de onde o Ansible é executado e na primeira conexão eu coloco as chaves no lugar.

Então eu adiciono as chaves de todos os escravos ao mestre com o seguinte:

# 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

O manual inteiro pode ser encontrado em github.com/soupdiver/ansible-cluster .

    
por 15.06.2014 / 23:40
4

Acredito que a solução a seguir deve funcionar no seu caso. Eu tenho usado para um cenário semelhante com um servidor de backup central e vários clientes de backup.

Eu tenho um papel (digamos " 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

Em seguida, criamos as tarefas reais na função 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

Então estamos basicamente:

  • criando dinamicamente chaves ssh nos escravos que ainda não os têm
  • então estamos usando delegate_to para executar o módulo fetch nos slaves e buscar suas chaves pub ssh para o host que está sendo executado, também salvando o resultado dessa operação em uma variável para que possamos acessar a lista real de arquivos buscados
  • depois disso, vamos normalmente empurrar os pubs ssh buscados (mais quaisquer pubkeys adicionais fornecidos) para o nó mestre com o módulo authorized_keys (usamos alguns filtros jinja2 para cavar os caminhos de arquivos de a variável na tarefa acima)
  • finalmente, removemos os arquivos pubkey localmente armazenados em cache no host que está sendo executado

A limitação de ter o mesmo usuário em todos os hosts provavelmente pode ser contornada, mas pelo que recebi da sua pergunta, isso provavelmente não é um problema para você (é um pouco mais relevante para meu cenário de backup). Você poderia também fazer o tipo de chave (rsa, dsa, ecdsa, etc) configurável.

Atualização : oops, eu escrevi originalmente usando terminologia específica para o meu problema, não o seu! Deve fazer mais sentido agora.

    
por 16.06.2015 / 23:46
0

Eu tenho o mesmo problema e resolvi assim:

---
# 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']}}"
    
por 17.08.2018 / 20:15