【问题标题】:Ansible - managing multiple SSH keys for multiple users & rolesAnsible - 为多个用户和角色管理多个 SSH 密钥
【发布时间】:2017-03-21 20:47:33
【问题描述】:

问题

我正在使用 Ansible 管理许多不同的服务器。每台服务器有多个Linux用户,如readonlyadmin等。

我的 Ansible 项目中还有许多文件,其中包含特定人群的所有 SSH 密钥 - 例如。 AppDevelopersPublicKeysDbaPublicKeys

不同的人群在不同的服务器上具有不同的访问级别。例如。在 WebServer 上,AppDevelopers 具有管理员权限,而 DBA 可能只有读取权限。在数据库服务器上,反之亦然。

为了实现上述目标,我为不同类型的服务器(例如WebAppServerDatabaseServer 等)设置了不同的 Ansible 角色。然后,这些角色会针对它们设置变量 readonly_key_filesadmin_key_files,列出应该具有只读和管理员访问权限的角色的适当密钥文件。

理想的解决方案是:

  1. 确保公钥是专有的 - 例如。如果从 Ansible 中的 AppDeveloperPublicKeys 文件中删除公钥,服务器也会删除此密钥
  2. 只有在实际发生更改时才上传/更改服务器上的文件
  3. 在使用 --diff 选项运行 Ansible 时显示文件的准确差异

我正在使用 Ansible 2.2.0.0

目前尝试的解决方案

以下都不是我想要的:

authorized_key with_file

- authorized_key: user=readonly exclusive=no key={{item}}
  with_file: {{readonly_key_files}}
  • 这不满足要求1,因为它循环了多个文件,所以exclusive必须设置为no

authorized_key with fact

根据https://github.com/ansible/ansible-modules-core/pull/4167/files解决方案

- name: "Generate developer keys from multiple files"
  set_fact: dev_key_list="{{ lookup('file', item) }}"
  register: dev_keys
  with_items: '{{developer_key_files}}'

- name: "Merge developer keys into single list"
  set_fact: dev_keys_string={{ dev_keys.results | map(attribute='ansible_facts.dev_key_list') | join('\n') }}

- authorized_key: user=readonly exclusive=yes key={{dev_keys_string}}
  • 这符合要求 1,但(至少对我而言)不符合要求 2 - 生成的键的顺序似乎不确定,因此多次运行 playbook 会导致 authorized_keys 步骤发生变化,即使没有密钥已从文件中添加/删除。它似乎也不符合要求 3,因为当我使用 --check --diff 运行时,我无法确切看到 Ansible 认为哪些行正在更改,它只是突出显示文件将被更改。

authorized_key with_template

- authorized_key: user=readonly exclusive=no key={{item}}
  with_template: {{readonly_keys.j2}}

readonly_keys.j2 的样子:

{% for key_file in readonly_key_files %}
{%   include '/files/' ~ key_file %}
{% endfor %}
  • 这符合要求 1 和 2,但在要求 3 上再次失败。当我使用 --check --diff 运行时,它只显示 SSH 文件是否会更改,而不是像我一样确切地添加/删除哪些行期待它。

结论

还有其他方法可以解决这个问题吗?似乎在 Ansible 中使用 --diffauthorized_keys 可能存在问题......我能想到的唯一其他方法是根本不使用 authorized_keys,而是将其作为常规文件/模板进行管理,这应该向我显示准确的差异(以及满足要求 1 和 2)。

【问题讨论】:

    标签: ssh ansible ssh-keys ansible-2.x


    【解决方案1】:

    我解决此问题的方法是将变量中的文件名数组传递给我的user-account 角色。然后角色获取每个文件的内容,将它们一起附加到一个换行符分隔的字符串中,最后将此值设置为新用户的 ssh-key。

    .

    剧本文件:

    - hosts: aws-node1
      roles:
        - { role: user-account, username: 'developer1', ssh_public_keyfiles: ['peter-sshkey.pub', 'paul-sshkey.pub'] }
    

    .

    user-account的角色定义:

    - name: add user
      user:
        name: "{{username}}"
    
    
    - name: lookup ssh pubkeys from keyfiles and create ssh_pubkeys_list
      set_fact:
        ssh_pubkeys_list: "{{ lookup('file', item) }}"
      with_items:
        "{{ssh_public_keyfiles}}"
      register: ssh_pubkeys_results_list
    
    
    - name: iterate over ssh_pubkeys_list and join into a string
      set_fact:
        ssh_pubkeys_string: "{{ ssh_pubkeys_results_list.results | map(attribute='ansible_facts.ssh_pubkeys_list') | list | join('\n') }}"
    
    
    - name: update SSH authorized_keys for user {{ username }} with contents of ssh_pubkeys_string
      authorized_key:
        user: "{{ username }}"
        key: "{{ ssh_pubkeys_string }}"
        state: present
        exclusive: yes
    

    【讨论】:

      【解决方案2】:

      我在未回答的问题列表中发现了这个问题,并做了一些研究。在您提出问题后不久,似乎差异功能已添加到 ansible 中的 authorized_keys 模块中。该提交于 2017 年初合并,似乎已包含在 2.3 及更高版本中。看起来您的第三个选项现在应该可以使用,但如果没有您的密钥设置,我无法确定。

      https://github.com/ansible/ansible/commit/b0b7a636d8930a2c7192ea83ff890e4313aaf4d9#diff-e50c31b8374987e7c9dd4795d7f2e89f

      https://github.com/ansible/ansible/pull/19277

      【讨论】:

        猜你喜欢
        • 2020-04-09
        • 2012-07-09
        • 2014-11-29
        • 1970-01-01
        • 2017-07-02
        • 1970-01-01
        • 2014-07-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多