保护微服务(第一部分)

保护微服务(第一部分)

面向服务的体系结构(SOA)引入了一种设计范式,该技术讨论了高度分离的服务部署,其中服务间通过标准化的消息格式在网络上通信,而不关心服务的实现技术和实现方式。每个服务都有一个明确的,公开的服务描述或服务接口。实际上,消息格式是通过SOAP进行标准化的,SOAP是2000年初由W3C引入的标准,它也基于XML--服务描述通过WSDL标准化,另一个W3C标准和服务发现通过UDDI标准化--另一个W3C标准。所有这些都是基于SOAP的Web服务的基础,进一步说,Web服务成为SOA的代名词 - 并导致其失去作为一种架构模式的本义。SOA的基本原则开始淡化。WS- *栈(WS-Security,WS-Policy,WS-Security Policy,WS-Trust,WS-Federation,WS-Secure Conversation,WS-Reliable Messaging,WS-Atomic Transactions,WS-BPEL等)通过OASIS,进一步使SOA足够复杂,以至于普通开发人员会发现很难消化。

现在,经过这么多年,我们又开始了一段过去实现SOA的基本原理-我们将其称为微服务的旅程。微服务将为应用程序设计提供专注,范围和模块化的方法。

微服务和物联网(IoT)、容器化以及区块链一样,是现在最流行的术语之一。每个人都在谈论微服务,每个人都希望实现微服务。“微服务”一词首次提出是在2011年5月威尼斯的软件架构师研讨会上,它被用来解释他们已经见证了一段时间的常见架构风格。

Sam Newman所著的《构建微服务》是一本非常棒的书,当你阅读它时,你会意识到,微服务不仅仅是SOA,这不仅仅是一个架构模式 - 而是围绕一个架构模式的新文化建设,由主要目标驱动 - 更快的部署或生产速度。

构建微服务〜设计细粒系统

在保护微服务方面有多种观点:

  • 安全开发生命周期和测试自动化:微服务背后的关键推动力是生产速度。人们应该能够对服务进行更改,对其进行测试并立即将其部署到生产环境中。为了确保我们不在代码级引入安全漏洞,我们需要有一个适当的静态代码分析和动态测试计划 - 最重要的是这些测试应该是持续交付(CD)过程的一部分。应该在开发生命周期的早期识别出任何漏洞,并缩短反馈周期。
  • DevOps安全性:有多种微服务部署模式 - 但最常用的是每服务器模式。该主机并不一定意味着一台物理机器-也有可能这将是一个容器(Docker),这时我们需要考虑容器级级别的安全。我们如何将一个容器与其他容器隔离开来,以及容器与主机操作系统之间有什么隔离级别?
  • 应用程序级安全性:我们如何验证和访问控制用户以使用微服务,以及如何保护微服务之间的沟通渠道?

这篇博文介绍了一种安全模型,以解决我们在应用程序级别保护微服务所面临的挑战。

单体系统与微服务

在单体应用程序中,所有服务都部署在同一个应用程序服务器中,应用程序服务器本身提供会话管理功能。服务之间的交互是本地调用,所有服务都可以共享用户的登录状态,每个服务(或组件)都不需要对用户进行身份验证。身份验证将在拦截所有服务调用的拦截器中集中完成。身份验证完成后,如何在服务(或组件)之间传递用户的登录上下文因平台而异。下图显示了单体应用程序中多个组件之间的交互。

在Java EE环境中,拦截器可以是一个servlet过滤器。这个servlet过滤器将拦截所有到达它注册的上下文的请求,并执行认证。服务调用者应该携带有效的凭据或可以映射到用户的会话令牌,一旦servlet过滤器找到用户,它就可以创建一个登录上下文并将其传递给下游组件,每个下游组件都可以从登录上下文中识别用户以进行任何授权。

安全性在微服务环境中变得具有挑战性。在微服务领域,这些服务的作用域和部署是在分布式的多个容器中。服务交互不再是本地的,而是远程的,大多数是通过HTTP交互。下图显示了多个微服务之间的交互。

这里面临的挑战是,我们如何以对称的方式验证用户并在微服务之间传递登录上下文,以及每个微服务如何授权用户。

保护服务间的通信

在这篇博文中,我将讨论两种保护服务到服务通信的方法。一个基于JWT,另一个基于TLS相互认证。

JSON Web令牌(JWT)

JWT(JSON Web令牌)定义了一个在相关方之间传输数据的容器。它可以用来:

  • 在相关方之间传播一个人的身份。
  • 在相关方之间传播用户权利。
  • 通过不安全的渠道在相关方之间安全地传输数据。
  • 断言一个人的身份,鉴于JWT的接受者信任断言方。

