如何为 Ansible 处理程序创建适当的 sudoer 规则?

如何为 Ansible 处理程序创建适当的 sudoer 规则?

是否可以become在处理程序中使用?

我们在 RHEL 7.4 机器上运行 ansible 2.9.3。我们有一个用户正在修改守护进程 (Consul) 的一些配置文件,我们希望服务在任何配置更改后重新启动。我们在任务中有一个通知和一个处理程序。

文件已正确修改,处理程序已收到通知并运行。但是,由于 Ansible 失败退出,因此 sudo 规则无法正常工作:

"module_stderr": "sudo: a password is required\n"

当他们从命令行运行它时,用户可以使用 sudo 命令运行他们想要的任何 systemctl 命令;例如,sudo systemctl restart consul并且sudo systemctl restart consul.service运行良好。只有 Ansible 处理程序需要密码。

这是我们的处理程序:

---

- name: Restart consul
  service:
    name: consul
    state: restarted
  become: yes
  become_user: root
  become_method: sudo

Ansible 想要 sudoers 文件中的什么魔法?我从输出中寻找线索,ansible -vvv但它只告诉我以下内容。它似乎想要运行类似

sudo -H -S -n  -u root /bin/sh -c '"'"'echo BECOME-SUCCESS-hltnfuwykrbhkmyixwzzockacxeosntn ; /usr/bin/python /home/consinstall/.ansible/tmp/ansible-tmp-1584133543.53-230020740311861/AnsiballZ_systemd.py'"'"'

这不可能放在我们的 sudoers 文件中。以下是处理程序的输出:

RUNNING HANDLER [workdir : Restart consul] *****************************************************************************************************
task path: /home/consinstall/bitbucket/workdir/roles/deploy/handlers/main.yml:3
<testhost01> ESTABLISH LOCAL CONNECTION FOR USER: consinstall
<testhost01> EXEC /bin/sh -c 'echo ~consinstall && sleep 0'
<testhost01> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /home/consinstall/.ansible/tmp/ansible-tmp-1584133543.53-230020740311861 `" && echo ansible-tmp-1584133543.53-230020740311861="` echo /home/consinstall/.ansible/tmp/ansible-tmp-1584133543.53-230020740311861 `" ) && sleep 0'
Using module file /usr/lib/python2.7/site-packages/ansible/modules/system/systemd.py
<testhost01> PUT /home/consinstall/.ansible/tmp/ansible-local-79139pfL0dr/tmpauDoVw TO /home/consinstall/.ansible/tmp/ansible-tmp-1584133543.53-230020740311861/AnsiballZ_systemd.py
<testhost01> EXEC /bin/sh -c 'chmod u+x /home/consinstall/.ansible/tmp/ansible-tmp-1584133543.53-230020740311861/ /home/consinstall/.ansible/tmp/ansible-tmp-1584133543.53-230020740311861/AnsiballZ_systemd.py && sleep 0'
<testhost01> EXEC /bin/sh -c 'sudo -H -S -n  -u root /bin/sh -c '"'"'echo BECOME-SUCCESS-hltnfuwykrbhkmyixwzzockacxeosntn ; /usr/bin/python /home/consinstall/.ansible/tmp/ansible-tmp-1584133543.53-230020740311861/AnsiballZ_systemd.py'"'"' && sleep 0'
<testhost01> EXEC /bin/sh -c 'rm -f -r /home/consinstall/.ansible/tmp/ansible-tmp-1584133543.53-230020740311861/ > /dev/null 2>&1 && sleep 0'
fatal: [testhost01]: FAILED! => {
    "changed": false, 
    "invocation": {
        "module_args": {
            "daemon_reexec": false, 
            "daemon_reload": false, 
            "enabled": null, 
            "force": null, 
            "masked": null, 
            "name": "consul", 
            "no_block": false, 
            "scope": null, 
            "state": "restarted", 
            "user": null
        }
    }, 
    "msg": "Unable to start service consul: Job for consul.service failed because the control process exited with error code. See \"systemctl status consul.service\" and \"journalctl -xe\" for details.\n"
}
META: ran handlers

NO MORE HOSTS LEFT *******************************************************************************************************************************************

PLAY RECAP ***************************************************************************************************************************************************
testhost01                : ok=2    changed=1    unreachable=0    failed=1    skipped=2    rescued=0    ignored=0   

答案1

Ansible 并不是简单地运行systemctl。服务模块会确定系统的正确服务管理器,然后传输具有适当状态报告和错误检查的适当 Python 模块。

必要的 sudo 规则是以 become_user 身份运行任意 Python 脚本。几乎不可能限制这一点,因此在限制较少的环境中,Ansible 用户倾向于让 Ansible 用户 sudo 来运行所有。

远程 Ansible ssh 登录并成为 root 的另一种方法是从已有特权的进程运行游戏。想想 ansible-pull 样式的克隆并从 root 的 crontab 运行。对于不需要它的任务,可以成为较低权限的用户。

从技术上讲,原始模块不需要运行任何脚本,但这严重限制了 Ansible,因为您无法使用模块。

对此的另一篇文章:无法在 Ansible 中使用 sudo 命令限制

相关内容