使用BeyondCorp限制访问您在AWS上的内部网站

2020-10-27 06:25:44

内部网站。每家公司都有它们,而且它们通常包含您公司的一些最重要的数据。因此,您应该保护它们以保护数据。

这并不是一个新想法,因为公司几十年来一直在创建VPN(虚拟专用网络)来限制对其内部网络的访问。但在2009年极光行动(Operation Aurora)黑客未遂事件发生后,谷歌对这种方法变得谨慎起来,于是他们决定转向零信任安全模式,在这种模式下,每个请求都会被视为来自可能受到攻击的网络。

这催生了BeyondCorp,这是一种在不使用VPN的情况下保护所有应用程序的理论模型。

这一想法得到了安全研究人员的广泛赞誉,尽管在最受欢迎的云平台上开始使用它的实用指南仍然有限。尽管谷歌在2014年发布了解释这一想法的白皮书,但这仍是事实。

我们明白,碧昂斯公司很复杂。它要求您查看流经系统的每个请求,并基于多个数据源验证其合法性:请求来自何处、由谁发送、该源的安全状态如何等等。这是一个很难回答的问题!

但我们也相信,开始使用BeyondCorp比许多人想象的要容易得多,安全方面的回报可以立即到来。

本文旨在为在AWS托管的内部网站上使用BeyondCorp安全性提供实用实施指南。

在Transcend,我们使用BeyondCorp安全来确保我们的IP和用户数据的安全。

碧昂斯公司(BeyondCorp)充斥着热词。这是零信任。这是无边界的。这是上下文感知的,确实有很多很酷的短语。但它在现实生活中看起来是什么样子呢?那么,让我们看看当我转到Transcend的内部codelabs站点时会发生什么,我们已经在那里使用我们公司的GSuite凭据设置了BeyondCorp身份验证:

当我试图加载该站点时,它要求我使用我的GSuite凭据登录。请注意,这包括硬件MFA令牌要求,该要求可在整个GSuite组织(以及许多其他身份提供商)中轻松实施。一旦我获得站点访问权限,我将在一小时内不需要登录任何内部系统。

要想亲眼看看,请访问codelab.dev.trancsend.com。虽然DNS是公开的,但只有我们的内部员工可以访问我们的内部教程,除非您有@transcend.io电子邮件地址,否则不允许您进入。

VPN创建了“蛋壳”安全,所有保护都在外围进行。一旦获得系统访问权限,该网络内的所有数据都可以访问。随着远程工作、手机和其他移动设备的兴起,您的受信任设备的“安全”网络也在不断扩大。

相反,BeyondCorp鼓励在应用程序的所有部分对所有设备进行一致的身份验证。任何设备试图访问codelab.dev.trancsend.com都无关紧要,即使是我们CEO的笔记本电脑在查看网站内容之前也需要安全地进行身份验证。

VPN是额外的攻击载体。当五角星或黑客试图攻击您的网络时,一种非常常见的方法是在他们能找到的任何面向公众的服务器中搜索漏洞。VPN接入点等系统通常是主要目标。这里有一个故事,一名漏洞赏金猎人使用这种方法攻击Facebook。当他访问他们的一台内部服务器时,他注意到另一名五角大楼的剩余文件,这名五角大楼利用同样的漏洞窃取了少量内部凭证。

与VPN服务器上的CVE相关的利用漏洞(常见漏洞和暴露)太常见了,例如900多台企业VPN服务器的密码被转储,或者常用的VPN实施允许直接访问I/O设备。或者,洛克希德·马丁公司(Lockheed Martin)(尽管做出了坚实的努力将MFA纳入他们的VPN)仍然受到一个组织的攻击,该组织发现了用于在他们的硬件MFA令牌上生成令牌的随机种子。

如果您将公司的WiFi网络用作受信任的网络,则该网络也可能成为攻击媒介。2016年,WPA2中的KRACK漏洞使得攻击者能够找到流经路由器的所有网络流量的加密密钥。

这些黑客攻击不是理论上的。他们都是有针对性的,协调得很好。当你的公司成功时,会有人想要你的数据。

相比之下,BeyondCorp没有VPN。BeyondCorp没有提供访问内部隐藏站点的面向公众的服务,而是拥有面向公众的服务,向内部隐藏的身份验证服务器请求身份验证信息。由于此身份验证服务器未公开,因此更难受到攻击。

