---
title: Istio 中的安全管控出口流量，第一部分
subtitle: 涉及出口流量攻击和出口流量管控要求
description: 涉及出口流量攻击和出口流量管控要求。
publishdate: 2019-05-22
attribution: Vadim Eisenberg (IBM)
keywords: [traffic-management,egress,security]
---

这是我计划发布的关于 Istio 中出口流量安全管控系列文章中的第一部分。在这一期，会阐述为什么集群需要应用出口流量管控，要防止的出口流量相关的攻击有哪些，以及出口流量管控系统的要求有哪些。
一旦同意集群的出口流量应该被管控，那么就会出现下面的问题：出口流量安全管控系统需要什么？针对这些要求的最佳解决方案是什么？（捣乱分子：以我之见 Istio 是最佳解决方案）
下一期将阐述 [Istio 中实现出口流量的安全管控](/zh/blog/2019/egress-traffic-control-in-istio-part-2/)，并和其它方案进行对比。

对于服务网格来说入口流量才是最重要的安全问题。一定要防止入侵者通过入口 API 渗透集群。既然这么说，流出服务网格的安全同样非常重要。一旦集群被攻破，你必须要有预案，尽可能的减少损害，并且要阻止攻击者使用集群对集群外的服务和已有系统进行进一步攻击。要达到这么目标，需要出口流量的安全管控。

