使用 Istio 服务网格实现零信任网络

作者:Paul Klinker

翻译:Bach(才云)

校对:星空下的文仔(才云)、bot(才云)

微服务有很多优点,包括独立的拓展、隔离的业务逻辑、独立的生命周期管理以及简易的分布式开发。这些优点同时也带来了一些弊端,例如微服务可能会增加安全漏洞,因为每个微服务都可以是攻击目标,这无形间增加了攻击面。如果入侵者进入网络,它们可以肆意地攻击单个微服务,因此仅保护网络边界(network border)是不够的,还必须保护网络内部,这就是零信任(Zero Trust)的来源。

零信任的概念由 John Kindervag 提出,它指的是无论网络范围是内部的还是外部的,都不能有任何隐式信任(implicitly trust),任何来源都需要显式验证,并使用最小特权来限制对资源的访问。简而言之,零信任策略就是不相信任何人。除非网络明确知道接入者的身份,否则任谁都别想进入。无论是 IP 地址、主机等等,只要不知道用户身份或者不清楚授权途径的,统统不放进来。

本文展示了将 Istio 服务网络配置为零信任网络的具体步骤,主要使用一个简单的微服务架构,然后通过 Istio 删除隐式的服务到服务(service-to-service)信任关系。

使用自行开发的解决方案保护微服务网络可能非常困难,但服务网格(如 Istio)可以提供帮助,它确保了南北流量(north-south traffic)和东西流量(east-west traffic)的安全。南北流量是进入和离开服务网格的流量,东西流量是网格内的流量,通常是服务到服务的流量。Istio 通过入口(ingress)和出口(egress)网关处理南北流量,流量路由则是由虚拟服务管理。Istio 的 Envoy Proxy 可以管理东西流量,在服务的 Kubernetes Pod 中作为边车(Sidecar)运行。下面我们就看一下这些概念在小型服务网格中的示例。

K8sMeetup

在服务网格外公开服务

在该例子中,我们将从两个微服务开始:一个在 NGINX Web 服务器中运行的 Web 客户端和一个 Java/Spring Boot 后端的 REST Service。

该客户是个“友好”客户,我们允许其访问后端服务。后面我们将向网格添加一个微服务,一个恶意的“敌人”Web 客户端,该客户端将被拒绝访问后端微服务。后端微服务称为“Capitol-Info”,具有查询和插入 Capitol 数据库的功能。这些微服务公开的 endpoint 如下图所示,该图显示了开放的、不受保护的服务网格体系结构。

使用 Istio 服务网格实现零信任网络_第1张图片

在 Istio 服务网格中运行的 Capitol-Client 微服务和 Capitol-Info 微服务

我们现在在尝试保护服务网格的微服务,所以不调用客户端网站到后端微服务。相反,我们要创建一个 API 网格,并允许该网关调用服务,从而实现服务到服务的调用。NGINX 在 Web 客户端的 /capitolservice 路径下提供了一个 API 网关。当使用此路径调用 Web 客户端时,NGINX 网关会将代理 Capitol-Info 服务的调用。

对于 Istio 配置,我们首先为客户端和数据微服务(Data Microservices)提供入口网关和虚拟服务。入口网关是标准 80 端口(Web)网关,我们将重点放在 Istio Virtual Service 处理流量路由。我们从以下虚拟服务定义中所示的 Capitol-Info 服务开始:

使用 Istio 服务网格实现零信任网络_第2张图片

Capitol Service VirtualService 定义

Capitol-Info 虚拟服务表明,我们仅开放了入站流量(inbound traffic)的 getCapitol REST 操作,没有开放 addCapitol REST 操作的 insert 功能。因此,addCapitol REST 操作不受外部(南北)调用的保护,也不受服务网格内其他微服务调用(东西调用)的保护。这样,getCapitol 调用对南北和东西的调用是开放的。

使用 Istio 服务网格实现零信任网络_第3张图片

Capitol-client Virtual Service 定义

The capitol-client 虚拟服务表明我们正在打开 /capitolservice 下的 API 网关,以及创建在 /info 路径下的 HTML 页面。

K8sMeetup

锁定微服务

本文已经介绍了基本架构,下面我们使用授权策略将其锁定。这是迈向零信任网络的重要一步,不再隐式信任网格中的其他服务。

要锁定微服务,我们首先使用“拒绝所有”策略,并应用于所有命名空间(默认)以锁定所有通道。然后,我们创建一个 Istio AuthorizationPolicy(授权策略) 以打开 endpoint。在第一个例子中,我们应用的策略允许任何调用者访问我们创建的资源:

使用 Istio 服务网格实现零信任网络_第4张图片

我们可以看到这里允许基于 HTTP 操作(GET、POST)和 URI 路径访问微服务。这里要注意,我们必须添加 NGINX API 网关、/capitolservice 到 AuthorizationPolicy 中,以使其可访问。如果少了这一步,那么网页将打不开,并且调用后端 Capitol-Info 微服务的功能也会被阻止。

应用了该授权策略后,我们就可以访问我们的网页和 REST endpoint。这里要注意,虽然我们允许任何人访问 /addCapitol,但外界仍无法访问它,因为我们尚未在虚拟服务中创建路由。如果我们到 Web 客户端查询 Capitol,http://localhost/info/QueryCapitol.html,我们可以访问该站点并运行查询:

使用 Istio 服务网格实现零信任网络_第5张图片

客户端微服务,Capitol 查询网页

现在我们已经使用了宽松的授权策略打开了流量,下面再选择一些锁定策略。如果我们通过删除 Web(/info)和 API(/capitolservice)的访问允许来阻止对 Web 客户端的访问,这样就限制了进入 Capitol-Client 的流量。查看下面的客户端和服务器授权策略,如果我们应用仅允许访问 Capitol 数据服务的策略,那么网站的访问就会被阻止。资源仅允许 /getCapitol REST 调用入站南北流量,而 /appCapitol 仍由于缺少虚拟服务路由而被阻塞。

使用 Istio 服务网格实现零信任网络_第6张图片

由于 Capitol-Client 仅在默认命名空间内运行,因此无法访问。我们也未明确授予特权,因此“拒绝所有”策略对这些资源均有效。我们导航到网页 http://localhost/info/GetCapitol.html,此时访问仍被拒绝。

使用 Istio 服务网格实现零信任网络_第7张图片

阻止网页是件奇怪的事情,相反,我们只希望保护后端 API 免受外界访问,但网站希望可以打开。现在我们假设不希望任何人直接从 Capitol-Info 服务中获取数据,而是仅通过 Capitol-Client 获取数据。对此,我们可以删除入口,阻止外部流量,但服务网格内的其他实体仍然可以获取。因此,不仅要阻止外部流量来实现零信任,我们还需要阻止未经批准的内部服务到服务的流量。

上述授权策略的一个问题是命名空间是全局的(默认),这意味着规则适用于命名空间内的所有服务。Capitol-Info 微服务和 Capitol-Client 微服务具有不同的 endpiont,因此我们为服务分别设置配置。

客户端授权策略

使用 Istio 服务网格实现零信任网络_第8张图片

上面的客户端策略打开了服务网格外部和内部客户端内的入站流量,因为它没有指定“from”的规则,但指定了“to”的规则。

服务端授权策略

使用 Istio 服务网格实现零信任网络_第9张图片

应用以上策略会为 Capitol-Client 和 Capitol-Info 微服务提供其自己的授权策略。查看服务网格 Istio 的 Kiali 仪表板,我们可以看到已应用的授权策略。

使用 Istio 服务网格实现零信任网络_第10张图片

Kiala 仪表板显示 Istio 网关、虚拟服务和授权策略

这些特定策略意味着,我们作为微服务的所有者,能控制谁可以访问它们。随着授权策略的分离,我们能锁定 Capitol-Info 服务的可信任东西流量。

使用 Istio 服务网格实现零信任网络_第11张图片

现在更新后的 Capitol-Info 授权策略,将流量限制为默认域(default domain)中的 Capitol-Client 微服务。这是因为我们在“from”规则中指定了 principal。下面测试这一点,我们在网格中添加一个“敌人”微服务。如前所述,零信任意味着不会隐式信任其他参与者,所以即便该微服务存在于服务网格中,但不意味着我们信任它。我们的数据服务会维护自己的安全配置,可以决定信不信任谁。

假使,敌方服务被恶意内部人员部署到服务网格中。该服务模仿了有效友好客户端的 URI 和 API 网关,如下图所示:

使用 Istio 服务网格实现零信任网络_第12张图片

没有东西安全控制,恶意微服务将严重破坏

如果我们不使用限制性的 Capitol-Info 授权策略,那么敌方微服务可以直接调用 Capitol-Info 微服务。假设敌方服务更进一步,甚至可以声明自己的授权策略,以覆盖“拒绝所有”策略,并将其部署到集群中:

使用 Istio 服务网格实现零信任网络_第13张图片

如果我们查看敌方微服务的配置,它会尝试添加自己的 ALLOW 语句来覆盖 Capitol-Info 服务策略。ALLOW 语句(/enemy 和 /capitolenemy)会覆盖“全部拒绝”策略。对 /getCapitol API 进行 HTTP GET 和 POST 操作的最后一条规则被覆盖和忽略。当我们尝试从敌方客户端调用 getCapitol 或 addCapitol REST 操作时,调用会被阻止并且数据服务会被保护起来。

使用 Istio 服务网格实现零信任网络_第14张图片

在零信任网络中,敌方微服务被阻止访问其他微服务

为了进一步保护我们的数据服务,现在我们使用授权策略保护服务到服务之间的通信,我们可以删除 Capitol-Info 入口官网和虚拟服务,仅允许 Capitol-Client 网页和 API 网关的访问。

K8sMeetup

总结

本文展示了如何通过将服务网格锁定受信任源的流量,以应用零信任原则。使用 Istio,我们可以使用多种资源来限制对微服务的访问,包括限制虚拟服务,以及基于流量源和目的地的授权策略。

原文链接:https://mp.weixin.qq.com/s/a93n0V9Imfgp9kLn8xVoCQ

你可能感兴趣的:(istio,service-mesh)