微服务框架的安全管控机制的设计
2018-12-26潘孝阳黄晓芳
潘孝阳 黄晓芳
(西南科技大学计算机科学与技术学院 四川绵阳 621010)
近年来,随着软件的不断发展,软件市场对软件的开发技术有着越来越高的诉求,不断提升的用户量和业务依赖复杂度都对软件开发技术提出许多挑战。因此,软件开发技术以高性能、易扩展为核心设计理念,从单一架构到分布式架构的逐步转型。微服务的特性正符合了我们所期望的目标,所以被大多数的开发者所看好,也说明了微服务框架是软件开发的必然选择。
普遍认为2014年Fowler与Lewis首次提出了微服务的概念[1],但当时并没给出精准的定义,只是将微服务描述为:微服务就是将单个应用程序拆分成多个小的服务的集群,每个微服务都围绕具体业务进行实现,相互之间通过轻量级通信机制,有着极少的统一管理。每个微服务可以独立部署,使用不同的编程语言,使用不同的数据存储技术[1-2]。反观SOA框架,它对某些技术栈的依赖性较高,从而使得切换时间长,花费成本高,让决策者望而生畏。由此也可以看出,虽然同样是以服务模块化为目标,微服务架构与SOA架构有着很大的差别。
微服务框架在很大程度上优化了现有的软件开发流程,主要表现在:细化的服务模块相互独立,使得各部分逻辑更为清晰简洁;某一部分的改动可以单独发布,对整体的影响也相对较小;服务间相互技术隔离,也使得开发工具的选择更加灵活;各模块独自成为一个项目,可以对不同的业务部分进行需求性能调优。但是,微服务并不是一个完美的解决方案:分散的服务模块需要更庞大的运维团队,提升了服务监控和日志审计难度;分布式的数据同步和跨平台检索等技术问题同样也带入了微服务框架中;进程中的接口调用变成了服务间的接口调用,提高了调用的改动成本和性能成本;多个服务相互依赖,使得测试更加困难;微服务模块之间无条件相互信任,为攻击者提供了很多可乘之机。所以,本文将在分析微服务框架的安全性问题后,提出一些针对性的解决方案。
1 微服务框架脆弱性分析
微服务的分布式架构解决了一些目前SaaS业务的复杂性问题,但同时也引入以下安全隐患:
(1)分布式的框架设计暴露了更大的可攻击面[3]。在整体架构中,接口与接口之间的调用是进程中的调用,难以被外部介入,但在分布式的微服务框架中,各个模块被细化成为了单独的项目,相互间接口的调用和数据的传递都必须通过轻量级的通信机制实现,因此,微服务之间的通信内容就直接暴露了出来,特别是在现在比较常用的第三方云环境中部署时,不同节点上的微服务之间的通信也就直接通过网络进行传输了,攻击者便可以通过针对网络通信的攻击手段对系统数据进行篡改。
(2)各个微服务相互信任,整个应用更容易受个别已被攻陷的服务的影响[4]。各个微服务之间相互协作以完成一个复杂的业务逻辑,服务与服务之间相互信任对其他模块的数据和请求没有做较为完善的数据校验,在这种情况下,一旦某个微服务被攻击者攻陷,攻击者便可以利用这种信任关系对整个系统进行数据获取或者篡改。
2 微服务框架的安全管控解决方案设计
微服务的设计核心之一是业务去中心化,但对于微服务模块集群的管理工作则需要采用中心化的管理手段,强化微服务框架中的安全策略。因此,笔者案设计权限中心微服务,在认证每个微服务的同时对系统内部框架访问进行权限控制,保障安全的访问。
当单个的系统被拆分成为了多个服务模块后,服务与服务之间的权限控制和信任关系便成为了安全控制的关键点。对微服务集群提供身份认证机制可以提高微服务的可信度,而以最小化权限思想来考虑微服务的访问权限,可以在很大程度上降低微服务集群被单点突破的不良影响。因此,本文考虑使用挑战应答的模式对微服务进行认证,同时在微服务框架中应用权限控制模型来控制微服务的可访问范围,进而降低微服务会受到系统中的其他被攻陷微服务的影响的可能性。
2.1 挑战应答式心跳机制
通常微服务框架中需要一个注册发现机制,一般分为客户端的注册发现和服务端的注册发现,以实现对分散的微服务的统一识别。在服务端的注册发现机制中,注册服务器利用客户端发送的心跳包实时监控微服务的存活状态。权限中心微服务的设计参考了这种客户端与服务端的联系方式,使用不间断的挑战应答来实现对微服务存活检测的同时,完成对微服务的身份认证。
挑战应答是一种异步令牌的动态口令技术,其中没有需要进行同步的要素,不受客户端和服务器的时间差异等问题的影响[5]。在挑战应答的一般实现中,通常由客户端发起挑战请求,然后服务端生成挑战码,客户端对挑战码进行运算然后响应给服务器,由服务器来识别客户端的合法性。然而,客户端服务器双方一般使用的加密杂凑算法,其运算结果会直接放在请求消息中,所以监听者只需要维护一个挑战码与响应的映射表,就可以简单地推测出相同的挑战码所对应的响应,冒充正常客户端进行攻击。
刘彤等[6]提到了一种添加了时间戳进行对称加密的双向认证挑战应答方法,使得某一个挑战码在不同的时间戳下会得到不同的响应,增加了加密的混淆程度,减少了挑战响应被仿冒的可能性,并实现了客户端与服务器的双向认证。在微服务框架中,由于挑战应答需要在客户端和服务器之间不间断地进行发送,所以这种混淆程度较高的挑战应答机制比较适用。另外,文献[7-8]中提到HMAC算法是一种安全度较高的加密杂凑算法,其普遍应用于挑战/应答机制中。
在图1中,本文拟采用HMAC算法替换刘彤等的挑战应答方案中的分组加密算法[6],以进一步提高认证结果的可靠性。挑战应答协议的主要内容除了包含客户端与服务端的3次握手之外,还必须对客户端和服务器双方的密钥共享方式进行设计。本方案拟采用提前配置的方式来确定客户端与服务器双方的密钥,即双方的密钥会在创建之初生成并添加到双方的配置文件中,来达到密钥共享的目的。
图1 微服务中的挑战应答Fig.1 Challenge response in microservice
在图1中,由于这里的挑战应答兼顾了心跳检测的机制,所以其间隔时间不宜过长,以保证检测的时效性,由于需要进行较为复杂的3次交互,所以其间隔时间也不宜过短,以避免占用过多通信资源。这里将间隔时间设置为5 min,既在一定程度上保证了状态识别和认证识别的时效性,也不会占用过多的带宽和计算资源。在挑战应答完成之后,由权限中心服务器为认证成功的微服务颁发一个唯一识别的令牌,来标识这个微服务。该令牌也会随每次挑战应答而变化。
由于微服务框架本身有具备心跳检测的模块,这里将方案中提到的心跳机制与微服务框架自己的心跳检测一起使用。当所有微服务实例都没有在指定的时间间隔内发起挑战请求时,则权限中心向注册发现中心发送微服务已全部停止的消息,修改微服务的注册状态为“DOWN”。
2.2 适用于微服务间通信的基于角色的权限控制
在传统的RBAC模型中,为表达用户与访问权限的关联关系,抽象出了几大模块来对其进行描述,主要包括用户、角色、会话和权限,权限一般又以操作和控制对象来表达[9-13]。而在微服务框架中,每个业务微服务实例被视为用户对象,每个业务微服务模块可以被定义为一种角色,对于微服务的权限使用“httpMethod+服务名”的格式来表达,传统的基于角色的权限控制模型在微服务环境下即为基于微服务的权限配置。在应用于微服务的权限配置模型中,多个微服务实例注册为相同的微服务模块,实现微服务实例与微服务功能模块的对应关系;同时,设计权限中心微服务来维护微服务模块与权限集的关联关系,实现微服务权限的灵活可定制。传统的RBAC模型和本文设计的微服务框架中的权限控制对比如图2所示。在RBAC模型应用到微服务框架中后,由于微服务实例所属的微服务是唯一不变的,所以删除了原模型中的会话模块,在判断微服务权限的时候不需要经由会话来激活对应所属的微服务。对于微服务权限的定义也是灵活可变的,操作可以粗略地分为“读与写”,也可以细分为“get,post,delete,put”;控制对象可以粗略地分为“服务级别”,也可以细分为“url级别”。通过调整不同的许可粒度,可以平衡管理复杂度和权限精准度之间主次关系。
图2 传统RBAC模型在微服务中的应用Fig.2 Application of RBAC model in microservice
权限的设置需要设计者针对大致的业务逻辑提前抽象出来,然后使微服务在每次发起访问时都必须符合预置的权限限制。假设在一个签名系统中有如下4个核心微服务模块:用户微服务,财务微服务,签名微服务,文件微服务。这4个微服务存在相互调用关系,根据相关的业务逻辑,他们相互之间的调用限制如表1所示。
表1 微服务调用限制表Table 1 Invoking restriction of microservice
在业务逻辑中,新用户在注册入系统时,会默认添加一定量的余额,因此用户微服务有对财务微服务的post(添加)请求;用户在进行充值操作时,会定位充值者提供的用户信息是否正确,确保充值正常进行;同理,签名微服务和文件微服务会检查签名和文件上传时的用户信息,所以都对用户微服务有get(获取)权限;在签名流程中,必须检查该用户的余额足够,然后进行扣费操作,所以签名微服务对财务微服务有get(查询)和put(修改)的权限,签名微服务获取需要签名的文件对象,并将签名完成的文件重新上传到系统中,所以签名微服务对文件微服务有get(查询)权限和post(提交)权限。鉴于权限判定增加了接口的响应时间,所以推荐在权限判定器的逻辑中直接跳过来自api网关的访问请求,所以这里所有微服务不对来自网关的请求进行限制。
为处理这些权限控制,这些权限关系会预先持久化到权限中心微服务中,并在每个微服务中设计权限判定器。由于注册发现中心只存储了微服务模块与其提供服务的IP和端口关联,所以通过IP和端口信息只能识别出请求中的目的地的微服务模块。为标识出请求来源的微服务模块,在微服务发起请求时要求使用第2.1节中提到的令牌来表明请求者身份,同时提供对令牌和部分请求消息计算的摘要值。当一个微服务收到请求时,消息会进入权限判定器进行处理,首先会校验摘要是否一致,保证消息的完整性没有被破坏,然后提交当前请求的“源ip+httpMethod+源令牌”到权限中心进行权限检查,如果权限正确则流程继续,如果权限不正确,则阻止当前访问。
3 方案分析
通过前期研究,本文提出了微服务的脆弱性之一是微服务间的访问缺乏身份认证和安全性控制机制,这样很容易被恶意攻击者利用,并通过单点突破实现全网扩散,导致整个微服务集群系统的不安全。因此,本文提出应用于微服务框架的微服务身份认证机制和访问控制机制,以权限中心微服务为基础建立微服务之间的信任关系。
3.1 防止重放攻击
在本文设计的挑战应答机制中,每次通信都会加入随机数和时间戳,并用HMAC对时间戳消息进行了完整性保护。每个随机数和时间戳数据对只会使用一次,使用后立刻失效,当攻击者截获数据包进行重放时,接收方会检查时间戳和随机数,防止攻击者重放数据包[14]。同时,每5 min一次令牌更新,也能够有效降低令牌被截取带来的不良影响。
3.2 通信消息完整性保护
在本文设计的通信协议中,每次通信都会将通信消息进行hash值的保护,使用MD5杂凑算法计算通信消息的hash值时,加入部分通信信息和令牌数据,提高了摘要的混淆程度, 防止攻击者对通信消息的篡改,保障协议过程中消息的完整性。
3.3 微服务间的隐蔽信道及安全性分析
各个业务微服务实例需要和权限微服务进行通信,在本系统架构中,采用改进的挑战应答机制建立身份信任关系,防止非法访问。微服务之间的消息通信通过令牌机制证明身份的可信,并采用权限控制系统对微服务实例在系统内的访问进行控制,防止攻击者的跳板攻击,并且,微服务的访问请求只能通过网关进行路由然后响应结果,请求信息不能以任何形式直接发送到某个微服务的接口上,因此,保证了微服务模块的接口不被暴露出来。除此之外,在权限判断过程中,选择了源ip和源令牌的组合身份鉴定,避免了令牌被盗用之后被滥用的情况,提高了令牌的可信度。
4 结束语
针对微服务中微服务间的访问缺乏身份认证和安全性控制机制的这一安全性问题,提出了将挑战应答和访问控制模型应用到微服务框架中的方案。在保证方案本身安全性的情况下,实现了对微服务的身份认证和访问控制,对通信中可能存在的重放攻击和消息篡改进行防护,阻止微服务集群的单点攻击对系统的影响进行扩散,提高了微服务框架的安全性。除了本文中提到的安全性问题,其拆分之后的效率问题也是亟待解决的内容,因此,如何平衡框架的安全性和效率,还需要进行进一步的研究。