如何使用Ansible playbook管理trusted.gpg.d中的keyring文件,因为apt-key已被弃用?

26

apt-key被弃用之前,我使用Ansible playbooks在我的服务器上添加和更新密钥。目前,apt-key不再更新密钥。经过一些搜索,我发现现在需要使用gpg。然而,我有很多服务器,我不想为每个服务器手动执行此操作。是否有一种方法可以使用Ansible来管理我的密钥环,包括gpg

以下是我的Ansible任务,其中包含已弃用的apt-key

- apt_key:
  url: "https://packages.treasuredata.com/GPG-KEY-td-agent"
  state: present

- apt_repository:
  repo: "deb http://packages.treasuredata.com/3/ubuntu/{{ ansible_distribution_release }}/ {{ ansible_distribution_release }} contrib"
  state: present
  filename: "treasure-data" # Name of the pre-compiled fluentd-agent

我尝试了apt-key update,但对我没有用。如果密钥已经存在但已过期,则不再更新它。


1
根据我在文档中的阅读,apt_key 现在在内部使用 gpg。你的 Ansible 版本是多少?如果是旧版本,你考虑过升级 Ansible 吗? - β.εηοιτ.βε
你好,我正在使用 Ansible 2.10.17;我可以升级 Ansible,但说实话我不理解“under the hood”这个注释的含义 :( - ecemnaz
我的意思是,模块被称为 apt_key 并不意味着它使用二进制文件 apt-key。实际上,大多数 Ansible 模块并不使用任何系统 OS 命令,而是使用 Python 工具,因为 Ansible 全部基于 Python。参见:Ansible 通过连接到节点并向其推送名为“Ansible 模块”的小程序来工作。这些程序编写成所需系统状态的资源模型。然后,Ansible 执行这些模块(默认情况下通过 SSH),并在完成时将它们删除。 - β.εηοιτ.βε
3
但是注意事项 https://docs.ansible.com/ansible/latest/collections/ansible/builtin/apt_key_module.html#notes 明确指出 “apt-key 命令已被弃用,并建议在 trusted.gpg.d 中管理 keyring 文件。有关详细信息,请参见 Debian wiki。此模块仅用于向后兼容那些仍然使用 apt-key 作为管理 apt 存储库密钥的主要方式的系统。” 因此,看起来 apt_key 不再适用... - lorenzo-bettini
是的,我同意。这不再适用了。我必须手动更新服务器上过期密钥,这对我产生了很大影响...我找不到新的解决方法。任何建议都将不胜感激。 - ecemnaz
3个回答

16
简而言之,您需要将具有正确扩展名的GPG密钥放入一个默认不被搜索的单独目录,并将您的存储库配置指向该特定文件。
有关为什么需要一个单独目录的更多信息,请参阅此答案中对“警告:apt-key已弃用。请在trusted.gpg.d中管理密钥环文件”警告:apt不会接受以.gpg扩展名保存的ASCII GPG密钥。 您可以通过file命令验证您是否具有旧的ASCII GPG格式(.asc)还是较新的二进制GPG格式(.gpg)。
# file elastic-old.gpg
elastic-old.gpg: PGP public key block Public-Key (old)

# file elastic.gpg    
elastic.gpg: PGP/GPG key public ring (v4) created Mon Sep 16 17:07:54 2013 RSA (Encrypt or Sign) 2048 bits MPI=0xd70ed6cd267c5b3e...

如果您的密钥是旧格式,您可以使用.asc扩展名,或者您可以选择通过gpg --dearmor elastic.gpg将其解码为新的二进制格式,并使用.gpg扩展名。
解码步骤对于ansible自动化来说很麻烦,所以我建议您直接使用上游提供的任何格式。
在Ubuntu 22.04上,有一个预期使用的文件夹,它没有预加载 - /etc/apt/keyrings - 或者您可以创建自己的目录并使用它。
至于Ansible部分,您可以使用get_urlfile将GPG密钥推送到系统上,然后像以前一样使用apt_repository添加存储库,同时指定密钥环。
使用二进制GPG格式和.gpg扩展名。
- name: Add Example GPG key
  ansible.builtin.get_url:
    url: https://example.com/example.gpg
    dest: /etc/apt/keyrings/example.gpg
    mode: '0644'
    force: true

或者如果上游还没有切换过来,可以使用.asc扩展名。
- name: Add Example GPG key
  ansible.builtin.get_url:
    url: https://example.com/example.gpg
    dest: /etc/apt/keyrings/example.asc
    mode: '0644'
    force: true

然后,您可以像以前一样使用apt_repository模块来定义您的存储库。
- name: Add Example repo
  ansible.builtin.apt_repository:
    filename: example-repo
    repo: 'deb [signed-by=/etc/apt/keyrings/example.gpg] https://example.com/packages/8.x/apt stable main'

请记住,apt_repository使用旧的.list格式而不是新的符合DEB822标准的.sources格式。
如果您想/需要使用较新的DEB822格式,并且您运行的是Ansible 2.15或更高版本,您应该使用deb822_repository模块。
如果您被迫使用较旧版本的Ansible核心,您可以自己进行类似的模板处理:

tasks/main.yaml

- name: Add Elastic repo
  notify: apt update force
  ansible.builtin.template:
    src: repo.j2
    dest: /etc/apt/sources.list.d/elastic-8.x.sources
    mode: '0644'
  vars:
    repo_name: Example PPA
    repo_uris: https://example.com/packages/8.x/apt
    repo_suites: stable
    repo_components: main
    repo_signed_by: /etc/apt/keyrings/example.gpg

templates/repo.j2

X-Repolib-Name: {{ repo_name }}
Types: deb
URIs: {{ repo_uris }}
Suites: {{ repo_suites }}
{% if repo_components is defined %}
Components: {{ repo_components }}
{% endif %}
Signed-By: {{ repo_signed_by }}

5
在 Ansible 中,是否有一种方法可以在将服务器文件(https://example.com/example.gpg)保存到本地文件夹(/etc/apt/keyrings/example.gpg)之前对其进行解密? - Janthelme
1
只是为了让上面更清楚:有没有一种通过Ansible进行去除装甲的方法? - Janthelme
6
此问题评论中所建议的,您可以将dest文件命名为.asc扩展名(而不是.gpg),以使其在无需额外解密步骤的情况下正常工作。 - geerlingguy
2
提示:如果您作为root用户自己创建了/etc/apt/keyrings目录(可能是因为您的操作系统没有预装它),请记得赋予它“o+x”权限,否则它将无法正常工作。 - Zero3

10
为了进一步解释 @geerlingguy 的评论,关于使用 .asc 扩展名,这是我最终添加 Telegraf 存储库的方法。请注意,在 get_url 和 apt_repository 任务中都使用了 influxdb.asc。
- name: Install InfluxDB key
  get_url:
    url:  https://repos.influxdata.com/influxdb.key
    dest: /etc/apt/trusted.gpg.d/influxdb.asc

- name:  Add InfluxDB repository
  apt_repository:
    repo:  "deb [signed-by=/etc/apt/trusted.gpg.d/influxdb.asc] https://repos.influxdata.com/debian stable main"
    state: present
    update_cache: yes

- name:  Install telegraf
  package:
    name:  telegraf
    state: present

使用此方法,您可以完全绕过gpg --dearmor步骤。

4
“证书绝不能放置在/etc/apt/trusted.gpg.d中” - ændrük

0

基于上述内容创建了一个使用set_fact的起点。 这样更容易将相同代码复制/粘贴到其他需要中。

提供3个变量,然后您就可以开始了。 我插入了sm-前缀,只是为了让我清楚地看到我的脚本将它们放在那里,而不是任何其他过程。

- set_fact:
     repoid: nginx
     repo_key_url: https://nginx.org/keys/nginx_signing.key
     repo_sources_list_url: "http://nginx.org/packages/ubuntu {{ os_release_name }} nginx"

- name: nginx repo - add gpg key as asc so apparmor fix not needed
  get_url:
    url: "{{ repo_key_url }}"
    dest: /etc/apt/keyrings/sm-{{ repoid }}.asc
    mode: '0644'
    force: true

- name: nginx repo - add to sources.list.d 
  apt_repository:
    filename: sm-{{repoid}}-repository
    repo: 'deb [signed-by=/etc/apt/keyrings/sm-{{ repoid }}.asc] {{ repo_sources_list_url }}'
    state: present

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接