Istio技术与实践6:Istio如何为服务提供安全防御能力

凡是产生链接关系,就一定带来安全问题,人类社会如此,服务网格世界,亦是如此。html

今天,咱们就来谈谈Istio第二主打功能---保护服务。面试

那么,便引出3个问题:api

Istio凭什么保护服务?浏览器

Istio具体如何保护服务?安全

如何告诉Istio发挥保护能力?网络

1      Istio凭什么保护服务?

将单体应用程序分解为一个个服务,为大型软件系统的开发和维护带来了诸多好处,好比更好的灵活性、可伸缩性和可复用性。但这也带来了一些安全问题:架构

l  为了抵御中间人攻击,须要对流量进行加密运维

l  为了提供灵活的服务访问控制,须要 mTLS(双向的安全传输层协议)和细粒度的访问策略工具

l  要审计谁在何时作了什么,须要审计工具性能

Istio 尝试提供全面的安全解决方案来解决这3个问题。

 

如上图所示,

Istio 安全的三大目标是:

l  默认安全(Security by default):应用程序代码和基础结构,无需更改。

l  深度防护(Defense in depth):与现有安全系统集成,提供多层防护。

l  零信任网络(Zero-trust network):在不受信任的网络上,构建安全解决方案。

为了实现这3个目标,Istio 安全功能提供了4大守护系统:

l  强大的身份(Identity)系统

l  健壮的策略(Policy)系统

l  认证,受权和审计(AAA:Authentication,Authorization,Accounting)系统,用于保护服务和数据

l  透明的 TLS 加密(Encryption)系统。

就保护对象而言,Istio 安全系统能够抵御来自内部或外部的威胁,这些威胁主要针对服务网格内的端点(Endpoints),通讯(Communication),平台(Platform)和数据(Data)。

2      Istio具体如何保护服务?

在安全方面,Istio具有3个远大的目标,配备了4大守护系统,那么它究竟是经过怎样的架构实现这个目标的呢,又经过什么样的安全基础设施,和kubernetes配合呢?

2.1      Istio安全架构

 

如上图,与Istio的4大守护系统相对应,Istio 中涉及安全的组件有:

Pilot :将受权策略和安全命名信息分发给代理

Proxy :实现客户端和服务端之间的安全通讯

Citadel :用于密钥和证书管理

Mixer :管理受权和审计

因而可知,Pilot不只负责流量规则和策略的分发,还负责安全相关策略的下发,有点像皇上的贴身太监,负责宣读圣旨;Proxy有点像各州属的州官,负责奉天承运;Citadel有点像玉玺和虎符,负责鉴真去假;Mixer有点像三省六部,负责受权审计。

2.2      两个安全基本概念

2.2.1        Identity

身份(Identity)是几乎全部安全基础架构的基本概念。在服务和服务的通讯开始前,双方必须用其身份信息交换凭证,以达到相互认证的目的。在客户端,根据安全命名(secure naming)信息,检查服务端的标识,以查看它是不是该服务的受权运行程序;在服务端,服务端能够根据受权策略(authorization policies)信息,肯定客户端能够访问哪些数据,审计其在什么时间访问了什么,拒绝未受权客户端的访问。

在 Istio 身份模型中,Istio 使用一流的服务标识来肯定服务的身份。这为表示人类用户,单个服务或一组服务提供了极大的灵活性和粒度。在没有此类身份的平台上,Istio 可使用能够对服务实例进行分组的其余身份,例如服务名称。

不一样平台上的 Istio 服务标识:

l  Kubernetes: Kubernetes 服务账户

l  GKE/GCE: 可使用 GCP 服务账户

l  AWS: AWS IAM 用户/角色 账户

l  On-premises (non-Kubernetes): 用户账户,自定义服务账户,服务名称,istio 服务账户或 GCP 服务账户。

作个类比,京东和天猫都有本身的一套很是成熟的服务帐户系统,淘宝只须要复用天猫的帐户系统便可,无需从新开发一套,这样咱们就能够用天猫的帐号,直接登陆淘宝。而Istio也更倾向于复用业界一流的服务帐户系统,如Kubernetes和AWS的,但也能够自定义服务帐户,并按需复用Kubernetes的帐户系统。

2.2.2  PKI 

Istio PKI(Public Key Infrastructure)创建在 Istio Citadel 之上,可为每一个工做负载提供安全且强大的工做负载标识。Istio 使用 X.509 证书来携带 SPIFFE 格式的身份信息。PKI 还能够大规模自动化地进行密钥和证书轮换。

