我想用pipe理一组现有的服务器。 我创build了一个ansible_hosts
文件,并使用仅针对单个主机的命令成功(使用-K
选项)进行了testing
ansible -i ansible_hosts host1 --sudo -K # + commands ...
我现在的问题是,每个主机上的用户密码是不同的,但我找不到在Ansible中处理这个问题的方法。
使用-K
,我只提示一个单一的sudo密码,然后似乎在没有提示的情况下尝试所有后续的主机:
host1 | ... host2 | FAILED => Incorrect sudo password host3 | FAILED => Incorrect sudo password host4 | FAILED => Incorrect sudo password host5 | FAILED => Incorrect sudo password
迄今为止的研究:
一个StackOverflow问题与一个不正确的答案(“使用-K
”)和作者说“发现我需要无密码的sudo”
Ansible文档中提到 “使用无密码sudo使事情更容易自动化,但不是必需的” 。 (重点是我的)
这个安全的StackExchange问题 ,它把它看作NOPASSWD
是必需的
文章“可扩展和可理解的configuration…”说:
“运行sudo可能需要input密码,这是永远阻止Ansible的一个确定的方法,一个简单的解决方法是在目标主机上运行visudo,并确保用户Ansible将用于login不必键入密码”
文章“基本Ansible手册” ,其中说
“Ansible可以以root身份login到目标服务器,避免sudo的需要,或者让没有密码的sudo用户拥有sudo,但是这样做的想法使得我的脾气会威胁到我的食道,阻塞我的气pipe,所以我别”
我的想法确切,但如何超越一台服务器?
可能的问题#1227 ,“Ansible应该为剧本中的所有用户索要sudo密码”,这是一年前由mpdehaanclosures的,评论“没有看到太多的需求,我想大多数人都只是从一个用户帐户或大部分时间使用密钥。“
那么……在这样的情况下,人们如何使用Ansible呢? 在/etc/sudoers
设置NOPASSWD
,在主机之间重复使用密码,或者启用root SSHlogin,都会显着降低安全性。
你当然完成了你的研究
从我所有的经验来看,你所要完成的任务是不被支持的。 正如你所提到的,可行的说,它不需要无密码的sudo,而你是正确的,它不。 但是我还没有看到任何使用多个sudo密码的方法,当然不需要运行多个configuration。
所以,我不能提供你正在寻找的确切解决scheme,但你确实要求…
“那么……在这样的情况下,人们如何使用Ansible?在/ etc / sudoers中设置NOPASSWD,在主机之间重复使用密码或者启用root SSHlogin,都会显着降低安全性。
我可以给你一个看法。 我的用例是在支持全球SaaS公司的多个数据中心中有1k个节点,由于我们业务的性质,我必须devise/执行一些非常严格的安全控制。 安全始终是平衡的行为,更多的可用性更less的安全性,这个过程是没有什么不同,如果你运行10台服务器或1000或100,000。
你绝对正确的,不要通过密码或SSH密钥使用rootlogin。 事实上,如果服务器插入networking电缆,则应该禁用根login。
让我们谈谈密码重用,在一个大型企业中,让系统pipe理员在每个节点上拥有不同的密码是合理的吗? 对于一对夫妇节点来说,但是如果我们的pipe理员/工程师必须在1000个节点上拥有不同的密码,那么他们就会发生兵变。 实现这一点几乎是不可能的,每个用户都必须在某个地方存储自己的密码,希望是一个keypass,而不是一个电子表格。 而且每次你把密码放在可以用纯文本的地方拉出来的地方,你的安全性就大大降低了。 我宁愿让他们知道一两个真正强大的密码,而不必每次需要在机器上login或调用sudo时查阅keypass文件。
因此,即使在安全的环境下,密码重用和标准化也是完全可以接受和标准化的。 否则ldap,keystone和其他目录服务将不需要存在。
当我们移动到自动化用户时,ssh密钥很适合你,但是你仍然需要通过sudo。 您的select是自动化用户的标准化密码(在许多情况下可以接受),或者如您所指出的那样启用NOPASSWD。 大多数自动化用户只执行一些命令,所以启用NOPASSWD是非常有可能的,但是只能用于预先批准的命令。 我build议使用你的configurationpipe理(在这种情况下是可以的)来pipe理你的sudoers文件,这样你就可以轻松地更新无密码的命令列表。
现在,一旦开始进一步分离风险,您可以采取一些步骤。 虽然我们有1000个左右的节点,但并不是所有的都是“生产”服务器,有些是testing环境等等。并不是所有的pipe理员都可以访问生产服务器,尽pipe他们可以在别处使用相同的SSO用户/密钥。 但是自动化用户会更安全一些,例如非生产pipe理员可以访问的自动化工具具有无法在生产中使用的用户和凭据。 如果你想在所有的节点上启动ansible,你必须分两批进行,一次是非生产,一次是生产。
我们也使用puppet,因为它是一个强制执行的configurationpipe理工具,所以所有环境的大部分变化都会被推送出去。
显然,如果你引用的这个特性请求被重新打开/完成,那么你所要做的就完全被支持了。 即使如此,安全是一个风险评估和妥协的过程。 如果您只有几个节点,您可以记住密码,而不必使用便签纸,那么单独的密码就会稍微安全一些。 但对于我们大多数人来说,这不是一个可行的select。
从Ansible 1.5开始,可以为host_vars和其他variables使用encryption保pipe库 。 这至less可以使您安全地存储每个主机(或每个组)的ansible_sudo_pass
variables。 不幸的是,– --ask-vault-pass
只会提示每个合法的调用一个保险库密码,所以你仍然被限制为一起使用的所有主机的一个保险库密码。
尽pipe如此,对于某些用途来说,这可能是跨越多个主机拥有单个sudo密码的改进,因为攻击者无法访问您的encryptionhost_vars仍然需要为他或她所攻击的每台机器(或机器组)分别提供一个sudo密码。
使用Ansible 1.5,可以使用lookup('password', …)
设置ansible_sudo_passvariables:
ansible_sudo_pass: "{{ lookup('password', 'passwords/' + inventory_hostname) }}"
我发现这比在host_vars/
使用文件更方便,原因如下:
我实际上使用with_password: "passwords/{{ inventory_hostname}} encrypt=sha256_crypt"
设置部署远程用户的密码(这是sudo需要的),所以它们已经存在于文件中(虽然这些明文查找丢失当生成散列值时存储在文件中的盐值)。
这只会保留文件中的密码(没有ansible_sudo_pass:
已知明文),因为密码安全性会提高一些。 更重要的是,这意味着您不会encryption所有其他主机特定的variables,因此可以在不使用保险库密码的情况下读取它们。
把密码放在一个单独的目录下可以让文件远离源代码控制,或者使用像git-crypt这样的工具以encryption的forms存储它们(你可以使用早期的缺lessVaultfunction的Ansible)。 我使用git-crypt,因为我只能在encryption的文件系统上以解密的forms检出版本库,所以我不用打开文件库,因此不需要键入文件库密码。 (使用两者当然会更安全。)
您也可以使用ansible_ssh_pass 查找函数; 对于没有ansible_sudo_pass的早期版本的Ansible,这甚至是可能的。
使用pass是一种简单的方法来提供sudo密码。 通过每个文件存储一个密码,可以很容易地通过git或其他方法共享密码。 这也是安全的(使用GnuPG),如果您使用gpg-agent,它可以让您使用安全,而不必在每次使用时input密码。
要将存储为servers/foo
的密码提供给server,请在库存文件中使用它,如下所示:
[servers] foo ansible_sudo=True \ ansible_sudo_pass="{{ lookup('pipe', 'pass servers/foo') }}"
考虑到你早先解锁了gpg-agent的密钥,这将会运行,而不需要input任何密码。
这是一个相当古老的线索,但是:
vars_plugin
(一个相当完整的实现可以在https://gist.github.com/mfriedenhagen/e488235d732b7becda81find),它区分了几个authentication系统: 一个可能的方法是使用环境variables。
例如
pass1=foo pass2=bar ansible-playbook -i production servers.xml
然后在游戏中,您可以使用以下命令查找sudo密码:
lookup('env', 'pass1') lookup('env', 'pass2')