无需密码检查的Ansible sudo命令

4
我希望在完全自动化的情况下使用ansible,无法手动输入密码。为了解决这个问题,我使用SSH公钥连接服务器,并在我的sudoers配置中列出了几个命令,例如apt-get install *,所以我不需要密码来运行它们。例如sudo apt-get install git
然而,如果在playbook中设置becomeTrue,ansible会询问我不需要的密码。
以下是一些问题:
  • 如何告诉ansible以sudo身份运行命令,而不要求输入密码?
  • 您是否知道另一种在不需要密码的情况下安装apt软件包的方法?
  • 我应该使用其他的become方法吗?

sudoers配置文件

myuser ALL = NOPASSWD: /usr/bin/apt-get install *

ansible

- name: install the latest version of ntpdate
  package:
    name: ntpdate
    state: latest
  become: True

生成以下内容:

failed: [x.x.x.x] (item=ntpdate) => {"failed": true, "item": "python3-dev", "module_stderr": "", "module_stdout": "sudo: a password is required\r\n", "msg": "MODULE FAILURE", "rc": 1}

我通常的做法是让一个用户拥有无需密码的sudo访问权限。 - Tejaswi
这就是我在我的sudoers文件中所做的,但是ansible仍然要求我输入密码。 - azmeuk
您能否不使用密码,通过该用户 SSH 访问目标主机? - Tejaswi
到目前为止,有没有任何解决方案? - Ori Wiesel
5个回答

2
简单的回答是,如果没有启用所有命令(或至少启用python),你无法完成它。
Ansible不会按照你期望的方式运行命令。它运行Python脚本。当你使用-vvv执行ansible-playbook时,你可以看到确切的命令。它们要复杂得多,要启用它们,你需要将它们添加到sudoers中,例如:
sudo -H -S -n -u root /bin/sh -c '"'"'echo BECOME-SUCCESS-xxxxxx;
  /usr/bin/python /var/www/.ansible/tmp/ansible-tmp-xxxxxxxx/apt.py;
  rm -rf "/var/www/.ansible/tmp/ansible-tmp-xxxxxxxx/" > /dev/null 2>&1'"'"'
  && sleep 0

麻烦的是,所有空格、引号和其他特殊字符都是相关的。除非你通过反复尝试并用通配符替换字符来获得正确的命令模式,否则系统将不允许以提升的权限运行该命令。实际上,你将无法将Ansible运行的所有命令列入白名单。

唯一的例外是raw模块,它可以完整地运行给定的命令。


我可以通过将ansible使用的命令添加到sudoers例外中来解决这个问题。然而,问题在于ansible在运行任何sudo命令之前都会检查密码,无论命令是什么:sudo -H -S -n -u root /bin/sh -c '"'"'echo BECOME-SUCCESS-xxxxxx; /usr/bin/python /var/www/.ansible/tmp/ansible-tmp-xxxxxxxx/apt.py; rm -rf "/var/www/.ansible/tmp/ansible-tmp-xxxxxxxx/" > /dev/null 2>&1'"'"' && sleep 0 - azmeuk
我也想避免使用raw,因为ansible的目的就是自动化一切 :) - azmeuk
不,它没有询问,但它抱怨没有根密码,并退出。请参见主要问题中的ansible输出。 - azmeuk
@azmeuk 因为您没有添加 Ansible 尝试运行的确切命令。尝试使用通配符而不是空格、引号等。您在 sudoers 中输入的内容对所有这些都很敏感。这就是我写它实际上是不可能的意思。 - techraf

1

在我所编写的所有Ansible playbook中,我只需要执行以下两个步骤,以便任务运行时具有become:True

  1. 在目标主机上创建文件/etc/sudoers.d/demo,内容如下:

    demo ALL=(ALL) NOPASSWD:ALL

  2. 使用ssh-copy-id将ssh id从Ansible主机复制到目标主机


1

模板/无sudo

%sudo  ALL=(ALL) NOPASSWD: ALL
%sudo  ALL=(ALL) NOPASSWD: /sbin/poweroff, /sbin/reboot, /sbin/shutdown

tasks/main.yml

- name: Sudoers no password
  raw: echo '{{ user_password }}' | sudo -S sh -c 'echo "{{ lookup('file', 'templates/without_sudo') }}" > /etc/sudoers.d/without_sudo'

ansible命令的其余部分不需要sudo权限


1
你可以在命令中使用ansible的 'command' 模块,加上sudo作为命令的一部分,而不是使用 'become: yes'。
- name: install the latest version of ntpdate
  command: 'sudo apt-get update ntpdate'

这样做的缺点是可移植性较差。好处是,它能够正常工作...而且你只需要将特定命令列入白名单即可。

-1

在我看来,如果你将你的节点设置为=(ALL) NOPASSWD:ALL,那么任何人,包括黑客都可以访问你的节点。

所以我建议,

ansible-playbook <name>.yml --ask-sudo-pass

这将要求您的节点sudo密码。我猜您知道您节点的凭据,因此您可以执行操作。


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