在充满敌意的环境中部署安全服务器

作者:Kyle Rankin

如果您知道有人在恶意监听,您会在电话里改变您说的话吗?无论您是否将 NSA 视为恶意的,我想在阅读了 Linux Journal 上关于 NSA 的报道后,你们中的一些人会发现自己正在改变自己的行为。当我开始将服务器部署到公共云(在我的例子中是 EC2)时,我也发生了同样的事情。

虽然我一直努力构建安全的环境,但 EC2 对您的容错系统和整体安全性都提出了许多额外的挑战。在 EC2 上部署服务器就像把它从直升机上扔到敌后,甚至连 IP 地址都没有。

在本文中,我将讨论一些我在充满敌意的环境中保护服务器安全的技术。虽然其中一些技术是 EC2 特有的,但大多数技术都适用于几乎任何环境。

敌后

那么,到底是什么让 EC2 如此充满敌意呢?当您在传统环境中保护服务器安全时,您可能会在一些假设下操作。首先,您可能认为外部网络是主要威胁,而您的内部网络非常安全。您通常还假设您控制服务器和网络硬件,如果您使用虚拟化,也控制虚拟机监控程序。如果您使用虚拟化,您可能还会假设其他公司没有共享您的硬件,而且您可能永远不会想到恶意用户可能与您共享您的虚拟化平台。

在 EC2 中,所有这些假设都是错误的。内部和外部网络都应被视为潜在的敌意环境。服务器和网络硬件都在别人的控制之下。其他人也控制着管理所有虚拟机的虚拟机监控程序,而且您的虚拟机肯定与其他公司共享硬件。最后,虽然这可能不是每天都会发生的事情,但您的虚拟化邻居很可能是恶意的。

EC2 特有实践

虽然我在这里描述的许多实践可以在几乎任何环境中使用,但其中一些是 EC2 特有的,但即便如此,您也可能会找到将这些概念映射到其他云环境的方法。这些实践大多围绕安全组展开。在某些方面,EC2 安全组可以被认为是传统网络中的 VLAN。借助安全组,您可以创建防火墙设置,阻止所有属于特定组的服务器的特定端口的入站流量。与传统的 VLAN 不同,您可以在安全组内创建防火墙规则,阻止该组的成员之间的流量。服务器可以是多个安全组的成员,但重要的是要知道安全组仅在创建实例时分配 - 创建实例后,您无法从实例中添加或删除安全组。

我通常像大多数人使用 VLAN 一样使用安全组,只是做了一些更改。每个具有共同用途的服务器组都有自己的安全组。默认情况下,所有组都阻止所有外部流量,并且我仅在需要时才打开端口。在大多数情况下,安全组不允许外部访问。我还保留了 EC2 默认设置的“default”安全组,并将每台服务器都作为该组的成员;但是,我锁定了该组,并且仅在我想授予从不同安全组访问我的所有服务器的权限时才使用它。例如,我可能会使用对默认安全组的更改来允许所有服务器在其自定义端口上与我的 Puppetmaster 服务器通信。再举一个例子,我使用 VPN 访问我的云网络,并且该 VPN 被授予 SSH 访问我环境中所有服务器的权限。

最后,我从不在我的 userdata 文件中存储任何秘密信息。通常,当您在 EC2 中生成服务器时,您会为服务器提供 userdata 文件。许多 AMI(Amazon Machine Images - 您选择的操作系统安装映像)都配置为执行 userdata 脚本。虽然在某些情况下,此文件用于将特定的配置值传递给服务器,但许多人(包括我自己)将该文件用作安装后脚本。在我的情况下,我使用它来配置我的配置管理系统 (Puppet),并从那时起让它接管系统的配置。您可能不知道的是,userdata 脚本的内容可以通过 API 调用提供给实例生命周期内系统上的任何用户。如果您使用 userdata 文件注入任何类型的秘密信息(证书或 SSH 私钥、密码或系统在其配置中使用的共享秘密,或您不希望普通用户看到的任何内容),这些秘密信息将对系统上的任何用户可见。事实上,如果您碰巧自己使用 Puppet(或者在系统上安装了 facter),facter 本身将为您返回该 userdata 脚本的内容。

处理秘密信息

在云环境中,除了 userdata 脚本之外,思考如何管理秘密信息非常重要。事实是,尽管您尽了最大努力,您仍然经常需要在系统上的某个地方以纯文本形式存储私钥或密码。正如我所提到的,我使用 Puppet 来管理我的系统的配置。我将所有 Puppet 配置存储在 Git 中,以跟踪更改并在我需要时提供审计跟踪。将所有配置都放在 Git 中是一个很好的实践,但我建议的第一个与秘密信息相关的安全实践是避免在您的配置管理系统中存储任何纯文本秘密信息。在可能的情况下,我尝试在需要它们的主机上生成秘密信息,这意味着我不是将 GPG 或 SSH 密钥对推送到服务器,而是使用我的配置管理系统在主机本身上生成一个。

我采取的另一个实践是在可能的情况下将秘密信息存储在 ramdisk 中。这避免了在可能随时消失的硬盘驱动器上安全删除文件的问题。我们刚刚在我们的配置管理系统中编写了一个基本模块,该模块自动化了将敏感文件移动到 /dev/shm 的过程,以其校验和命名,并在原始位置创建符号链接。当然,如果您走这条路,您需要意识到存储在 ramdisk 中的任何文件在重启后都会消失(这就是全部想法),所以不要在那里存储任何您在重启后无法重新生成的东西,尽管我通常只是重新生成实例而不是在云中重启它们。

在许多情况下,我在主机上生成的秘密信息永远不需要离开系统。在其他情况下,我可能需要与其他服务器共享密钥对的公共组件。在这种情况下,Puppet 会导入生成的公钥并将其存储在其数据库中,然后可以将其导出到任何需要它的其他主机上。在某些情况下,我不得不编写一些自定义 Puppet facts 以帮助导出这些数据。

即使采取了所有这些实践,有时在您的配置管理系统中存储数据库密码仍然要简单得多。在这些情况下,我使用 Puppet 的一个附加模块 hiera-gpg,它允许您存储 GPG 加密的 YAML 文件,其中包含敏感的配置设置。每个独立的环境(例如开发和生产)都有自己的 Puppetmaster 和自己的 GPG 密钥。每个系统管理员将这些密钥中的每一个添加到他或她自己的 GPG 密钥链中,我们使用一个包装脚本来帮助编辑这些 hiera-gpg 文件。包装脚本被告知要编辑哪个文件以及它用于哪个环境,并且它确保文件被加密,以便任何系统管理员和该特定环境中的 Puppetmaster 都可以打开它。

这些技术仅仅触及了您在云中托管敏感服务器时应采取的措施的表面,这绝不是我已到位的系统的完整列表。在以后的文章中,我将继续介绍我用来在充满敌意的环境中保护服务器安全的其他技术。

Kyle Rankin 是 Linux Journal 的技术编辑和专栏作家,也是 Purism 的首席安全官。他是 Linux Hardening in Hostile NetworksDevOps TroubleshootingThe Official Ubuntu Server BookKnoppix HacksKnoppix Pocket ReferenceLinux Multimedia HacksUbuntu Hacks 的作者,也是许多其他 O'Reilly 书籍的贡献者。Rankin 经常在安全和开源软件方面发表演讲,包括 BsidesLV、O'Reilly Security Conference、OSCON、SCALE、CactusCon、Linux World Expo 和 Penguicon。您可以在 @kylerankin 上关注他。

加载 Disqus 评论