已签名的JWT称为JWS(JSON Web签名),加密的JWT称为JWE(JSON Web加密)。事实上,JWT本身并不存在 - 要么是JWS要么是JWE。它就像一个抽象类--JWS和JWE是具体的实现。

JWT,JWS和JWE不是傻瓜!

从一个微服务到另一个微服务的用户上下文可以与JWS一起传递。由于JWS通过上游微服务已知的密钥签名,因此JWS将携带最终用户身份(如JWT中的声明)和上游微服务的身份(通过签名)。为了接受JWS,下游的微服务首先需要根据JWS本身中嵌入的公钥验证JWS的签名。这还不够 - 我们还需要检查我们是否信任该密钥。微服务之间的信任可以通过多种方式建立,一种方法是将可信证书通过服务提供给每个微服务。毫无疑问,这种方式在微服务部署中难以扩展。我想建议的方法是建立一个私人证书颁发机构(CA),如果需要的话,还可以由不同的微服务团队建立中级证书颁发机构。现在,下游微服务不再信任每个单独的证书,而是信任根证书颁发机构或中介,这将大大减少证书配置的开销。

JWT验证的成本

每个微服务必须承担JWT验证的成本,其中还包括验证令牌签名的加密操作。在微服务级别缓存JWT可以降低重复令牌验证带来的开销。缓存过期时间必须与JWT到期时间相匹配。如果JWT到期时间非常短,缓存的作用将会降低。

识别用户

JWT 在其声明集中携带名为sub的参数,该参数代表拥有JWT的主体或用户。除了主体标识符之外,JWT还可以携带用户属性,例如first_namelast_nameemail等。微服务可以通过查找这些属性在操作过程中识别用户。属性的值仅对给定颁发者是唯一的。如果你有一个微服务,它接受来自多个发行人的令牌,那么发行者和属性的组合将决定用户的唯一性。

JWT声明集中的aud参数指定令牌的目标受众。它可以是单个收件人或一组收件人。在进行任何验证检查之前,令牌收件人必须首先检查JWT是否发布给他使用,如果不是,应立即拒绝。在发布令牌之前,令牌发行者应该知道令牌的预期接收者(或接收者),并且aud参数的值必须是令牌发行者与接收者之间的预先约定的值。在微服务环境中,可以使用正则表达式来验证令牌的受众,例如,令牌中aud的值可以是* .facilelogin.com,facilelogin.com域下的每个接受者都可以拥有自己的aud值:foo.facilelogin.combar.facilelogin.com

TLS相互认证

无论是在TLS相互认证还是基于JWT的方法中,每个微服务都需要拥有自己的证书。这两种方法之间的区别在于,在基于JWT的认证中,JWS可以同时承载最终用户身份和上游服务身份,而在使用TLS相互身份验证时,最终用户身份必须在应用程序级别传递。

证书撤销

在我们上面讨论的两种方法中,证书撤销都有点棘手。证书撤销是一个难以解决的问题—尽管有多种选择:

  • CRL(认证撤销清单/ RFC 2459)
  • OCSP(在线证书状态协议/ RFC 2560)
  • OCSP Stapling (RFC 6066)
  • 必须OCSP Stapling(draft-hallambaker-muststaple-00)

CRL是一种不常用的技术。启动TLS握手的客户端必须从对应的证书颁发机构(CA)获取撤销证书的长列表,然后检查服务器证书是否在撤销的证书列表中。客户端可以在本地缓存CRL,而不是为每个请求做这件事,但是这会遇到了基于陈旧数据做出安全决策的问题。当使用TLS相互认证时,服务器也必须对客户端执行相同的证书验证。最终,人们认识到CRL不能工作,并开始构建新的OCSP。

在OCSP的世界里,事情比CRL好一点。TLS客户端可以检查特定证书的状态,而无需从证书颁发机构下载完整的撤销证书列表,换言之,每次客户端与新的下游微服务对话时,它都必须与相应的OCSP响应者通信以验证服务器(或服务)证书的状态 - 并且服务器必须对客户端证书执行相同的操作。这导致OCSP响应者身上产生了很大的流量。虽然客户依然可以缓存OCSP的决策,但这又会导致相同的陈旧数据问题。

使用OCSP Stapling,客户端不需要每次与下游微服务进行交互时都转到OCSP响应者。下游微服务将从相应的OCSP响应者处获得OCSP响应,并将响应附加到证书本身。由于OCSP响应由相应的证书颁发机构签署,客户端可以通过验证签名来接受它。这使事情变得更好,现在服务和OCSP响应者交互,而不是客户端。但在TLS相互认证模式中,与普通的OCSP相比,这并不会带来任何额外的好处。

使用OCSP must stapling,服务(下游微服务)为客户端(上游微服务)提供了一个保证,将OCSP响应附加到它在TLS握手期间接收到的服务证书。如果OCSP响应未附加到证书,则客户端必须立即拒绝该连接。

短生命周期证书

从最终用户的角度来看,短期证书的行为与普通证书的工作方式相同,区别是短期证书的到期时间很短,TLS客户端不需要对短期证书进行CRL或OCSP验证,而是检查证书本身签署的到期时间。

Netflix和短生命周期证书

短期证书面临的挑战主要在于其部署和维护,自动化是解决之道!Netflix建议使用分层方法构建短期证书部署,您将拥有驻留在TPM(可信平台模块)或SGX(软件防护扩展)上的系统标识或长期凭据,并且SGX具有很多安全性,然后使用该凭据获取短期证书,然后为您的微服务提供短期证书,该证书将被另一个微服务使用。每个微服务都可以使用其长期凭据定期刷新短期证书。拥有短期证书并不够 - 托管服务(或TLS终结器)的底层平台应该支持动态更新服务器证书。许多 TLS 终端都支持动态重载服务器证书,但大多数情况下不能保证零停机。

边缘安全

将一组微型服务展示给世界其他地方的常见模式是通过API网关模式。使用API​​网关模式 - 需要暴露在外的微服务将在API网关中具有相应的API。并非所有的微服务都需要从API网关中暴露出来。

最终用户对微服务的访问(通过API)应在边缘或API网关处进行验证,保证API的最常见模式是OAuth 2.0。

OAuth 2.0

OAuth 2.0是访问委派的框架,它允许某人代表别人做某件事。OAuth 2.0引入了多种授权类型。OAuth 2.0中的授权类型解释协议,对象(客户端)应该只能访问资源所有者同意代表他/她访问的资源。此外,还有一些授权类型,它们只是代表自己(client_credentials)解释获取令牌的协议 - 换句话说,客户端也是资源所有者。下图解释了高层视觉下的OAuth 2.0协议,它描述了OAuth客户端,资源所有者,授权服务器和资源服务器之间的交互。

任何对象想要通过API网关访问微服务,必须先获得有效的OAuth令牌。系统以自身身份或者他人代表的身份访问微服务。对于后一种情况,例如,用户登录到Web应用程序,现在Web应用程序将代表登录的用户访问微服务。

让我们看看端到端的通信是如何工作的,如上图所示:

  • 用户通过身份提供者登录到网络应用程序/移动应用程序,网络应用程序/移动应用程序通过OpenID Connect(也可以是SAML 2.0)进行认证。
  • 网络应用获取OAuth 2.0 access_token和id_token。id_token将识别Web应用程序的最终用户。如果使用SAML 2.0,那么Web应用程序需要与其信任的OAuth授权服务器的令牌端点进行通话,并根据OAuth 2.0的SAML 2.0授权类型将SAML令牌交换到OAuth access_token。
  • Web应用程序调用一半的最终用户的API - 将access_token传递给API请求。
  • API网关拦截来自Web应用程序的请求,提取出access_token,与Token Exchange端点(或STS)通信,这将验证access_token,然后向API网关发出JWT(由其签名)。这个JWT也将携带用户上下文。当STS验证access_token时,它将通过introspection API 与相应的OAuth授权服务器通信。
  • API网关将通过JWT以及对下游微服务的请求。
  • 每个微服务将验证它接收的JWT,然后对于下游服务调用,它可以创建一个由它自己签名的新JWT,并将其与请求一起发送。另一种方法是使用嵌套的JWT - 新的JWT也将携带以前的JWT。

采用这种方法,只有来自外部客户端的API调用才会通过API网关。当一个微服务与另一个微服务对话时则不需要通过网关。此外,从给定的微服务角度来看,无论您是从外部客户端还是其他微服务获取请求,您获得的都是JWT - 因此这是一个对称安全模型。

访问控制

授权是一项业务功能,每个微服务都可以决定其操作授权的标准。在最简单的授权形式中,我们检查给定用户是否可以对特定资源执行给定操作。动作和资源的组合被称为许可。授权检查评估给定用户是否具有访问给定资源所需的最小权限集合。资源可以定义谁可以执行,对其执行哪些操作。给定资源所需权限的声明可以通过多种方式完成。

XACML(可扩展访问控制标记语言)

XACML是细粒度访问控制的事实标准。它引入了一种方法来以基于XML的领域特定语言(DSL)中的细粒度方式来表示访问资源所需的一组权限。

上图显示了XACML组件的体系结构。策略管理员首先需要通过PAP(策略管理点)定义XACML策略,这些策略将存储在策略存储中。为了检查给定实体是否有权访问给定资源,PEP(策略执行点)必须拦截访问请求,创建一个XACML请求并将其发送到XACML PDP(策略决策点)。XACML请求可以携带任何有助于PDP决策过程的属性,例如,它可以包括主题标识符,资源标识符和给定主体将在资源上执行的动作。需要授权用户的微服务必须通过从JWT中提取相关属性并与PDP通信来构建XACML请求。PIP(策略信息点)在PDP发现在XACML请求中缺少策略评估所需的某些属性时出现,然后,PDP将与PIP进行交互以找到相应的缺失属性。PIP可以连接到相关数据存储查找属性,然后将这些属性提供给PDP。

嵌入式PDP

远程PDP模型存在一些缺陷,可能很容易违反基本的微服务原则:

  • 性能成本:每次需要进行访问控制检查时,相应的微服务必须通过网络与PDP进行通信。通过在客户端进行决策缓存,可以减少运输成本和政策评估成本,但通过缓存,我们就会基于陈旧数据做出安全决策。
  • 策略信息点(PIP)的所有权:每个微服务都应拥有其PIP的所有权,这些PIP知道从哪里引入进行访问控制所需的数据。通过上述方法,我们正在构建一个“单片”PDP,其中包含所有PIPs - 与所有微服务相对应。

如上图所示,嵌入式PDP将遵循事件模型,其中每个微服务将订阅其感兴趣的主题以从PAP获取适当的访问控制策略 - 然后更新嵌入式PDP。微服务团队可以拥有PAP,或者可以是全球多租户模式的PAP。当新策略可用或有策略更新时,PAP将向相应主题发布事件。

这种方法也不会违反微服务中的'不可变服务器 '概念。不可变的服务器的含义是 - 在持续交付流程结束时,直接从服务器加载的配置中构建服务器或容器,并且应该能够使用相同的配置一次又一次构建相同的容器。所以,我们不希望任何人登录到服务器并在那里做任何配置更改。使用嵌入式PDP模型,尽管服务器在运行时加载了相应的策略,但如果我们启动一个新的容器,它也会获得相同的策略集。

在本文结束之前,还有一个重要的问题需要回答,API网关在授权环境下的作用是什么,我们可以拥有全球可访问的访问控制策略 - 适用于最终用户,在网关上实施 - 而不是服务级策略,服务级策略必须在服务级别执行。

本文的版权归 用户1196457 所有,如需转载请联系作者。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏FreeBuf

利用HTC One漏洞破解手机PIN密码

HTC One手机运行的是Android 4.2.2、HBOOT 1.54.0000,它存在一个名为Bootloader的漏洞。这个漏洞早在2014年2月份就报...

2815
来自专栏云瓣

关于 Node.js 的认证方面的教程(很可能)是有误的

原文地址:Your Node.js authentication tutorial is (probably) wrong 我搜索了大量关于 Node.js/E...

3389
来自专栏FreeBuf

CANard工具套件:CAN总线安全工具

CAN是控制器区域网络(Controller Area Network, CAN)的简称,是国际上应用最广泛的现场总线之一。在北美和西欧,CAN总线协议已经成为...

35310
来自专栏FreeBuf

工具推荐: 汽车CAN总线分析框架CANToolz

aka YACHT (又一个汽车黑客工具) ? CANToolz 是一个分析控制局域网络CAN(Controller Area Network) 和设备的框架。...

2727
来自专栏企鹅号快讯

CCERT月报:物联网安全需从网络层加强控制

2017年12月教育网运行正常,未发现影响严重的安全事件。近期一个存在于TLS加密协议中的漏洞被披露,漏洞是因为TLS协议在使用RSA算法协商加密密钥的过程中存...

2315
来自专栏安恒信息

安全漏洞公告

多个IBM产品存在未明SQL注入漏洞 多个IBM产品存在未明SQL注入漏洞发布时间:2014-01-13漏洞编号:BUGTRAQ ID:64749 CVE ID...

30410
来自专栏owent

整理一波软件源镜像同步工具+DevOps工具

上个月,同学的公司,格奕,突然间跪了。这个月基本属于休息+四处溜达。同时空闲的时候也想整理下之前做得一些之前的做得一些小工具们。在不泄密的情况下开源出来吧(其实...

1152
来自专栏FreeBuf

钓鱼邮件攻击中的猥琐技巧与策略

引言 钓鱼邮件攻击是社会工程学攻击中的一种常见的手段,其目的是欺骗受害人来进行一些操作,最终控制受害人。一般来说,钓鱼邮件从后续的攻击手段来说,可以分为两类: ...

2926
来自专栏菜鸟程序员

色情网站的光棍节“福利”:加密式挂马玩转流氓推广

3372
来自专栏Java后端技术栈

Nexus高级配置之添加jboss代理资源库

1、Hosted Repository - nexus本机的资源库(相当于nexus所在服务器硬盘上已经存在的jar、pom文件库);

792

扫码关注云+社区

领取腾讯云代金券