Istio 支持在 Kubernetes pod 和本地计算机上运行的服务。目前,Istio为每一个方案使用不一样的证书密钥配置机制,下面试举例Kubernetes方案的配置过程:

  1. Citadel 监视 Kubernetes apiserver,为每一个现有和新的服务账户建立 SPIFFE 证书和密钥对。 Citadel 将证书和密钥对存储为 Kubernetes secrets。
  2. 建立 pod 时,Kubernetes 会根据其服务账户经过 Kubernetes secret volume 将证书和密钥对挂载到 pod。
  3. Citadel 监视每一个证书的生命周期,并经过重写 Kubernetes secret 自动轮换证书。
  4. Pilot 生成安全命名信息,该信息定义了哪些服务账户能够运行某个服务。接着Pilot 将安全命名信息传递给 Envoy。

3      如何告诉Istio发挥保护能力?

如上一章节所言,Istio基于控制面组件,引入了一流的服务帐户系统,结合强大的PKI,实现了对服务网格的安全守护。同时,Istio也开放了接口,让咱们能够进行精细化的配置,全方位知足咱们对服务的安全需求。

服务安全,老是离不开两个具体过程:认证(Authentication)和鉴权(Authorization)。Istio经过Policy和MeshPolicy文件,实现对认证相关功能的定义;经过RbacConfig、ServiceRole和ServiceRoleBinding文件,实现对鉴权相关功能的启用和定义。

让咱们举个几个通俗的例子来区分认证和鉴权:

进火车站须要提供身份证和火车票,身份证能够证实你就是你,这是认证;火车票能够证实你有权上那趟火车,这是受权。

又例如,你要访问本身淘宝的购物车,须要先登陆,这是认证。你要访问朋友的购物车,就须要他的容许,这是受权。

再例如,有经验的朋友能发现浏览器常常会面对两个错误码:401和403。一般而言,401就是未登陆的意思,须要认证;403就是禁止访问的意思,须要受权。

3.1      认证

Istio 提供两种类型的身份认证:

l  传输身份认证,也称为服务到服务身份认证:对直连客户端进行验证。Istio 提供双向TLS做为传输身份认证的全栈解决方案。咱们能够轻松启用此功能,而无需更改服务代码。这个解决方案:

l  为每一个服务提供强大的身份认定,以实现跨群集和跨云的互操做性。

l  保护服务到服务通讯和最终用户到服务通讯。

l  提供密钥管理系统,以自动执行密钥和证书生成,分发和轮换。

l  来源身份认证,也称为终端用户身份认证:对来自终端用户或设备的原始客户端请求进行验证。Istio 经过 JSON Web Token(JWT)、Auth0、Firebase Auth、Google Auth 和自定义身份认证来简化开发者的工做,使之轻松实现请求级别的身份认证。

在这两种状况下,Istio 都经过自定义 Kubernetes API 将身份认证策略存储在 Istio 配置存储(Istio config store)中。Pilot会在适当的时候进行同步,为每一个Proxy更新其最新状态以及密钥。此外,Istio 支持在许可模式下进行身份认证,以帮助咱们理解策略变动先后,服务的安全状态是如何变化的。

3.1.1        认证架构

咱们可使用身份认证策略,为 Istio 网格中接收请求的服务指定身份认证要求。咱们使用 .yaml 文件来配置策略,策略将保存在 Istio 配置存储中。在任何策略变动后,Pilot 会将新策略转换为适当的配置,下发给Envoy,告知其如何执行所需的身份认证机制。Pilot 能够获取公钥并将其附加到 JWT 进行配置验证。或者,Pilot 提供 Istio 系统管理的密钥和证书的路径,并将它们安装到负载 Pod 中,以进行双向 TLS。

 

本文屡次提到双向TLS认证,让咱们理解一下其在Istio里的实现。Istio 经过客户端和服务端各自配备的Envoy进行通讯,也就是说,客户端和服务端的流量,是被各自的Envoy接管了的。对于客户端调用服务端,遵循的步骤是:

  1. Istio 将出站流量从客户端从新路由到客户端的本地 Envoy。
  2. 客户端 Envoy 与服务端 Envoy 开始双向 TLS 握手。在握手期间,客户端 Envoy 还执行安全命名检查,以验证服务证书中提供的服务账户是否有权运行目标服务。
  3. 客户端 Envoy 和服务端 Envoy 创建了一个双向的 TLS 链接,Istio 将流量从客户端 Envoy 转发到服务端 Envoy。
  4. 受权后,服务端 Envoy 经过本地 TCP 链接将流量转发到服务端的服务。

3.1.2        认证策略配置

和其余的 Istio 配置同样,能够用 .yaml 文件的形式来编写认证策略,而后使用 Istioctl 二进制工具进行部署。以下图的配置,经过配置Policy文件,对reviews服务进行了传输身份认证的配置,要求其必须使用双向TLS作认证。

apiVersion: "authentication.Istio.io/v1alpha1"

kind: "Policy"

metadata:

  name: "reviews"

spec:

  targets:

  - name: reviews

    peers:

  - mtls: {}

3.2      受权

Istio 的受权功能,也称为基于角色的访问控制(RBAC),为 Istio 服务网格中的服务提供命名空间级别,服务级别和方法级别的访问控制。它的特色是:

l  基于角色的语义,简单易用。

l  包含服务到服务和终端用户到服务两种受权模式。

l  经过自定义属性灵活定制受权策略,例如条件,角色和角色绑定。

l  高性能,由于 Istio 受权功能是在 Envoy 里执行的。

3.2.1        受权架构

 

上图显示了基本的 Istio 受权架构。和认证的生效过程同样,运维人员使用.yaml文件指定 Istio 受权策略。部署后,Istio 将策略保存在Istio Config Store中。Pilot 会一直监视 Istio 受权策略的变动,若是发现任何更改,它将获取更新的受权策略,并将 Istio 受权策略分发给与服务实例位于同一 pod 内的 Envoy 代理。

每一个 Envoy 代理都运行一个受权引擎,该引擎在运行时受权请求。当请求到达代理时,受权引擎根据当前受权策略评估请求上下文,并返回受权结果ALLOW或DENY。

3.2.2        受权策略配置

咱们可使用 RbacConfig 启用受权策略,并使用ServiceRole和ServiceRoleBinding配置受权策略。

RbacConfig是一个网格维度的单例,其固定名称值为default,也就是说咱们只能在网格中配置一个RbacConfig实例。与其余 Istio 配置对象同样,RbacConfig被定义为Kubernetes CustomResourceDefinition (CRD)对象。

在RbacConfig中,运算符能够指定mode值,它能够是:

l  OFF:禁用 Istio 受权。

l  ON:为网格中的全部服务启用了 Istio 受权。

l  ON_WITH_INCLUSION:仅对包含字段中指定的服务和命名空间启用 Istio 受权。

l  ON_WITH_EXCLUSION:除了排除字段中指定的服务和命名空间外,网格中的全部服务都启用 Istio 受权。

在如下示例中,为default命名空间启用了 Istio 受权,。

apiVersion: "rbac.Istio.io/v1alpha1"

kind: RbacConfig

metadata:

  name: default

  namespace: Istio-system

spec:

  mode: 'ON_WITH_INCLUSION'

  inclusion:

    namespaces: ["default"]

针对服务和命名空间启用受权后,咱们还须要配置具体的受权策略,这经过配置ServiceRole和ServiceRoleBinding实现。与其余 Istio 配置对象同样,它们一样被定义为CRD对象。

ServiceRole定义了一组访问服务的权限。ServiceRoleBinding向特定对象授予 ServiceRole,例如用户,组或服务。

ServiceRole 和 ServiceRoleBinding 组合规定了: 容许谁在哪些条件下作什么,具体而言:

l  谁指的是 ServiceRoleBinding 中的 subject 部分。

l  作什么指的是 ServiceRole 中的 rule 部分。

l  哪些条件指的是咱们能够在 ServiceRole 或 ServiceRoleBinding 中使用Istio Attributes指定的 condition 部分。

让咱们再举一个简单的例子,以下图,ServiceRole和 ServiceRoleBinding的配置规定:将全部用户(user=“*”)绑定为(products-viewer)角色,这个角色能够对products这个服务发起GET或HEAD请求,可是其限制条件是请求头必须包含version,且值为v1或v2。

apiVersion: "rbac.Istio.io/v1alpha1"

kind: ServiceRole

metadata:

  name: products-viewer

  namespace: default

spec:

  rules:

  - services: ["products"]

methods: ["GET", "HEAD"]

    constraints:

    - key: request.headers[version]

      values: ["v1", "v2"]

---

apiVersion: "rbac.Istio.io/v1alpha1"

kind: ServiceRoleBinding

metadata:

  name: binding-products-allusers

  namespace: default

spec:

  subjects:

  - user: "*"

  roleRef:

    kind: ServiceRole

    name: "products-viewer"

 

至此,咱们作个简单的总结:单体应用程序拆分红成千上百个服务后,带来了安全问题,Istio尝试在由服务组成的服务网格里,加入了一套全栈解决方案。这套方案里,Istio默默处理了大部分安全基础设施,但也暴露了认证和受权两个功能让用户进行自定义配置。咱们经过Policy、MeshPolicy以及RbacConfig、ServiceRole、ServiceRoleBinding就能够完成对认证和受权环节全部功能的配置,而不须要侵入地改动任何服务的代码。

相关文章
相关标签/搜索