【问题标题】:Is it possible to use Ansible authorized_key exclusive with multiple keys?是否可以将 Ansible authorized_key 独占与多个密钥一起使用?
【发布时间】:2016-12-17 04:24:24
【问题描述】:

我在使用 Ansible 方面相当新,并且一直在阅读 here 和 google,但尚未找到答案。

我的情况是我在服务器上有 1 个用户,但需要将 2-3 个不同的 pub 密钥放入它的 authorized_keys 文件中。

我可以成功删除所有密钥,或使用此脚本添加所有密钥:

---
  - hosts: all

 tasks:
  - name: update SSH keys
    authorized_key:
     user: <user>
     key: "{{ lookup('file', item) }}"
     state: present
     #exclusive: yes
    with_fileglob:
      - ../files/pub_keys/*.pub

使用present 标志,它读取并添加所有键。使用 absent 标志,它会删除所有列出的键。

问题是我有一个仅在服务器上的旧密钥,我想删除/覆盖它,并且为了将来的部署覆盖任何可能在服务器上而不是在我的剧本中的未经授权的密钥。

使用exclusive 标志,它只需要最后一个键并添加它。如果它会循环并重复添加所有键,那就太棒了。如果在 Ansible 中有办法做到这一点,我还没有找到。

有什么方法可以遍历 pub 文件并同时使用 exclusive 选项?

【问题讨论】:

    标签: ubuntu ansible ansible-playbook authorized-keys


    【解决方案1】:

    有什么方法可以循环遍历 pub 文件并同时使用独占选项?

    没有。 docs中有关于循环和独占的说明:

    exclusive:是否从 authorized_keys 文件中删除所有其他未指定的密钥。通过用换行符分隔多个键,可以在单个键字符串值中指定多个键。 此选项不支持循环,因此如果您使用 with_ ,它将在循环的每次迭代中独占,如果您想要文件中的多个键,您需要将它们全部传递给单个批次中的键,如上所述。

    因此,您需要加入所有密钥并一次发送所有密钥。
    像这样的:

    - name: update SSH keys
      authorized_key:
        user: <user>
        key: "{{ lookup('pipe','cat ../files/pub_keys/*.pub') }}"
        state: present
        exclusive: yes
    

    在生产中运行之前检查此代码!

    【讨论】:

    • 天哪,你是救生员!效果很好!我刚刚发现了 lookup 的东西,但试图理解它。非常感谢!
    • 您需要小心,并将 EOL 放在每个 pub 密钥文件的末尾。否则,键可能会串联在一行中。
    【解决方案2】:

    如果您想避免pipe 查找(例如,因为路径与角色无关),您还可以使用filefileglob 查找的组合:

    - name: update SSH keys
      authorized_key:
        user: <user>
        key:  "{% for key in lookup('fileglob', 'pub_keys/*.pub').split(',') %}{{ lookup('file', key) ~ '\n'}}{% endfor %}"
        state: present
        exclusive: yes
    

    【讨论】:

    • 使用“查询”比使用“查找”更好 - 这样您就可以避免“拆分”并获得针对不存在路径的保护:key: "{% for key in query('fileglob', 'pub_keys/*') %}{{ lookup('file', key) ~ '\n'}}{% endfor %}"
    【解决方案3】:

    如果您将用户保留在变量中,则可以使用:

    ---
    
    - hosts: all
      vars_files:
        - roles/users/vars/main.yml
      tasks:
        - name: Allow other users to login to the account
          authorized_key:
            user: user_name
            exclusive: yes
            key: "{{ developers|map(attribute='publish_ssh_key')|join('\n') }}"
    

    roles/users/vars/main.yml 看起来像这样:

    ---
    
    developers:
      - name: user1
        publish_ssh_key: ssh-rsa AAAA...
      - name: user2
        publish_ssh_key: ssh-rsa AAAA...
    

    【讨论】:

    • 这只添加了最后一个键,但根据文档,它应该可以工作“多个键可以通过换行符分隔在单个键字符串值中指定”docs.ansible.com/ansible/authorized_key_module.html你知道为什么坏了?
    • @goetzc 我不知道 :-(
    • 嘿,我有相同的测试键,只是注释不同,然后 Ansible 只添加了最后一个 :)
    【解决方案4】:

    正如我在另一个答案 (Ansible - managing multiple SSH keys for multiple users & roles) 中所写的那样,这是我为我的用例解决此问题的方式。也许在这里有用?

    我将变量中的文件名数组传递给我的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
    

    【讨论】:

      【解决方案5】:

      与前面的答案相同的基本概念,但只使用变量并从 github 或 gitlab 之类的 url 中提取键。

      #Vars
      ssh_users:
        - user1
        - user2
      ssh_key_urls: "{{ ssh_users | map('regex_replace', '^(.*)$', 'https://key_server/\\1.keys') | list }}"
      authorized_keys: "{% for u in ssh_key_urls %}{{ lookup('url', u, split_lines=False) }}\n{% endfor %}"
      
      #task
      - name: setup authorized_keys
        authorized_key:
          key: "{{ authorized_keys }}"
          state: present
          exclusive: true
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-02-03
        • 2020-08-26
        • 2019-08-29
        • 1970-01-01
        • 2016-09-14
        • 2021-05-13
        • 2011-06-04
        • 2011-10-25
        相关资源
        最近更新 更多