为Ansible指定sudo密码

Sla*_* II 202 ansible

如何以非交互方式为Ansible指定sudo密码?

我正在运行这样的Ansible剧本:

__CODE__

但我想像这样运行它:

__CODE__ --sudo通= 12345

有办法吗?我想尽可能地自动化我的项目部署.

dee*_*our 218

文档 强烈建议不要在纯文本中设置sudo密码,而是--ask-sudo-pass在运行时在命令行上使用ansible-playbook


2016年更新:

Ansible 2.0(不是100%时)标记--ask-sudo-pass为已弃用.这些文档现在建议使用--ask-become-pass,同时也交换使用sudo整个剧本become.

  • 是的,我明白为什么这是推荐的.但是,当我们将Ansible用作部署过程的一部分时,有什么更好的自动化方法?在部署过程中停止并要求用户输入sudo密码并不是很方便. (15认同)
  • 注意--ask-sudo-pass可以被删除到-K,但是,据我所知,没有办法处理在具有不同密码的多个服务器上运行的剧本(它只询问你一次),所以我认为无密码sudo是要走的路. (9认同)

Ale*_*tin 149

您可以通过命令行传递变量--extra-vars "name=value".Sudo密码变量是ansible_sudo_pass.所以你的命令看起来像:

ansible-playbook playbook.yml -i inventory.ini --user=username \
                              --extra-vars "ansible_sudo_pass=yourPassword"
Run Code Online (Sandbox Code Playgroud)

2017年更新:Ansible 2.2.1.0现在使用var ansible_become_pass.要么似乎工作.

  • 在命令行上传递密码不是一个好习惯.任何人都可以在进程列表中看到密码,而命令正在执行... (38认同)
  • 不过,就是不要这样做.--ask-须藤通 (19认同)
  • @kiltek:*或*在行的开头(在bash中)添加一个额外的空格,这将_*不*_将该行写入`.bash_history`. (11认同)
  • 从安全角度来看,如果添加以下内容,最好的答案是:执行yml后的`history -c`. (7认同)
  • @scrutari 在某些情况下它是完全有效的:例如:从默认的、世界已知的初始密码更改为注入用户的公共 ssh 密钥......想想新重新映像系统的初始配置。 (3认同)
  • 如果您想在 GitLab CI/CD 运行程序上运行 Ansible,并且密码位于受保护的存储库变量中并在合并时传递给运行程序,则无法以交互方式提供密码。如果在命令行上传递密码的整个管道和环境都是安全的,那么这种姿势就很好。 (2认同)

toa*_*oza 101

可能最好的方法 - 假设您不能使用scottod提供的NOPASSWD解决方案是将Mircea Vutcovici的解决方案与Ansible保险库结合使用.

例如,你可能有一个像这样的剧本:

- hosts: all

  vars_files:
    - secret

  tasks:
    - name: Do something as sudo
      service: name=nginx state=restarted
      sudo: yes
Run Code Online (Sandbox Code Playgroud)

这里我们包含一个名为的文件secret,其中包含我们的sudo密码.

我们将使用ansible-vault来创建此文件的加密版本:

ansible-vault create secret
Run Code Online (Sandbox Code Playgroud)

这将要求您输入密码,然后打开默认编辑器以编辑该文件.你可以把你ansible_sudo_pass放在这里.

例如secret::

ansible_sudo_pass: mysudopassword
Run Code Online (Sandbox Code Playgroud)

保存并退出,现在您有一个加密secret文件,Ansible可以在您运行Playbook时解密.注意:您可以使用ansible-vault edit secret(并输入创建文件时使用的密码)编辑文件

最后一个难题是为Ansible提供一个--vault-password-file用于解密secret文件的方法.

创建一个名为的文件vault.txt,然后输入您在创建secret文件时使用的密码.密码应该是在文件中作为单行存储的字符串.

来自Ansible Docs:

..确保文件的权限是这样的,没有其他人可以访问您的密钥,也不会将您的密钥添加到源代码管理

最后:你现在可以运行你的剧本了

