【交易技术前沿】基于 Spring Cloud Gateway 的新型业务网关设计与实现

本文选自《交易技术前沿》总第四十一期文章(2020年12月)

陈波、陈明辉/上交所技术有限责任公司

摘要

随着微服务技术在交易所基础技术架构中的不断发展,越来越多的通用功能不断独立成微服务部署。对于大部分内部应用,都有接入部分通用功能的需求,如登录、鉴权验证、负载均衡、限流监控、缓存等。若每个服务独立编写相关代码,显然会增加工作量且并不稳定。当相关依赖服务升级时,所有服务必须同步升级,而各服务的接入方式存在一定差异,且升级方案互不统一,导致升级成本相对较高。网关的出现恰好解决了这些问题,通用功能可在网关实现,减少各个服务的冗余代码,同时可对部署在网关背后的服务提供更好的安全保障。不同于客户端的网关服务对并发的要求,业务内网关将需要接入更多公司内部的统一需求,设计重点更偏向于基础功能的接入。

在经历了网络安全攻防演习行动后,我们发现很多服务接入的方式不统一,甚至部分老旧的系统没有接入新的基础服务,导致缺少登录控制、权限控制等相关的安全防护,因此在网关的设计上,我们增加了更多的安全控制功能,确保接入应用的访问安全。

关键字:微服务、网关、登录认证、网络安全

一、术语导读

本文涉及专业术语及简称如表1-1所示,后续使用到相关术语时会使用简称,特此说明。

表1-1 本文所涉及相关术语

二、 概述

随着软件系统架构的演变,微服务架构的使用也越来越广泛,随之带来的是企业对软件系统集成对接与能力开放的需求。网关控制系统针对不同软件系统之间对接过程中带来的多样性、易变性、开发效率等问题,提供轻量级、高性能、易控制的运行环境。网关提供多种系统通用功能,例如接口权限认证、流量控制、登录认证、接口日志、接口缓存、监控告警等。网关本身使用微服务架构,每个微服务本身的轻量化和可扩展性使其能够满足不同业务场景提出的定制化需求,以可插拔式的方式运行业务定制插件。微服务架构同时能够满足不同业务场景的不同组网需求,组网环境下多个微服务的集群部署有利于提高性能。国内外目前对微服务架构的研究主要在将单体应用微服务化,通过逻辑上的分割来体现微服务带来的优势。国内外的网关系统都已有产品应用,国内阿里云率先推出网关产品,提供API托管服务,帮助用户开放部署在阿里云上的服务。国外目前比较成熟的微服务网关组件有Zuul和Gateway。

三、 技术选型

当前比较流行的API网关组件有OpenRestry、Kong、Nginx、Zuul、Gateway等,为了更加适应当前的技术架构,对于非Java语言开发的网关如OpenRestry、Kong、Nginx等将不在考虑之列。在微服务的生态中,Zuul和Gateway应用比较广泛。其中Zuul在早期的1.x版本有相当多的落地实践,截至到2020年11月23日,Zuul已经更新到了v2.2.0版本[1]。Zuul 2.x相比Zuul1.x基于NettyServer实现了异步IO接入请求,同时基于Netty Client实现了网关到后端业务服务API的请求,极大地提高了网关的性能,实现了更低延时、更高性能的网关服务。由于当时Zuul2一直未能面世,对于http2和Websocket的需求进展缓慢。Spring Cloud官方推出了gateway,它是基于WebFlux/Reactor编写的,支持http2和Websocket,与Spring Cloud生态完美兼容 [2] 。截至本文撰写时Zuul2已经发布到2.2.0。如果对于网关的转发效率,没有太大的需求,建议直接使用Zuul1.x,它的文档更加完善,实践案例更加丰富。Zuul2.x和Gateway都比较新,相关文档还在不断完善中。目前我们的网关初步规划的接入应用对转发效率上有一定要求,因此Zuul1.x不在考虑之列。下面将从几个方面对Zuul2.x和Gateway进行对比。

