在 Ansible 上使用用户输入来(重新)启动 systemd 单元

在 Ansible 上使用用户输入来(重新)启动 systemd 单元

类似的工具加密文件系统与 systemd 结合使用时具有一些优势,因为可以轻松定义依赖性、状态和权限。

由于它需要密码,因此它要么需要系统上的纯文本文件,要么通过标准输入输入密码通过使用systemd-ask-password. 通常首选 stdin 变体,因为纯文本文件中的密码有一些缺点。

尽管Ansible 有一个 systemd 模块它似乎没有提供直接插入此类参数的可能性。

因此,我很好奇使用 Ansible 时处理使用密码输入(重新)重启服务的首选方式是什么。

可以执行类似以下伪代码的操作

- name: Start GoCryptFs
  systemd:
    name: gocryptfs
    state: started
    daemon_reload: true
    args:
      stdin: "{{ gocryptfs_password }}"

答案1

配置加密文件系统使用选项-extpass CMD. 引自男人gocryptfs

使用外部程序(如 ssh-askpass)来提示密码。程序应在 stdout 上返回密码,结尾的换行符会被 gocryptfs 删除。

例如,在远程主机上创建一个返回变量值的脚本gocryptfs_密码

shell> ssh admin@test_11 sudo cat /root/bin/gocryptfs-extpass.sh
#!/bin/sh
echo ${gocryptfs_password}

也可以通过 Ansible 实现自动化

    - file:
        state: directory
        path: /root/bin
        owner: root
        group: wheel
        mode: '0755'
    - copy:
        dest: /root/bin/gocryptfs-extpass.sh
        owner: root
        group: wheel
        mode: '0700'
        content: |
          {{ '#' }}!/bin/sh
          echo ${gocryptfs_password}

将密码放入控制器的文件中,然后加密

shell> cat vault/test_11/gocryptfs_password.yml 
gocryptfs password at test_11

下面的剧本从文件中读取密码并为命令设置环境

shell> cat pb.yml
- hosts: test_11
  vars:
    gocryptfs_password_file: "vault/{{ inventory_hostname }}/gocryptfs_password.yml"
  tasks:
    - command: /root/bin/gocryptfs-extpass.sh
      register: result
      environment:
        gocryptfs_password: "{{ lookup('file', gocryptfs_password_file) }}"
      no_log: true
    - debug:
        var: result.stdout

给出

ok: [test_11] => 
  result.stdout: gocryptfs password at test_11

如果你设法配置加密文件系统使用-extpass /root/bin/gocryptfs-extpass.sh下面的任务应该可以完成这项工作

- name: User systemctl import environment gocryptfs_password
  command: systemctl --user import-environment gocryptfs_password

- name: Start GoCryptFs
  systemd:
    name: gocryptfs
    state: started
    daemon_reload: true
  environment:
    gocryptfs_password: "{{ lookup('file', gocryptfs_password_file) }}"
  no_log: true

(未经测试)


笔记

  • 该方案应该能够满足大部分安全要求:

    • 加密密码远程存储
    • 密码传输是加密的
    • 密码范围仅限于单个任务
  • 将值gocryptfs_密码根据需要。有很多选择。例如,使用密码库。然后,使用社区.常规.密码存储查找插件而不是ansible.builtin.文件

  environment:
    gocryptfs_password: "{{ lookup('community.general.passwordstore',
                                   'test_11/gocryptfs_password' }}"
   shell> ansible-doc -t lookup community.general.passwordstore
   shell> systemctl --user import-environment gocryptfs_password
  • 正确的 Bash 和 shell 脚本变量大写. 引述:“如果它是你的变量,就把它小写。如果你导出它,就把它大写。...对所有作用于单个脚本或块的变量使用‘蛇形命名法’(全部小写和下划线)。”

相关内容