ansible-playbook playbook.yml -u someuser -i hosts --sudo --vault-password-file=vault.txt 
Run Code Online (Sandbox Code Playgroud)

以上是假设以下目录布局:

.
|_ playbook.yml
|_ secret
|_ hosts
|_ vault.txt
Run Code Online (Sandbox Code Playgroud)

您可以在此处阅读有关Ansible Vault的更多信息:https://docs.ansible.com/playbooks_vault.html

  • 我在生产中使用这个解决方案,jenkins将Vault密码存储为混淆的环境变量,在运行时将其写入临时文件并继续调用ansible. (6认同)
  • 如果您将密码以纯文本形式存储在保险库旁边,那么保险库有什么用呢? (6认同)
  • 注意:从ansible 1.9开始,您似乎无法再使用ansible_sudo_pass(或ansible_become_pass)变量:"致命:[...] =>缺少成为密码" (5认同)
  • 或者更简单:``ansible-vault create group_vars/all/ansible.yml``并在那里添加``ansible_sudo_pass:yourpassword``.无需更改剧本或库存 (5认同)

leu*_*cos 45

查看代码(runner/__init__.py),我认为你可以在库存文件中设置它:

[whatever]
some-host ansible_sudo_pass='foobar'
Run Code Online (Sandbox Code Playgroud)

