我想使用ansible来管理一组现有服务器。我创建了一个ansible_hosts文件,并使用仅针对单个主机的命令成功测试了(使用-K选项)

ansible -i ansible_hosts host1 --sudo -K # + commands ...


我现在的问题是用户密码在每个主机都是不同的,但是我在Ansible中找不到处理此问题的方法。后续所有未提示的主机:

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 docs,其中说:“使用无密码的sudo使事情更容易自动化,但这不是必需的。” (强调我的问题)
此安全性StackExchange问​​题被视为需要-K

文章“可伸缩且可理解的供应...”,其中说:

“运行sudo可能需要输入密码,这是永远阻止Ansible的肯定方法。一个简单的解决方法是在目标主机上运行visudo,并确保用户Ansible将用于登录而不必输入密码”


文章“ Basic Ansible Playbooks”,其中说

“ Ansible可以以root用户身份登录到目标服务器,而无需sudo或让ansible用户有没有密码的sudo,但是这样做的想法使我的脾脏有可能扬起我的食道并阻塞我的气管,所以我不会“

我的想法完全正确,但是如何扩展

ansible问题#1227,“ Ansible应该在剧本中要求所有用户使用sudo密码”,该问题在一年前被mpdehaan关闭,并带有注释“没有看到为此,我有很多需求,我认为大多数人大多数时候只使用一个用户帐户或使用密钥。”

那么...人们在这种情况下如何使用Ansible?在NOPASSWD中设置NOPASSWD,在主机之间重用密码或启用root SSH登录都似乎大大降低了安全性。

评论

您不使用SSH密钥是有原因的吗?

我已经在使用SSH密钥;它们不会影响sudo(仍然需要输入密码)。

这可能不完全是您要查找的内容,但是在Ubuntu盒子上,我仍然使用密钥,即将我的公共密钥放在/ root / authorized_keys中,以直接作为root用户进入。明显的缺点是允许通过ssh进行root登录...我也不允许通过ssh进行密码登录,并运行fail2ban以提高安全性。

@senorsmile感谢您的回复!您介意将其转为答案,以便我不赞成您阅读未回答的问题吗?

即ansible_ssh_password设置仅适用于SSH密码(提示位于名称中...)。 &我已经在使用基于密钥的SSH登录。

#1 楼

当然,您已经完成了研究...

根据我的所有经验,您将无法完成您要完成的工作。如您所述,ansible指出它不需要无密码的sudo,而您是正确的,它不需要。但是我还没有看到在ansible中使用多个sudo密码的任何方法,当然也没有运行多个配置。

因此,我无法提供您正在寻找的确切解决方案,但您确实提出了... ...在这样的情况下使用Ansible?在/ etc / sudoers中设置
NOPASSWD,在主机之间重用密码或启用
root SSH登录似乎都大大降低了安全性。“


我可以给你一个看法。我的用例是支持一个全球SaaS公司的多个数据中心中的1k个节点,由于我们的业务性质,我必须在其中设计/实施一些严格的安全控制措施。安全性始终是一种平衡行为,更多的可用性会降低安全性,如果您正在运行10台服务器或1,000或100,000,则此过程没有什么不同。

绝对正确,不要通过密码或ssh键使用root登录。实际上,如果服务器插入了网络电缆,则应该完全禁用root登录。

让我们谈谈密码重用,在大型企业中,要求sysadmins在每个节点上使用不同的密码是否合理?也许有几个节点,但是如果我的管理员/工程师必须在1000个节点上使用不同的密码,那么他们会发动叛变。要实现几乎也是不可能的,每个用户都必须将自己的密码存储在某个地方,希望是密码,而不是电子表格。而且,每次将密码放在可以以纯文本形式提取的位置时,都会大大降低安全性。我更希望他们从心底中知道一个或两个非常强大的密码,而不是每次他们需要登录或在计算机上调用sudo时都必须查阅密钥文件。

因此密码重用和标准化即使在安全的环境中也完全可以接受并且是标准的。否则,ldap,keystone和其他目录服务将不需要存在。

当我们转向自动化用户时,ssh密钥可以很好地吸引您,但是您仍然需要通读sudo。您的选择是自动用户的标准密码(在许多情况下是可以接受的),或者如您所指出的那样启用NOPASSWD。大多数自动化用户只执行几个命令,因此启用NOPASSWD是很有可能的,当然也很可取,但是仅适用于预先批准的命令。我建议使用您的配置管理(在这种情况下可用)来管理您的sudoers文件,以便您可以轻松地更新无密码命令列表。

现在,一旦开始扩展规模,您可以采取一些步骤来进一步隔离风险。尽管我们有1000个左右的节点,但并非所有节点都是“生产”服务器,有些不是测试环境,等等。并非所有管理员都可以访问生产服务器,尽管这些管理员可以使用与其他地方相同的SSO用户/密码。 。但是自动化用户会更安全一些,例如非生产管理员可以访问的自动化工具具有无法在生产中使用的用户和凭据。如果要在所有节点上启动ansible,则必须分两批进行一次,一次用于非生产,一次用于生产。

我们还使用puppet,因为它是强制执行的配置管理工具,所以对所有环境的大多数更改都可以通过它来完成。

很显然,如果您引用的功能请求被重新打开/完成,那么您想要做的事情将得到完全支持。即使如此,安全性也是风险评估和折衷的过程。如果只有几个节点可以记住密码而不需要使用便签纸,那么单独的密码会稍微安全些。但是对于我们大多数人来说,这不是一个可行的选择。

评论


@Zeb,谢谢,我曾想过,出于理智的原因,拥有成千上万台服务器的用户还是会使用NOPASSWD(可能受到更严格的防火墙规则等的支持),但是阅读您的用例和想法是很好的威胁模型。

–supervacuo
2013年12月31日12:39

但是,对于您关于限制使用“预先批准的” sudo命令的建议,有一条评论(当我发现几乎需要NOPASSWD时,我确实想到了)。不幸的是,这似乎也完全不受支持-Ansible不承诺致电例如chown或mkdir二进制文件,并且需要能够sudo / bin / sh才能使大多数模块正常工作。

–supervacuo
2013年12月31日13:00



我似乎回想起我的一位工程师曾经抱怨过这一点,这很烦人。

– Zeb
2014年1月1日的1:59

#2 楼

从Ansible 1.5开始,可以对host_vars和其他变量使用加密的保管库。这至少可以使您安全地存储每个主机(或每个组)的ansible_sudo_pass变量。不幸的是,--ask-vault-pass每次提示都只会提示您输入一个保管库密码,因此您仍然只能为将要一起使用的所有主机使用一个保管库密码。

尽管如此,对于某些用途,这可能是跨多个主机使用单个sudo密码的一种改进,因为无法访问加密的host_vars的攻击者仍然需要为每台机器(或机器)使用单独的sudo密码。组)他或她攻击。

评论


ansible_sudo_pass选项似乎也很新-似乎可以满足我的要求。同样,单个保险库密码也是我理想的选择。谢谢!

–supervacuo
2014年5月11日13:49

有没有一种避免使用此方法加密所有host_vars的方法? (Alex Dupuy指出的潜在限制)

–supervacuo
2015年9月24日,下午1:41

@supervacuo-为避免对所有主机变量进行加密,只需使用包含main.yml(未加密)和secret.yml(已加密)的主机var目录-请参阅本文档的最后一部分,其中讨论“ raleigh”组-相同的技术适用于主机变量和组变量。我经常使用它,唯一的变化是,如果某些剧本只需要一个秘密,则将其完全存储在不同的树中并通过包含主机名或var名的路径包含它会很有用。

– RichVel
16 Sep 14'6:01



如果我已经在Vault中加密了“ ansible_ssh_pass”值,那么我还需要复制“ ansible_sudo_pass”值吗?有没有办法让第二个sudo_pass值引用第一个“ ssh_pass”值?

–emeraldjava
18年8月30日在16:18

可以在以下位置找到关于保险库密码使用的良好介绍:stackoverflow.com/a/37300030/5025060

–CODE-REaD
19年4月3日在18:48

#3 楼

在Ansible 1.5中,可以使用lookup('password', …)设置ansible_sudo_pass变量:

ansible_sudo_pass: "{{ lookup('password', 'passwords/' + inventory_hostname) }}"


由于以下几个原因,我发现这比在host_vars/中使用文件更方便:

我实际上使用with_password: "passwords/{{ inventory_hostname}} encrypt=sha256_crypt"
为部署的远程用户提供密码(然后sudo需要密码),
所以它们已经存在于文件中了
(尽管进行这些纯文本查找会丢失散列值生成时存储在文件中的盐值
。)
这仅将文件中的密码(没有已知的纯文本)保留在密码上,以增加一些ε安全性。
更重要的是,这意味着您不对所有其他主机特定的变量进行加密,
因此可以在不使用库密码的情况下读取它们。
将密码放在单独的目录中可以更轻松地使文件脱离源代码管理,或者使用git-crypt之类的工具以加密形式存储它们(您可以在earli上使用它er缺少Vault功能的Ansible。)
我使用git-crypt,由于我只在加密文件系统上以解密形式签出存储库,因此我无需打扰Vault,因此无需键入a保险库密码。 (使用两者当然会更安全。)

还可以将查询功能与ansible_ssh_pass一起使用;对于没有ansible_sudo_pass的早期版本的Ansible,这甚至可能是可行的。

评论


我终于可以尝试一下了(谢谢!),但是看不到没有git-crypt会如何工作。据我所知。似乎Ansible尚不支持在加密的保管库上使用查找。密码模块文档说,加密存储还存在一些尚未公开的支持,但是我还没有找到详细信息。有什么线索吗?

–supervacuo
2015年9月14日在17:44



#4 楼

使用pass是为ansible提供sudo密码的简单方法。 pass为每个文件存储一个密码,这使得通过git或其他方法轻松共享密码成为可能。它也是安全的(使用GnuPG),如果您使用的是gpg-agent,它可以让您使用ansible,而无需每次使用时都输入密码。 ,请在如下清单文件中使用它: 。


更新:Ansible现在通过passwordstore插件内置了此功能。与上述代码等效:

[servers]
foo ansible_sudo=True \
    ansible_sudo_pass="{{ lookup('pipe', 'pass servers/foo') }}"


甚至可以创建一个尚不存在的密码,这非常有用。

#5 楼

尽管如此,这是一个非常古老的线程:


我们内部使用两个不同的身份验证系统,计算机的管理是通过团队中的本地工作站完成的。适用于Ansible的vars_plugin(可以在https://gist.github.com/mfriedenhagen/e488235d732b7becda81上找到比较完整的实现),它区分了几种身份验证系统:使用的登录名/ sudo用户是特定于组和管理员的。文档kwallet Gnome和_win_crypto也受支持)。
我在Mac OS X的钥匙串中设置了密码权限,以通知我以下事实:命令行程序安全性要求访问由使用的每个验证系统使用的密码
主机,所以我运行“ ansible -s all -m ping” nd出现两个提示(每个身份验证系统一个),在这里我按空格键,ansible会获取密码。

评论


看起来很整洁,谢谢您-我喜欢不必在两个地方存储密码的想法。目前,我一直在使用KeepassX(因为GNOME密钥环似乎不太便携),但是也许我可以使python-keepass正常工作?

–supervacuo
2015年4月2日,11:37

据我了解,python-keyring是对此的一种抽象,因此您的同事可能会使用其他操作系统。还是将keepassx数据库存储在USB记忆棒上,并且必须从具有不同操作系统的工作站进行管理?

– Mirko Friedenhagen
2015年4月3日12:29



理解我的意思是我已经必须使用KeepassX才能访问非GNOME系统上的密码,因此将它们存储在gnome-keyring中将意味着保留重复的记录。仍然比使用NOPASSWD更好,但是…

–supervacuo
15年4月7日在15:46

#6 楼

到这里迟到的人:c.f. https://stackoverflow.com/a/37002802

Per host, in your inventory hosts file (inventory/<inventoryname>/hosts)
[server]
10.0.0.0 ansible_sudo_pass=foobar

Per group, in your inventory groups file (inventory/<inventoryname>/groups)
[server:vars]
ansible_sudo_pass=foobar

Per group, in group vars (group_vars/<groupname>/ansible.yml) and encrypted (ansible-vault create group_vars/<groupname>/ansible.yml)
ansible_sudo_pass: "foobar"


#7 楼

一种可行的方法是使用环境变量。

例如

pass1=foo pass2=bar ansible-playbook -i production servers.xml


然后在剧本中,可以使用以下命令查找sudo密码:

lookup('env', 'pass1') 
lookup('env', 'pass2') 


#8 楼

这是完全可能的。您可以定义清单以将变量用于密码之类的事情:

库存:

如果您使用的是跳转服务器(如果需要),您的清单是:

[023_mqtt]
023-softbank-mqtt01 ansible_host=IP.IP.IP.IP ansible_ssh_private_key_file=/path/to/my_key ansible_ssh_user=my_user ansible_become=yes ansible_become_method=sudo ansible_become_pass='{{ my_user_pass }}'


最后,您定义一个保管库来存储密码。最好在库存文件所在的文件夹中创建该文件:

ansible_ssh_common_args: '-o ProxyCommand="ssh -i /path/to/your/jump_key -W %h:%p -q you_jump_user@IP.IP.IP.IP"'


添加密码:

ansible-vault create passwds.yaml
[enter a vault pass]


要运行此文件,请将保管箱作为额外变量传递:而且效果很好。有关全文,请查看我的git:

https://github.com/flow0787/ansible/blob/master/README.md