1. 兼容性

二者都可无缝对接Spring Cloud。 其中,Gateway采用了WebFlux框架,与传统的Spring-Web项目不兼容,若不熟悉,则改造上有一定难度。

2. 功能

功能对比如表3-1所示。 Zuul的很多功能都需要基于Filter实现,而Gateway则提供了许多官方的Filter,用户只需要去配置即可。 在实际的应用中,Gateway提供的Filter也许并不能完全实现需求,需要少量的改造,但是有官方实现作为基础,因此在功能维护上更好。 目前许多厂家也逐步从Zuul1.x迁移到了Gateway,网络上能够找到许多开源资料。

3. 性能

针对二者的性能比对,我们做了WRK和AB测试。WRK测试采用10个线程,200并发,持续30秒,比对结果见表3-2,其中Gateway每秒处理请求个数以及平均时延较Zuul有明显优势。AB测试采用200并发,50000个请求测试,比对结果见3-3,AB测试结果同样表明Gateway在性能方面较Zuul有明显优势。

表3-1 Gateway与Zuul功能对比

表3-2 Gateway与Zuul性能对比,WRK测试结果

表3-3 Gateway与Zuul性能对比,AB测试结果

综上,性能方面,Gateway比Zuul更优,考虑到我们需要在Gateway上完成一些自定义的功能,需要查询数据库,这本身会带来一些时延,Gateway的性能优势可以降低时延,是个不错的选择。考虑二次开发成本和性能,我们尝试在Gateway的兼容性上做进一步实践,熟悉了Webflux相关内容后,我们选择了Gateway作为基础骨架进行二次开发。

四、 Gateway概念和基础原理

图4-1 Gateway原理图

断言:JAVA8中的条件断言。网关中使用断言,来判断一个请求是否匹配,如判断请求头、请求参数是否符合某个条件。

路由:网关的基础组成部分。由路由ID、对应的网络资源、一组断言、一组过滤器组成。如果断言全部为真,则匹配该路由。

过滤器:Gateway Filter的实例。GatewayFilter是Gateway内部定义的一个过滤接口。你可以通过过滤器在网关转发的各个阶段进行介入,实现自己想要的功能。同时Gateway也支持相当多种类的过滤器功能配置。

Gateway的原理如图4-1所示[2]。客户端发起请求到Gateway,首先会经过Gateway Handler Mapping进行路由匹配,如果匹配成功则将其发送给Gateway Web Handler模块,匹配到路由后,按顺序执行路由中定义的一系列Filter的前置代码后到达代理服务模块,再通过定义的转发规则转发到目的服务。当请求返回后则是逆序执行Filter中实现的后置代码。

五、 架构设计与实现

我们抽取了几个试点项目(Permission、Galaxy、Luna)接入网关试点。用户中心采用公司内部UUMS系统,进行登录验证。服务关系如图4-2所示。其中所有服务均接入Eureka注册中心,其中Permission、Luna是前后端分离的Web项目,Galaxy是纯后端服务。我们开发了网关的客户端,Permission、Galaxy、Luna均接入了该客户端。网关服务端启动后会从Eureka初步同步相应的应用服务名并启动相关路由。

图4-2 服务关系

接入了网关客户端(Airport-Client)的程序,启动时会向网关的服务端(Airport)发送一些信息,如应用信息、接口信息、监控信息等。用户也可以在网关的配置页面对应用相应的信息、接口信息进行修改。对于非Eureka的服务,如Python小项目等,暂不支持使用客户端接入,但可以通过服务端的管理页面进行手工添加。一旦服务注册到Airport之后,在页面上配置一些转发路由,就可以通过网关对外提供接口服务。

除了基础的路由转发功能,基于Gateway做了二次开发的Airport网关提供了许多统一的业务功能如请求合法性校验、接口权限验证、登录验证、缓存、审计日志、服务监控、XSS防护、IP黑白名单等功能。全局功能流程如图4-3所示。

图4-3 全局功能流程

a) 登录认证

登录认证接入了UUMS系统提供登录认证服务。为了提供统一的登录认证,我们对原有的接入流程进行了改造。新的接入流程如下:

  1. Web服务的前端页面发起请求经过Nginx代理到网关。

  2. 网关对请求进行合法性校验,如不通过 接拦截告知非法请求。 通过则执行步骤3。

  3. 通过请求获取session和redis缓存中的session缓存存判断用户是否登录。 如果未登录则拼接登录跳转地址返回给前端,其结构示例如下:

该链接遵守UUMS跳转规范。

4. 前端对返回做拦截,对于status为30200的返回,跳转到data所指定的地 址。 status为其他值时表示已通过登录认证,跳转步骤6。

5. 进入跳转地址后,用户在UUMS的登录页面输入账号密码进行登录,验证通过后,UUMS服务端会请求已经配置到其系统内部的登录接口(该接口由Airport服务端统一实现),并附带token。

6. Airport接到login接口的请求后,使用该token向UUMS反查用户信息,并将用户信息存入session同时写入redis session缓存。

7. 结束。

该流程对于接入网关的应用的后端不需要实现相关登录流程,前端对response做相应的拦截修改即可。Airport转发时会附带session信息,接入服务端可在请求的session中获取相关用户信息。

b) 接口鉴权:

任何接入到网关的应用,都需要先在网关的管理页面上申请接入密钥。Airport基于该密钥做权限认证。为了提高安全性,在申请密钥的时候提供了多种加密方法的选择如md5、sha256、md5hex、sha256hex、sha1hex,同时在生成签名时密钥拼接默认后缀如(abcdefg)。此外对于任意请求,Airport都会做XSS拦截和IP甄别。

表4-1 接口认证发送方需要发送的相关字段

请求方需要传递的请求头部参数如表4-1所示。注意不论是源应用还是目的应用,都是已经注册在Airport之上的应用。签名计算方法(如选择md5作为加密方法,申请的密钥为f35ade77-4a22-40f5-a61d-efd5011e0f46默认加密后缀abcdefg)DigsetUtils.md5(luna+galaxy+1606125050+f35ade77-4a22-40f5-a61d-efd5011e0f46+abcedefg)。Airport收到请求后取出相关头部参数,先判断时间戳是否过期(如限定距当前时间5分钟内有效),根据在Airport申请密钥时选取的加密方法进行同样的计算再进行签名比对。

c) 缓存:

由于缓存的更新需要接入方根据对应的业务逻辑进行更新,Airport仅提供了简单场景的缓存配置功能。比如对于数据延时不敏感,但查询压力较大的场景,可以选择在Airport中开启缓存。对于复杂的缓存场景,如需要保持缓存一致性,请在接入方实现。

d) 日志:

Gateway的response和post请求的body都是流式的,不可重复读取,因此定义了一个全局的过滤器,复制请求体和返回内容。需要注意的是,有些服务端开启了压缩选项,需要先解压才能记录可读的返回内容。目前仅支持gzip压缩方式。由于集中存储了很多系统的接口日志,后端数据库存储采用了MySQL+ELK,其中MySQL仅保留7天日志,ELK存储全量日志。

六、 安全防护

网络安全、信息安全问题一直备受国家和企业重视。随着2020网络安全攻防演习行动的推进,交易所组织了大量的漏洞扫描工作,我们逐步在应用层也增加了许多防护措施。其中一些和应用层服务比较贴近的攻击手法,如XSS、恶意伪造请求等,比较适合在网关层进行防护。Airport目前已实现了XSS攻击防护与IP黑白名单防护。

跨站脚本攻击(Cross Site Scripting)是指攻击者利用网站程序对用户输入过滤不足,输入可以显示在页面上对其他用户造成影响的HTML代码,从而盗取用户资料、利用用户身份进行某种动作或者对访问者进行病毒侵害的一种攻击方式。为与层叠样式表(Cascading Style Sheets)的缩写CSS区分开,跨站脚本攻击通常简写为XSS [4]

目前比较流行的前端框架,如Vue、React、Angular在底层都做了XSS防护。不过还是有一些途径可进行XSS攻击,如React中使用dangerouslySetInnerHTML,Vue中使用v-html都有攻击风险 [6] 。一般主流做法是对这些带有攻击性质的字符串进行转义。但有一些场景转义存储,会带来一些新的问题。如本身就是要向后端传递编写的脚本,如果进行转换后端存储将和实际想要存储的数据不一致。目前我们考察了需要接入网关的服务,不存在带有XSS攻击性质的参数传递,因此暂时先做了统一拦截,对于带有攻击性质参数的请求,会被拦截。这样做也仅仅是在请求到达后端前做了一层拦截,在后续请求返回后风险依旧存在。总之,关于XSS防护,是前端和后端一起配合的工作。在网关层,付出多少代价,取得多大效果还需要结合后续实际应用进行验证和改进。

关于IP防护,目前服务基本部署在内网,防护的场景是假设内网被攻入,还有一层拦截能力;或者部分客户端需要临时屏蔽,如某些接入的应用发生故障大量对其他服务发起请求,导致下游服务承载不了,此时可以先屏蔽到异常客户端的所有请求,保障下游服务能正常提供服务。 

Airport可配置黑白名单,其中白名单具有绝对权威,当其中网段与黑名单中有冲突时,优先放行。这取决于对待IP拦截的原则是优先提供服务,还是优先保障安全牺牲用户。对于内部网关来说,显然前者更符合设计。

七、 应用监控

微服务监控有很多解决方案,Airport基于Actuator实现了轻量级的监控。在Airport-Client中嵌入Actuator插件,定时采样相关监控指标如内存使用量、CPU使用率、GC耗时、线程数量、JVM相关指标、请求数量等上报到Airport服务端,由服务端写入ES集群。Airport提供对这些监控数据的可视化展示如图7-1所示。

图7-1 Airport监控指标示例

八、 结语

本项目基于Gateway实现了许多基本功能,简化了后续应用的开发,提高了开发效率。同时通用功能的变更和迭代,只需要在Airport中进行修改即可,提高了版本更新效率。

Airport还提供了可视化监控服务,填补了目前没有服务指标监控的空白。后续会对相应指标提供告警功能,帮助用户更早的发现服务异常,减少事件产生。

在安全防护上,Airport也提供了基础的XSS防护和IP拦截,后续会针对不同的攻击手法增加必要的安全防护。

参考文献

[1]https://github.com/Netflix/zuul/wiki

[2]https://docs.spring.io/spring-cloud-gateway/docs/3.0.0-M3/reference/html/

[3]廖俊杰, 陶智勇. 微服务API网关的设计及应用[J]. 自动化技术与应用, 2019(8).

[4]刘海,徐芳,郭帆防范XSS 攻击的研究综述

[5] 李涛. 网络安全概论[M]. 电子工业出版社, 2004.

[6]牟森, 梁宵, 刘茜,等. 一种用于防范React前端框架的跨站脚本攻击XSS的方法及系统:, 2019.

免责声明

本公众号内容仅供参考。对任何因直接或间接使用本公众号内容而造成的损失,包括但不限于因有关内容不准确、不完整而导致的损失,本公众号不承担任何法律责任。如有问题请反馈至tech_support@sse.com.cn。

————————–

上海证券交易所为证券公司、基金管理公司等市场参与者及相关行业机构提供交易技术支持与服务,包括日常交易技术支持、技术交流研讨、市场调查反馈、证券信息技术知识库、测试等服务。

上交所技术服务
我还没有学会写个人说明!
上一篇

重大更新!一文了解京东通用目标重识别开源库FastReID V1.0

下一篇

SpringBoot + Security学习笔记

你也可能喜欢

评论已经被关闭。

插入图片