是否可以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 命令限制。