ansible.cfg配置文件中似乎也有一些配置,但现在没有实现(constants.py).

  • 安全配置它的一个好方法是将它存储在`host_vars`或`group_vars`目录中,然后使用[ansible-vault]加密文件(http://docs.ansible.com/playbooks_vault.html) (7认同)

小智 43

我不认为ansible会让你在标志中指定一个密码.可以在配置中的某处设置这可以设置但是这将使得使用ansible总体上不太安全并且不会被推荐.

您可以做的一件事是在目标计算机上创建用户,并为所有命令或受限制的命令列表授予无密码sudo权限.

如果您运行sudo visudo并输入如下所示的行,则用户'privilegedUser'在运行以下内容时不必输入密码sudo service xxxx start:

%privilegedUser ALL= NOPASSWD: /usr/bin/service
Run Code Online (Sandbox Code Playgroud)

  • @bschlueter所以你赞同不良做法? (7认同)

Bou*_*egh 21

sudo的密码存储为一个叫做变量ansible_sudo_pass.您可以通过以下几种方式设置此变量:

每个主机,在您的库存主机文件(inventory/<inventoryname>/hosts)中

[server]
10.0.0.0 ansible_sudo_pass=foobar
Run Code Online (Sandbox Code Playgroud)

每组,在您的库存组文件(inventory/<inventoryname>/groups)中

[server:vars]
ansible_sudo_pass=foobar
Run Code Online (Sandbox Code Playgroud)

每组,在组变量(group_vars/<groupname>/ansible.yml)

ansible_sudo_pass: "foobar"
Run Code Online (Sandbox Code Playgroud)

每组,加密(ansible-vault create group_vars/<groupname>/ansible.yml)

ansible_sudo_pass: "foobar"
Run Code Online (Sandbox Code Playgroud)


Mir*_*ici 17

您可以一次为组或所有服务器设置密码:

[all:vars]
ansible_sudo_pass=default_sudo_password_for_all_hosts

[group1:vars]
ansible_sudo_pass=default_sudo_password_for_group1
Run Code Online (Sandbox Code Playgroud)


gre*_*e83 13

我正在把头发撕成一片,现在我找到了一个能满足我想要的解决方案:

每个包含sudo密码的主机的1个加密文件

的/ etc/ansible /主机:

[all:vars]
ansible_ssh_connection=ssh ansible_ssh_user=myuser ansible_ssh_private_key_file=~/.ssh/id_rsa

[some_service_group]
node-0
node-1
Run Code Online (Sandbox Code Playgroud)

然后你为每个主机创建一个加密的var文件,如下所示:

ansible-vault create /etc/ansible/host_vars/node-0
Run Code Online (Sandbox Code Playgroud)

内容

ansible_sudo_pass: "my_sudo_pass_for_host_node-0"
Run Code Online (Sandbox Code Playgroud)

如何组织金库密码(通过--ask-vault-pass输入)或cfg由您决定

基于此我怀疑你可以加密整个主机文件...


slm*_*slm 8

一种更精明的方法是将sudo密码存储在安全的保管库(例如LastPassKeePass)中,然后将其传递给ansible-playbook使用,-e@但您可以使用该结构-e@<(...)在目录中运行命令,而不是对实际文件中的内容进行硬编码。子外壳程序,并将其输出(STDOUT)重定向到匿名文件描述符,从而有效地将密码提供给-e@<(..)

$ ansible-playbook -i /tmp/hosts pb.yml \
   -e@<(echo "ansible_sudo_pass: $(lpass show folder1/item1 --password)")
Run Code Online (Sandbox Code Playgroud)

上面做了几件事,让我们分解一下。

  • ansible-playbook -i /tmp/hosts pb.yml -显然是通过ansible-playbook运行一个剧本
  • $(lpass show folder1/item1 --password)"-运行LastPass CLI lpass并检索要使用的密码
  • echo "ansible_sudo_pass: ...password..." -接受字符串“ ansible_sudo_pass:”,并将其与提供的密码组合 lpass
  • -e@<(..)-将以上内容放在一起,并连接的子外壳<(...)作为ansible-playbook要使用的文件描述符。

进一步改进

如果您不想每次都键入该命令,则可以简单地输入以下内容。首先.bashrc像这样创建一个别名:

$ cat ~/.bashrc
alias asp='echo "ansible_sudo_pass: $(lpass show folder1/item1 --password)"'
Run Code Online (Sandbox Code Playgroud)

现在,您可以像这样运行您的剧本:

$ ansible-playbook -i /tmp/hosts pb.yml -e@<(asp)
Run Code Online (Sandbox Code Playgroud)

参考文献


sid*_*cat 5

如果您习惯于将密码保存在纯文本文件中,则另一种选择是使用带有--extra-vars参数的JSON文件(确保从源代码管理中排除该文件):

ansible-playbook --extra-vars "@private_vars.json" playbook.yml 
Run Code Online (Sandbox Code Playgroud)

从1.3开始,Ansible支持此选项


小智 5

这里曾多次建议使用Ansible Vault,但我更喜欢git-crypt来加密我的剧本中的敏感文件。如果您使用git来保存您的ansible剧本,那很容易。我在ansible Vault中发现的问题是,我不可避免地最终遇到了要使用的文件的加密副本,并且必须先解密该文件才能使用。 git-crypt提供了更好的IMO工作流程。

使用此方法,您可以将密码放在剧本中的var中,并将剧本标记为加密文件,.gitattributes如下所示:

 my_playbook.yml filter=git-crypt diff=git-crypt
Run Code Online (Sandbox Code Playgroud)

您的剧本将在Github上进行透明加密。然后,您只需要在用于运行ansible的主机上安装加密密钥,或按照文档中的说明进行设置即可gpg

关于转发gpg密钥(例如您的ssh-agent转发SSH密钥),这里有很好的问答:https : //superuser.com/questions/161973/how-can-i-forward-a-gpg-key-via-ssh-agent


小智 5

您可以像这样在主机文件中为您的剧本写sudo密码:

[host-group-name]
host-name:port ansible_sudo_pass='*your-sudo-password*'
Run Code Online (Sandbox Code Playgroud)


JPv*_*iel 5

我实现自动化的技巧是使用环境变量并通过--extra-vars="ansible_become_pass='{{ lookup('env', 'ANSIBLE_BECOME_PASS') }}'".

导出 env var,但避免使用 bash/shell 历史记录(以空格或其他方法开头)。例如:

     export ANSIBLE_BECOME_PASS='<your password>'
Run Code Online (Sandbox Code Playgroud)

在将额外ansible_become_pass变量传递到 中时查找 env var ansible-playbook,例如:

ansible-playbook playbook.yml -i inventories/dev/hosts.yml -u user --extra-vars="ansible_become_pass='{{ lookup('env', 'ANSIBLE_BECOME_PASS') }}'"
Run Code Online (Sandbox Code Playgroud)

好的替代答案: