我准备将 Ansible 引入我的数据中心,并且正在寻找一些关于控制机器的位置以及如何管理 SSH 密钥的安全最佳实践。
问题一:控制机
我们当然需要一台控制机器。控制机器上保存了公共 SSH 密钥。如果攻击者可以访问控制机器,那么就有可能访问整个数据中心(或 Ansible 管理的服务器)。那么,在数据中心有一台专用的控制机器还是一台远程控制机器(比如我的笔记本电脑远程连接到数据中心)更好?
如果最佳做法是使用我的笔记本电脑(当然,它可能会被盗,但我可以将我的公钥安全地保存在云端或便携式加密设备上),如果我需要使用 Ansible 的一些 Web 界面,比如 Ansible Tower、Semaphore、Rundeck 或 Foreman,而这些界面需要安装在数据中心的集中式机器上,该怎么办?如何确保其安全并避免其成为“单点攻击”?
问题 2:SSH 密钥
假设我需要使用 Ansible 执行一些需要 root 执行的任务(例如安装软件包或类似操作)。我认为最佳做法不是在受控服务器上使用 root 用户,而是为 Ansible 添加具有 sudo 权限的普通用户。但是,如果 Ansible 需要执行几乎所有任务,则它需要通过 sudo 访问每个命令。那么,最佳选择是什么:
- 让 Ansible 使用 root 用户(其公钥保存在
~/.ssh/authorized_keys
- 创建专用于 Ansible 且具有 sudo 访问权限的非特权用户
- 让 Ansible 用户通过 sudo 运行每个命令并指定密码(该密码是唯一的,需要每个使用 Ansible 控制该服务器的系统管理员都知道)
- 让 Ansible 用户通过 sudo 运行每个命令而无需指定任何密码
- 还有其他提示吗?
答案1
堡垒主机(ansible 控制中心)属于单独的子网。它不应该从外部直接访问,它不应该直接访问从托管服务器!
您的笔记本电脑是最不安全的设备。一封愚蠢的邮件、一个愚蠢的闪存漏洞、一个愚蠢的访客 Wifi 都会让您的笔记本电脑被攻破。
对于服务器,根本不允许通过 ssh 进行 root 访问。许多审计对此嗤之以鼻。
对于 ansible,让每个管理员在每个目标服务器上使用自己的个人帐户,并让他们使用密码执行 sudo。这样两个人之间就不会共享密码。您可以检查每个服务器上的每个人做了什么。个人帐户是否允许使用密码登录、仅使用 ssh 密钥还是同时要求两者,都取决于您。
澄清ansible 不需要使用单个目标登录名. 每个管理员可以且应该拥有个人目标登录名。
附注:如果帐户有密码,请尽量不要创建名为某个单词(如“ansible”或“admin”或“cluster”或“management”或“operator”)的帐户。具有密码的帐户的唯一好名称是人名,如“jkowalski”。只有人类才能对通过帐户执行的操作负责,并对不正确地保护其密码负责,“ansible”不能。
答案2
>问题1:控制机
在 Userify(全面披露:我们实际上提供管理 ssh 密钥的软件),我们一直在处理这个问题,因为我们还运行着最大的 SSH 密钥仓库。我们通常建议本地安装而不是使用云,因为这样您可以增强控制,减少接触面,并且可以真正将其锁定在已知的受信任网络上。
要记住的重要一点是,在这样一个正确构建的系统中,确实不应该有任何重大机密可以被泄露攻击者。如果有人驾驶叉车闯入您的数据中心并带走您的服务器,他们不会得到太多信息,除了一些经过大量哈希处理的密码、可能还有一些经过大量加密的文件以及一些没有相应私钥的公钥。换句话说,他们得不到太多信息。
正如你所指出的,这里真正的威胁载体是如果攻击者控制了该机器会发生什么并使用它来部署自己的用户帐户和(公共)密钥。这对几乎每个云平台(例如:Linode)来说都是一种风险。您应该最关注的是防止访问控制平面,这意味着最小化攻击面(仅暴露几个端口,并尽可能锁定这些端口),最好使用针对特权升级和各种攻击(SQL 注入、XSS、CSRF 等)进行强化的软件。启用对控制平面的 2FA/MFA 访问,并专注于尽可能锁定该控制平面。
那么,在数据中心有一台专用的控制机器还是一台远程控制机器(比如我的笔记本电脑远程连接到数据中心)更好?
它是绝对更好在安全的数据中心拥有一台专用的控制机器,因为您可以隔离它并将其锁定,以防止/尽量减少盗窃或未经授权的访问的风险。
如果最佳做法是使用我的笔记本电脑(当然,它可能会被盗,但我可以将我的公钥安全地保存在云端或离线的便携式加密设备上),如果我需要使用一些网络界面怎么办使用 Ansible,例如 Ansible Tower、Semaphore、Rundeck 或 Foreman,哪些需要安装在数据中心的集中式机器上?
你不需要运行任何网页界面或辅助控制平面来管理您的密钥(甚至 Userify),直到您变得足够大,由于用户数量增加和服务器之间授权级别不同而开始遇到管理问题,或者需要为可能不了解或无法访问 Ansible 来更新密钥的用户提供额外的指导。 Userify 最初只不过是一堆 shell 脚本(今天它们可能是 Ansible!),这完全没有问题,直到您开始需要额外的管理控制和方便人们管理/轮换自己的密钥的简便方法。 (当然,如果您到了那一步,请查看 Userify!)
如何确保其安全并避免其成为“单一攻击点”?
当然,要查看网络上的所有资源,以便锁定东西,但最重要的是从安全的基础开始:
1. 从一开始就考虑安全性来设计解决方案。选择传统上问题较少的技术(即数据库或语言),然后以安全为首要考虑进行编码。清理所有传入数据,即使是来自受信任用户的数据。偏执是一种美德。
2. 最终,一切都会被打破。当这种情况发生时,尽量减少损害:正如您已经指出的那样,尽量减少对秘密材料的处理。
3.保持简单。不要使用最新的奇特技术,除非您确定它可以显著且可证明地提高您的安全性。例如,我们选择 X25519/NaCl (libsodium) 而不是 AES 作为我们的加密层(我们对所有内容进行加密,无论是静止的还是动态的),因为它最初是由我们信任的人(DJB 等人)设计和编写的,并经过 Schneier 和 Google 安全团队等世界知名研究人员的审查。如果是较新的东西,请使用趋向于简单的东西,因为简单性使得隐藏深层漏洞变得更加困难。
4.符合安全标准。即使您不属于 PCI 或 HIPAA 安全规则等安全制度,也请通读这些标准并找出如何满足这些标准或至少非常强大的补偿控制。这将有助于确保您真正满足“最佳实践”。
5. 引入外部/独立渗透测试并运行漏洞赏金计划确保您持续遵循这些最佳实践。一切看起来都很棒,直到您让一些聪明且积极性很高的人来敲打它……一旦完成,您将对自己的解决方案充满信心。
问题 2:SSH 密钥 最好的选择是什么:让 Ansible 使用 root 用户(其公钥保存在
~/.ssh/authorized_keys
/ 中)让 Ansible 用户通过 sudo 运行每个命令并指定密码(该密码是唯一的,需要每个使用 Ansible 来控制该服务器的系统管理员都知道)
尽量避免在服务器上使用密码,即使是 sudo。这涉及到秘密,最终会破坏您的安全(您实际上不能很容易地在机器之间更改 sudo 密码,您必须将其存储在某个地方,密码意味着您实际上无法进行服务器到服务器的自动化,这正是它的全部意义所在。此外,如果您将 SSH 保留为默认设置,这些密码可能会被暴力破解,这使得密钥变得毫无意义。此外,请避免将 root 用户用于任何目的,尤其是远程登录。
创建一个专门用于 Ansible 的非特权用户,并赋予其 sudo 访问权限 / 让 Ansible 用户通过 sudo 运行所有命令,而无需指定任何密码
确实如此。您可以使用 sudo 角色将非特权用户审核回 ansible。理想情况下,创建一个专用于服务器到服务器/ansible 通信的标准用户,并使用 sudo 访问权限(无需密码)。
... 注意,如果您使用 Userify,我建议您这样做:为 ansible 创建一个 Userify 用户(如果您有多台 ansible 控制机器,您也可以按项目或服务器组进行划分),在控制服务器上生成 SSH 密钥,并在其 Userify 配置文件页面中提供其公钥。 (此文本框本质上变成/home/ansible/.ssh/authorized_keys
)。 您应该将 ansible 系统帐户与其他服务器到服务器系统帐户(例如远程备份帐户、秘密管理等)分开。 然后邀请您的人员,他们也可以创建和管理自己的密钥,并且一切都保持分开。 但是,就像锁定 Ansible 控制服务器一样,尝试以相同的方式锁定您的 Userify 服务器(或您部署的任何解决方案)。
还有其他提示吗?
我认为你肯定在以正确的方式处理这个问题,并提出了正确的问题。如果你想讨论这类事情,请给我发电子邮件(userify 上的第一个点姓氏),无论你最终追求什么方向,我都很乐意与你聊天。祝你好运!
答案3
答案1:控制机
两者皆有,您可以使用笔记本电脑通过堡垒主机连接到服务器。例如:
Host private1
IdentityFile ~/.ssh/rsa_private_key
ProxyCommand ssh user@bastion -W %h:%p
Host bastion
IdentityFile ~/.ssh/bastion_rsa_key
您拥有堡垒服务器的密钥,以及其背后主机的单独密钥。(我个人会使用 gpg-agent/ssh-agent)
答案 2:身份验证
我不确定“ansible”特定的最佳实践与任何其他 ssh 连接最佳实践有何不同但不,您想以自己的身份运行 ansible,而不是服务帐户或 root 帐户。
以下身份验证的组合:
- 每个用户的 ssh 密钥(集中存储)
- 凯尔伯罗斯验证
- 多因素身份验证(尤比克、Duo、GoogleAuth 等)
- Fail2ban/帐户锁定
- 集中记录和警报
- 集中认证(FreeIPA、LDAP、IdM、MS AD)
- 使用内部 CA 签署 ssh 密钥
其他想法:
- 始终将秘密/私人信息存储在 ansible-vault 中。
- Ansible 不需要 SUDO/Root 来运行,除非您正在执行的操作需要 sudo/root。
- Ansible 可以通过多种方式提升权限
最后,您没有提到任何有关 Windows 的内容。所以我只能假设您没有使用这个。但是在这种情况下,我会使用委托选项让您的笔记本电脑使用堡垒主机 (delegate_to: bastion.hostname.fqdn
) 和带有 kerberos 票证的 kerberos/winrm https。
如果你错过了,计算的最佳实践,永远不要以 root 身份执行任何操作,始终使用命名帐户
答案4
“最终,一切都会被打破”:
嗯,这不完全正确。我的牙医卖给我一个使用寿命为 100 年的植入物。它肯定会坏掉,但在我死后很久,所以…… ;)
这里的关键是实现具有寿命目标的安全性,如果它在此时间之前发生损坏,请做好准备,并在达到预计寿命时进行更换。