在主机之间分发 ssh 公钥

sou*_*ver 12 provisioning ssh-keys ansible

我正在使用 Ansible 设置一些机器,并且需要在它们之间启用无密码连接。我有一个数据库主站和几个从站。对于初始复制,从服务器需要通过 ssh 连接到主服务器并获取数据库的副本。我不确定将所有奴隶公钥动态添加到 mastersauthorized_keys文件的最佳方法是什么。

我已经考虑过将奴隶公钥作为变量提供,然后通过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
Run Code Online (Sandbox Code Playgroud)

{% %}仅在模板文件中工作的循环,而不是直接在剧本中工作。有什么办法可以在我的剧本中做到这一点?

sou*_*ver 8

我想出了一个对我有用的解决方案。我确实在运行 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
Run Code Online (Sandbox Code Playgroud)

整个剧本可以在github.com/soupdiver/ansible-cluster找到


Leo*_*nes 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
Run Code Online (Sandbox Code Playgroud)

然后我们在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
Run Code Online (Sandbox Code Playgroud)

所以我们基本上是:

  • 在那些仍然没有它们的奴隶上动态创建 ssh 密钥
  • 然后我们使用delegate_to在slave上运行fetch模块,并将它们的ssh pubkeys获取到运行ansible的主机,同时将这个操作的结果保存在一个变量中,这样我们就可以访问获取文件的实际列表
  • 之后,我们继续将获取的 ssh 公钥(以及提供的任何额外公钥)推送到具有authorized_keys模块的主节点(我们使用几个 jinja2 过滤器从上述任务中的变量中挖掘出文件路径)
  • 最后,我们删除本地缓存在运行 ansible 的主机上的公钥文件

在所有主机上拥有相同用户的限制可能可以解决,但从我从您的问题中得到的信息来看,这对您来说可能不是问题(这与我的备份方案更相关)。您当然也可以使密钥类型(rsa、dsa、ecdsa 等)可配置。

更新:哎呀,我最初是使用特定于我的问题的术语编写的,而不是你的!现在应该更有意义了。