虽然您的内部服务#9001可能具有防火墙规则,规定只有服务器#4001可以在端口443上与其通信,但是服务#9001如何知道#4001上的请求不是由通过VPN安全的对手发送的?

在爱德华·斯诺登2013年转储给“华盛顿邮报”的文件中,我们看到了上图。在这份报告中,美国国家安全局(用笑脸)显示,谷歌云中的流量没有对请求进行加密,因为他们认为网络边界是安全的。

在这种情况下,国安局甚至不需要破门而入。他们的强大计划直接连接到连接谷歌(和雅虎)数据中心的网络基础设施,从光缆中抽走了如此多的数据,以至于美国国家安全局的PINWALE数据库不堪重负。

这次攻击非常简单,令人痛苦。在当今云计算的世界里,重要的是要记住,物理上保护您的网络的VPN存在于某个地方,而您的网络流量流经的电缆也存在于物理上的某个地方。攻击者很聪明,会利用他们可以支配的所有载体。

相反,BeyondCorp会对所有请求进行身份验证,即使是您的私有网络中的请求也是如此。像AWS App Mesh这样的服务将很快要求对所有内部请求使用代理授权。这一要求,以及在服务网络上随时随地使用TLS变得更加容易,使得为您的网络流量实施加密和安全变得容易得多。

AWS有一些服务可以使BeyondCorp的实施变得相当容易管理。如果您感到紧张,并且认为将应用程序代码添加到公司的每个前端和后端听起来像是一件很大的工作,请不要害怕-Amazon Cognito就在这里!

Amazon Cognito是用于身份验证管理的托管服务。它与许多身份提供商(如Google、Facebook和Apple)连接,同时还通过SAML和OpenID Connect支持通用提供商。

如果您不熟悉这些身份验证协议,只需知道这意味着在前面的Codelabs演示中,您可以将GSuite登录更改为通过Okta、Amazon帐户、您公司的自定义身份验证等登录。

Cognito非常适合引入BeyondCorp,因为它位于基础设施级别,并且可以很容易地添加到单独的服务中。这使得逐步添加BeyondCorp变得很容易,也意味着您不需要更改任何应用程序代码。如果您有用各种语言和框架编写的多语言应用程序,那么您就幸运了:Cognito对所有这些应用程序都以相同的方式工作。

此过程的第一步是创建一组可以访问您的资源的人员。使用Cognito,应该可以访问不同资源集的每个不同的人员组都可以组成一个用户池。

下一步是创建用户池应用客户端,该客户端控制用户如何向用户池进行身份验证的设置:

在本例中,我们没有启用身份提供商(IdP),因此只接受用户名和密码身份验证。如果您想启用像GSuite这样的IDP,可以很容易地添加额外的Cognito身份提供程序。

要完成设置,让我们创建一个域。此用于身份验证的托管UI需要存在于Web上的某个URL处,亚马逊允许您轻松指定登录页面所在的位置(在Amazoncogito.com域下或在您自己的自定义域下)。在本例中,让我们在https://codelab-beyondcorp-alb.auth.us-east-1.amazoncognito.com/:为我们的登录站点创建一个子域。

现在我们有了Cognito用户组,我们可以将其连接到后端应用程序。对于大多数后端路由来说,已经具有某种身份验证是相对常见的,因此您只需要将Cognito添加到那些没有身份验证的路由中即可。

AWS应用程序负载均衡器提供了这种细粒度的控制。在本节中,我们将构建一个完整的应用程序,其中包含公共路由和私有路由(需要通过上一节中的Cognito用户池登录),所有这些都在大约100行Terraform中!首先,让我们创建一个虚拟私有云(VPC)来放置负载均衡器。在大多数应用程序中,您还必须为EC2、ECS服务、Auto Scaling组、数据库等添加专用子网。

现在,让我们通过Amazon Certificate Manager(ACM)添加SSL证书的资源。此SSL证书将用于我们的前端和后端:

为了保护我们的应用程序的安全,我们只想在端口443(HTTPS)上与我们的ALB对话,因此我们可以通过安全组来明确这一点:

现在到了有趣的部分-让我们创建一个应用程序!AWS提供了多种创建后端应用程序的方法:ECS、EKS、EC2、Lambda函数等。但所有这些都有一个共同点:它们都是应用程序负载平衡器(ALB)的目标选项。通过在ALB层添加身份验证,我们可以轻松地向所有这些后端服务添加登录步骤。

为了保持通用性,我将展示一个给出固定响应的ALB,但是无论在您的情况下ALB后面是什么,逻辑都应该以相同的方式工作:

9#将ALB放在上面创建的私有网络中,只开放443端口。

55#在此代码实验室中,为了使示例简单,我们没有向此目标组注册任何内容。

请注意,我们的应用程序将有两个路径:/public和/private。当请求/public时,会立即返回文本“this is a public response”。当请求/PRIVATE时,有两个操作:对我们的用户池进行身份验证,然后是固定响应(只有在身份验证步骤成功时才会返回)。

在本练习中,我还添加了指向此演示中的ALB的DNS记录,以便您可以验证行为:

在terraform Apply创建我们的基础设施之后,我们可以尝试访问公共url和私有url。

我们创建一个用户名为“testuser”、密码为“test123!”的用户。在我们的Cognito用户池中,这可以在控制台中完成,如下所示:

如果我们去私人网址呢?它会让我们先登录,然后才能看到内容:

有时,您可能希望将Cognito身份验证添加到您的前端。例如,您的开发站点和临时站点可能会给出可能影响您的开发数据库的路线。或者,您可能希望限制站点的访问,因为它只为端到端测试而创建,并且您不希望外部人员干扰数据库状态。在像我们的codelabs网站这样的情况下,我们只是不认为我们的面向内部的codelab会对其他任何人感兴趣或有用(或者仍在起草它们以供外部发布)。

在这些情况下,将类似的登录功能添加到您的前端是一个好主意,就像我们刚刚走过的后端一样。虽然您完全可以让您的网站成为ALB的目标,并使用与后端部分相同的Cognito步骤,但这也有一些缺点。通过将站点的所有流量限制为来自负载均衡器,您将失去全球分布式CDN的许多好处,而且还需要为长寿命的ALB服务器支付相当高的费用。

相反,我们可以利用亚马逊的无服务器技术Lambda@Edge。有关如何在AWS中使用CloudFront和S3制作简单前端的介绍,请查看我们的博客文章。要更深入地了解如何设置和使用lambda@Edge函数,请查看我们的后续帖子。

主要的想法是,我们将有一个Lambda函数,它可以在请求我们的前端时随时运行。如果用户已经登录,此函数将提供对前端的访问权限;如果用户尚未登录或其会话已过期,该函数将重定向他们登录到Cognito身份验证页面。

既然我们已经对什么是CloudFront和Lambda@Edge有了共同的理解,让我们使用Terraform创建一个CloudFront分发,其原点为S3,并受Lambda@Edge函数的保护。让我们用短短45行来完成它吧!

该函数的确切内容与ALBS中的内置功能高度相似,因为如果授权成功,它只会显示前端内容。要了解此模块如何工作,或查看lambda函数的源代码,请查看我们的公共报告。此lambda函数最酷的部分之一是,您可以在多个CloudFront发行版上重复使用它,只要其他前端应该允许相同的Cognito用户池进行身份验证即可。既然Lambda@Edge函数已经准备好,让我们创建一个CloudFront发行版,其中包含S3源和我们在后端部分创建的SSL证书:

就这样!如果您使用Terraform进行申请,您将拥有一个受Cognito身份验证保护的网站。您可以将网站内容发布到普通CI/CD管道中的原始S3存储桶,也可以以您喜欢的任何其他方式发布。作为一个快速示例站点,我使用以下内容填充了存储桶中的index.html文件:

这就是你需要的一切!通过大约200行Terraform,我们已经创建了前端应用程序、后端应用程序、两个应用程序的SSL证书以及保护这两个应用程序的身份验证机制。保护前端和后端代码从未像现在这样简单,在基础架构级别这样做可以让您的应用程序专注于它们应该做的事情。

希望这些教程能帮助您开始使用BeyondCorp的一些内部服务。

以下是我在研究BeyondCorp和AWS时使用的一些非常棒的资源: