可靠通信

  • 零信任网络
  • 服务安全

零信任网络

首先我们介绍一下边界安全的概念:将安全措施集中的部署在各个区域的边界之上,重点考虑跨边界的网络流量,比如 VPN,防火墙,内外网都是这个概念的体现。

传统的边界安全对于网络边界的流量进行重点检查,对于可信任区域的流量,给于直接放行,或者至少宽松对待的策略,减少因为安全措施导致的整个系统的复杂度的提升,以及对于网络传输效率的影响。

不过在微服务时代,一切都变了,微服务时代边界安全尽管对于单台节点保护的再好,一旦集群中出现了一个猪队友,该集群作为所谓的内网,也就是可信任区域,也会受到影响,攻击者会通过该台机器,作为跳板,进行内网渗透,从而达到攻击整个集群的目的。

因此,零信任安全模型的概念应运而生,核心思想是:不应当以某种固有特征来自动信任任何流量,除非明确得到了能代表请求来源 (不一定是人,可能是一个服务) 的身份凭证,否则一律不会有默认的信任关系。

传统网络边界安全模型 vs 零信任安全模型

传统网络边界安全模型 零信任安全模型 具体要求
基于防火墙,认为内部可以信任 服务到服务需要认证,环境内的各个服务之间保持警惕(相当于安全范围没有变化,还是单个服务器内部,毕竟最初的单点服务的内网指的就是单个服务器内部) 保护网络边界(仍然有效);服务之间默认没有互信
特定的ip和物理硬件 资源利用率、重用、共享更好,包括 IP 和硬件 受信任的机器运行来源已知的代码
基于ip的认证身份 基于服务的认证 受信任的机器运行来源已知的代码
服务运行在已知的、可预期的服务器上 服务可以运行在任何环境中,比如公有云,私有云 受信任的机器运行来源已知的代码
安全相关的需求由应用来实现,每个应用单独实现 基础设施去实现,比如使用了k8s,那么由k8s等相关基础设备提供基础的安全设施,无需单个服务去实现 集中策略实施点Choke Points(阻塞点/战略咽喉点)一致的应用到全部的服务之上
对服务如何构建、评审、实施的安全需求的约束力较弱 安全相关的需求一致地应用到所有服务 集中策略实施点一致的应用到全部的服务之上
安全组件的可观测性较弱 因为是基础设施去提供的统一的标准的安全策略,所以安全组件的可观测性很强 集中策略实施点一致的应用到全部的服务之上
发布不标准,发布频率较低 标准化的构建和发布流程,每个微服务变更独立,变更更频繁 简单、自动、标准化的变更发布流程(CI/CD & Ops)
工作机器通常是物理机器或者是虚拟机 通常是共享在操作系统中的容器,并且由某些基础设施提供隔离 在共享的操作系统的工作负载之间进行隔离

零信任网络具体落地分析

  • 零信任网络不应该放弃传统的边界安全模型,在微服务器集群的前端部署一个边界安全设备比如防火墙,可以大大提高安全防护能力,将外网流量和内网流量进行隔离,还是可以尽量保护内网的安全,比如可以抵御大量的 DDOS 攻击的大幅度网络流量。
  • 身份的鉴权只认凭证,传统的单点服务由于物理服务器的不变性,比如 MAC 地址,ip 的不变,通常我们使用 ip 等地址作为凭证,微服务时代,由于服务的灵活性,ip 等地址不再是一个稳定的凭证,因此我们需要使用更加稳定的凭证 token 作为鉴权凭证,通常是数字证书。
  • 服务之间没有固定的信任关系,只有已知的通过授权的调用者才能访问服务,比如我们使用微服务设计模式中的断路器和舱壁隔离模式来避免雪崩效应的产生

    断路器模式的主要目的是防止一个服务的故障影响到整个系统的稳定性。它通过监控服务调用的成功和失败次数来实现这一点。当服务调用失败率达到一定阈值时,断路器会 “跳闸”,阻止后续的请求,从而防止故障扩散 断路器状态:通常有三种状态:关闭 (Closed):正常状态,请求正常通过。打开 (Open):故障状态,请求被阻止,通常会有一个超时时间,之后会进入半开状态。半开 (Half-Open):尝试恢复状态,允许有限数量的请求通过,以检测服务是否恢复正常。 舱壁模式的主要目的是隔离服务之间的依赖,防止一个服务的故障影响到其他服务。它通过将系统划分为多个独立的 “舱室” 来实现这一点,每个舱室都有自己的资源 (如线程池、内存等),从而限制故障的影响范围。

  • 集中、共享的安全策略实施点 (Choke Points):微服务提倡每个服务自己独立的负责自身所有的功能性与非功能性需求但是但涉及安全的非功能性需求 (如身份管理、安全传输层、数据安全层) 最好除外,将这种安全功能集中在基础云设施之中可以将安全标准化,高质量化。
  • 受信的机器运行来源已知的代码:服务只能使用认证过的代码和配置,并且只能运行在认证过的环境中,比如使用了 k8s,那么只能使用 k8s 提供的容器,不能使用自己的容器,这样可以保证服务的安全性。安全不仅仅局限于软件运行阶段,还包括软件开发、测试、部署、运维 (软件供应链:CICD & Ops) 等各个阶段。
  • 自动化、标准化的变更管理:一套独立于应用的安全基础设施,可以让运维人员轻松地了解基础设施变更对安全性的影响,并且可以在几乎不影响生产环境的情况下发布安全补丁程序
  • 强隔离性的工作负载:容器相比虚拟机性能是上升的,但隔离性是下降的,因此强调安全性的应用中,容器会有强隔离性的工具方案。

服务安全

在服务之间我们需要权威公证人模式去保证服务之间的安全。只要我们有了 CA 根证书,我们就可以通过 CA 根证书去签发服务的证书,这样我们就可以保证服务之间的安全。

所谓 CA 根证书就跟公理一样,我们使用公理去推导的定理就肯定是对的,同理,使用 CA 根证书去签发的服务证书也肯定是可信的,权威公证人的权威就是这么个意思。

比起传统的 TLS 单向验证,只需要验证服务端的真伪,在微服务中,各个服务之间还需要进行双向验证,既要验证服务端的真伪也要验证调用端的真伪。传统的 TLS 仅仅需要让客户端使用正确的服务器即可,它并不 care 是谁调用了它,毕竟服务端属于公开服务。双向教研就是一种私密链接,它需要让双方都互相可信。

认证

我们先看看节点之间的双向认证

或许你会认为我们需要部署 CA 根证书,然后每个节点都去签发服务证书,这样我们就可以保证服务之间的安全。但是我们也知道,微服务情况下,这些基础设施是由基础设施去提供的,我们只需要保证基础设施提供这些服务即可,通常来说,我们部署微服务,使用 k8s 进行服务编排,使用 istio 进行服务治理,istio 会提供认证功能

如果所有节点皆为 istio 管理,那么可以一键接入 istio 提供的 mTLS 功能 (双向 TLS 认证):

apiVersion: security.istio.io/v1beta1 # istio api
kind: PeerAuthentication # 
metadata:
  name: authentication-mtls # istio 认证名称
  namespace: steamaple-servicemesh # istio 命名空间,只要是满足这个namespace的 k8s pod 都会被启用mTLS
spec:
  mtls: 
    mode: STRICT # 严格模式,只有双向认证通过才能访问

如果尚有一些节点不是 istio 管理,也可以开启宽容模式,受 Istio 管理的服务会允许同时接受明文和 mTLS 两种流量,明文流量仅用于与那些不受 Istio 管理的节点进行交互,需要自行想办法解决明文流量的认证问题,也就是对于这些未被 istio 管理的节点自主开启 mTLS,CA 根证书 -- 授权节点证书,等一套 mTLS 认证方案。

对于普通用户的认证

当来自最终用户的请求进入服务网格时,Istio 会自动根据配置中的 JWKS (JSON Web Key Set) 来验证令牌的合法性,如果令牌没有被篡改过且在有效期内,就信任 Payload 中的用户身份,并从令牌的 Iss 字段中获得 Principal。

授权

我们想要控制一部分服务只允许移动应用调用,另外一部分服务只允许浏览器调用。一种可行的方案就是为不同的调用场景设立角色,进行授权控制,另一种常用的方案是 BFF 网关

istio 同样提供服务之间的授权功能,比如,在 Istio 中,通过以下配置,限制了来自某个空间的内部流量只允许访问某些端点的 GET、POST、PUT、PATCH 方法,而对于来自另一个名空间的外部流量就不作限制,直接放行。

如果我们使用 BFF 网关,那么我们可以在 BFF 网关上进行授权控制,比如我们可以在 BFF 网关上进行用户的认证,然后根据用户的角色进行授权,然后再将请求转发到后端服务。