合规要求是要实施出口流量安全管控的另外一个原因。例如，[支付卡行业 (PCI) 数据安全标准](https://www.pcisecuritystandards.org/pci_security/)进出流量都必须限制在必要的范围之内：

{{< quote >}}
_1.2.1 将入口和出口流量限制为持卡人数据环境所必需的流量，并明确拒绝所有其他流量。_
{{< /quote >}}

特别是对出口流量：

{{< quote >}}
_1.3.4 不允许持卡人数据环境没有授权的出站流量进入互联网。。。持卡人数据环境流出的所有流量应该做评估，以保证流量符合既定的授权规则。应该检查链接上的流量并限制只允许认证过的通信（例如：通过限制源/目的的地址/端口，包括限制传输内容）。_
{{< /quote >}}

我们从涉及出口流量的攻击开始。

## 流量攻击 {#the-attacks}

在还没有被攻击的时候 IT 部门就必须要假设会被攻击，并且它的部分基础设施可能已经损坏或者未来会出现损坏。一旦攻击者能渗透集群中的应用程序，他们就可以继续攻击外部服务了：已有系统，外部 web 服务和数据库。攻击者可能想偷取应用程序的数据并且发送到他们的外部服务上。攻击者的恶意程序会访问攻击者的服务器来下载更新。攻击者可能使用集群中的 pod 执行 DDOS 攻击或者闯入外部系统。即便您[不知道](https://en.wikipedia.org/wiki/There_are_known_knowns)攻击的所有可能类型，你还是想减少任何攻击的可能性，无论是已知还是未知的攻击。

外部攻击者通过应用程序的缺陷从服务网格外部访问到应用程序的容器进行攻击，但是攻击者同样也可能来自内部，比如：组织内部的恶意 DevOps 人员。

为了防止以上所说的攻击，必须应用一些出口流量管控策略。我们在下一节介绍出口流量管控。

## 出口流量安全管控解决方案 {#the-solution-secure-control-of-egress-traffic}

出口流量安全管控的意思是监控出口流量并且针对出口流量应用所有的安全策略。
监控出口流量，可以对它进行分析（可能是离线的），即便你无法实时阻止攻击，也要检测攻击事件。
另外一个减少攻击可能性的方法是遵循[需要知道](https://en.wikipedia.org/wiki/Need_to_know#In_computer_technology]) 的原则进行指定限制访问策略。

现在来看看已经收集到的出口流量管控要求。

## 出口流量管控要求 {#requirements-for-egress-traffic-control}

我的同事（在 IBM）和我从一些客户那里收集了一些出口流量安全管控的要求，并把它们和 [Kubernetes 网络特定兴趣小组的出口流量管控要求](https://docs.google.com/document/d/1-Cq_Y-yuyNklvdnaZF9Qngl3xe0NnArT7Xt_Wno9beg)做了整合。

Istio 1.1 满足所有的收集要求：

1.  使用 [SNI](https://en.wikipedia.org/wiki/Server_Name_Indication) 支持 [TLS](https://en.wikipedia.org/wiki/Transport_Layer_Security) 或者用 Istio 支持 [TLS 源](/zh/docs/reference/glossary/#tls-origination)

1.  **监视器** SNI 和每个出口访问的源 workload。

1.  定义和执行 **每个集群的策略**，比如：

    * 集群中所有应用程序可能访问 `service1.foo.com` （指定的主机）

    * 集群中所有的应用程序可能访问  `*.bar.com` (泛域名) 下的任何主机

     必须阻止所有未明确的访问。

1.  定义和执行**每个源的策略**， _Kubernetes 可感知_：

    * 应用 `A` 可能访问 `*.foo.com`。

    * 应用 `B` 可能访问 `*.bar.com`。

    必须阻止其他访问，尤其是应用 `A` 到 `service1.bar.com` 的访问。

1.  **防篡改*。万一有一个应用的 pod 被破坏了，要防止受损的 pod 逃离监控，防止发送假信息给监控系统，防止破坏出口策略。

1.  有这点就更好：流量管控对应用程序要**透明**。

对每个要求我来详细介绍以下。第一个要求指出，必须支持对外服务访问只能使用 TLS。在看到所有出集群的流量都必须加密后，这个要求就出现了。这意味着要么是应用程序执行 TLS，要么是 Istio 必须为应用程序执行 TLS。
注意如果应用程序执行了 TLS，Istio 代理是无法看到原始的流量的，只能看到加密后的，所以代理只能看到 TLS 协议。对代理来说它不关心原始协议是 HTTP 还是 MongoDB ，所有的 Istio 代理只能看到 TLS 流量。

第二个要求指出：必须监控 SNI 和流量源。监控是防止攻击的第一步。即使攻击者可以从集群内访问外部服务，如果监控了访问请求，就会有机会发现可疑流量并且采取纠正措施。

注意如果是应用程序发起的 TLS，Istio 的 sidecar 代理就只能看到 TCP 流量和包含 SNI 的 TLS 握手。 源 pod 的标签可以识别出流量来源，但是 pod 的服务账号或者其它源识标识符也可以用来识别流量。我们把出口流量管控系统的这个特性叫做 _Kubernetes 可感知_：这个系统必须理解 Kubernetes 组件，比如 pod 和服务账号。如果这个系统不是 Kubernetes 可感知的，那它只能监控 IP 地址，并把它作为源的标示。

第三个要求指出：Istio 运维人员必须能为整个集群所有的出口流量定规策略。策略指出集群中的 pod 可能会访问哪些外部服务。外部服务可以通过服务的[全域名](https://en.wikipedia.org/wiki/Fully_qualified_domain_name) （比如 `www.ibm.com`）或者泛域名（比如：`*.ibm.com`）进行标示。只有指定的外部服务可以访问，其它所有的出口流量都要被阻止。

这个要求是为了阻止攻击者访问恶意站点而提出的，比如下载更新/操作他们的恶意软件。同样也想去限制攻击者可以访问和攻击的外部站点的数量。只允许集群内应用程序需要访问的外部站点并且阻止其它所拥有的服务访问，这样减少了[攻击面](https://en.wikipedia.org/wiki/Attack_surface)。当外部服务有了它们自己的安全机制，你想使用[纵深防御](https://en.wikipedia.org/wiki/Defense_in_depth_(computing)) 并且使用多个安全层：除了外部系统的安全层外，集群内还有一个安全层。

这个要求意味着外部服务必须能用域名来标示。我们把出口管控系统的这个特性叫做 DNS 感知。如果系统不是 DNS 可感知的，外部服务必须用 IP 地址标示。
使用 IP 地址不方便而且经常不灵活，因为服务的 IP 地址会变的。有时候服务的所有 IP 地址甚至都不知道，比如：[CDN](https://en.wikipedia.org/wiki/Content_delivery_network)。

第四个要求指出：出口流量的源都必须添加策略，以高效扩展第三个要求。策略能明确那个源可以访问那个外部服务，并且就像第二个要求一样源必须要标示，例如：通过源 pod 的标签或者通过 pod 的服务账号。
这意味这策略的执行也必须是 Kubernetes 可感知的。如果策略执行不是 Kubernetes 可感知的，策略必须通过 pod 的 IP 来标示流量的源头，使用 pod 的 IP 是不方便的，特别是 pod 启动和销毁，而它们的 IP 是不固定的。

第五个要求指出：即使集群被攻破并且攻击者管控了一些 pod，他们也必须不能欺骗监控或者违反出口管控系统的策略。我们才能说这样的系统提供了出口流量的安全管控。

第六个要求指出：提供的流量管控服务要不能改变应用程序容器，特别是不能修改应用程序代码和不能修改容器环境。我们把这样的做法称为透明出口流量管控。

在下一篇文章中，我将展示 Istio 作为出口流量管控系统的示例，由此说明它可以满足所有这些要求，特别是它的透明性、DNS 感知能力和 Kubernetes 感知能力。

## 总结 {#summary}

希望您确信对于集群安全来说出口流量管控是非常重要的。在[这个系列文章的第二部分](/zh/blog/2019/egress-traffic-control-in-istio-part-2/) 我讲述了使用 Istio 实现出口流量安全管控的方法。在[这个系列文章的第三部分](/zh/blog/2019/egress-traffic-control-in-istio-part-3/) 我和其它方案进行了对比，比如 [Kubernetes 网络策略](https://kubernetes.io/docs/concepts/services-networking/network-policies/)以及已有的其它出口代理/防火墙方案。
