一、Keystone Token深度概述 
Keystone作为OpenStack项目基础认证模块,目前支持的token类型分别是uuid、pkiz、pki、fernet。 
首先,简要叙述一下这四种类型的原理及其优缺点。 
uuid 比较简单,采用随机生成的序列(128位,以16进制表示)作为id,并构造token内容,需要持久化后端数据库支撑,比如MySQL数据库存储。优点,实现简单;缺点是持久化查询、每次访问都需要keystone相关服务进行认证。 
pki(pkiz) 基于cms算法,token格式以PKIZ_开头,pki类的token 长度很长(pkiz只是对pki进行了一定程度的压缩),它将所有token的内容都放在了token中,并且认证不需要与keystone服务交互,直接采用相关的证书进行本地认证,这类似与传统的U盾技术,但是密钥是在keystone处生成好了之后,是不能够进行实时更新的,安全性相对较低,一旦被破解,相关的信息将被暴露,此时,如果对密钥进行更新,将导致前面生成的token不可用。它的缺陷在于,没有密钥的周期性更替机制(安全性大打折扣),同时,负载太大,部分rest接口,不能处理超长请求。在生产环境中,极不推荐这种方式。 
fernet 是当前主流推荐的token格式,这种方式相较于前几种类型,是当前比较均衡的一种方式。它不需要后端持久化存储,与pki类似,但是在认证上,仍然需要与keystone进行交互。它的token结构,采用了特定的数理结构设计(包括socoped类型、user信息等等),结合加密技术,重要的优点是它的轮询替换算法。简要叙述一下fernet密钥的原理,默认的轮换长度是3,当以keystone-manage fernet-setup生成密钥时,会看到0、1两个索引表征,这分别是什么意思呢?在此,需要提一下三个概念,primary key(主密钥,用于加密、解密token)、secondary key(次次密钥,用于解密token)、staged key(次密钥,用于解密token),那么上述0 表示的是staged key,1 表示的是primary key,primary key相比较另外两种key,它的索引最高,并且可以加密、也可以解密;staged key 相较于secondary key是它更有机会变为primary key。也就是说,fernet的密钥不是不变的,并且可以周期性轮转,不同认证节点之间的更新频次可以相差1。这安全性大大提高,keystone 进行认证的时候,依赖于这些密钥进行解密,从而进一步实现认证。 
在分析了上述四种token格式后,毋庸置疑,fernet是比较靠谱,且性能相对较优的格式。但是,如果仅从这些分析上,不足以保证fernet的优势,说服力还不够。下面两节,将分别从认证原理、及历史经验数据上做探究分析。fernet是当前比较合适的方式,这并不表示fernet就是最优的token方式。在后面的分析上,尽可能提出更优的方案。 
二、openstack认证 
Openstack项目的认证技术,除了与keystone认证服务相关,也离不开众多的中间件的处理,如典型的keystone/middleware。首先,任何的服务在使用之前都需要获取token,token的生成,按照各种token的格式,uuid是存储在持久化后端数据库中,其他方式采用加密技术,token ID中包含了token数据的信息。有了token后,所有服务在发送请求时,需要将token ID作为请求字段,否则,直接抛出异常。而token ID的认证,主要依赖于中间件组件的处理。在下一小节中,重点说明。 
在介绍认证原理之前,必须明确几个概念,cache、revoke、service-token、user-token、expiration,其中cache就是缓存,在keystone中常用的缓存工具是memcache,它在内存中开辟一块空间,用于存放token,优点不用多说,会大大缩短获取token的时间,并且验证时间也缩短了;revoke是回收机制,keystone中的token过期回收机制,会根据token的过期时间作响应或者人为主动发出的token回收请求;service-token在请求头中用X-Service-Token表示,是M版后,keystone认证所改进的技术,它主要是区分普通的用户的请求和服务请求,区分的原因是引入了过期token的使用,P版将会更加强化这一概念,并且过期token的使用,只发生在服务请求中;user-token就是普通用户的请求,在请求头中用X-Auth-Token表示;expiration,即过期时间,在keystone中有两处过期的概念:token的过期时间、cache的过期时间。简要叙述一下,cache的过期时间的设定,一般我们认为,cache存储的时间越久越好,但是cache的容量有限,并且,它占据着内存的空间,因此cache内存的大小实际存在一个理论上的“极值”设定,超过了这个大小,将会影响服务的响应处理,除了这一点,另外就是过期时间,考虑到过期token,即使存储在cache中,它也认证不通过,但是,如果cache中不存在的话,需要keystone服务去获取并且验证,这个开销比存储在cache中的开销要大。虽然如此,考虑一种高压情况,cache的存储,我们希望有效的token存储越多越好,过期的token,我们只存储一个index值,这样不会占据太多的空间,并且认证过程中,很快能够检测出过期token。在下一段的改进性能优化上,进一步说明。 
正式进入openstack认证原理的介绍。openstack的项目,依赖于keystone项目进行认证,借助于中间件的处理.Token包括两部分,分别是token ID、token Data,token Data是核心,包括用户的信息、角色信息、服务信息、服务入口等等。Openstack认证,首先去cache中,查询是否存在对应的Token,如果存在,则进一步验证token是否被回收。此流程很简单;如果cache中不存在的话,keystone服务会去获取token的信息,并调用对应的driver去验证token,不同格式的token处理上有些差异,pki(pkiz)直接本地认证即可;其它两种方式都需要和keystone服务交互。如果获取并认证通过了,则需要将token的信息加入到cache中,否则,认证不通过,返回结果。具体流程,如下图所示。

三、结合实际探究分析 
回顾历史经验数据,曾经做过一个压力测试,验证token的抗压能力,uuid、fernet、pkiz的模式,得出的结论是fernet相对结果较好。我们的测试用例是nova list,这个结果,现在来看的话,有着它的必然性。能想到的keystone认证的瓶颈,主要是token 过期时间、cache的大小、时长、服务的worker数、数据库的性能。 
fernet的数据性能最好,原因是它不需要后端持久化操作,并且token的认证,使用的是密钥进行解密,能够直接得出token Data的信息,从而进行token的过期认证,它的失败原因,只可能是token过期了,或者是token放到了cache中,但是已经被回收了。归根到底,还是token过期了。之前做的压测,设置的work数是8个,所以,当压力达到3千以上的时候,进程本身有一定的负载上限,因此在处理上,会出现多数的等待,我们看到获取token的那条命令,出错概率相对较低,原因是生成token的流程,没有后端数据库的操作,因此,比较流畅。有部分出错了,原因是由于请求等待时间过长,如果一直没有进程在处理,那么将会抛出获取token时的认证异常。其它出错,在认证时候的异常,原因是由于压力增多,导致一条请求的处理流程被拉长,token的过期时间也设置的较短,并且也存在请求长时间没有得到处理而抛出的认证异常。因此,当我们增加服务节点或者提高work数的时候,压力问题会得到有效的缓解。 
Pki系列的性能也不太好,原因就是token长度太长。虽然它采用的是自认证的方式,在请求传递过程中的负载,将会消耗很大的时间,并且采用cache的方式,会导致命中出现问题,因为cache有大小上限,因此,很容易出现之前已经存在于cache的token,会被替换出去,从而影响后续的认证流程。它的请求传递开销,是它致命的缺陷。抗压能力较弱(此处说的是只有一台服务器的情况下)。 
uuid的实现简单,但是抗压能力,是比较差的,因为它涉及大部分的持久化操作,数据库的性能直接影响压力测试的结果。常规情况下,我们不会单独再用一台数据库节点,因此,数据库性能不会很高,并且当数据库达到一定压力的时候,本身连接数据库就会变得很慢。 
在上述分析中,我们从历史数据得出的部分解答。从近期的调研分析来看,openstack的服务在使用之前都需要认证,认证如果变得很快,那么openstack整体的服务性能将大大提升。认证过程中,除了增加服务数的方法、提高服务进程数外,token的cache命中率,也是有效提高认证的方法之一。除此之外,可信认证的充分利用,比如将某些服务发送的请求,去掉部分认证的环节,尤其是过期token的引入。 
四、性能提升 
为了提升token的认证能力,假设我们的使用场景是抗压能力测试,没有其他操作干扰,还是以nova list作为测试用例,我们以rest接口作为测试方法,没有超时限制,fernet作为token的格式,并且将token的时长调大,理论上只要token过期时长足够大,成功率,应该是能够达到100%。如果针对这个测试用例,非要找出出错的可能性,只可能出现在token过期。当我们引入过期token可再使用时,那么成功率将更加有保障。 
在上述分析中,我们得出影响性能的几个关键因素:服务能力数(认证服务节点数量)、服务进程数(worker数量)、token的格式、cache的大小设置,cache策略。 
服务能力数,即设置多少台服务节点是合适的,这个问题,需要考虑实际部署的机器的性能,因此,我们只有通过测试,这个值的大小大致是可以确定的。我们可以通过rest请求的响应时间作为参考值,我们需要提前预估一下响应时间的最大时间,即用户能够接受的时长,这个也是分请求的,比如创建虚机的请求,它涉及多个流程,它的响应时长的设置,应该是每个子操作响应时长的总合,因此,我们只需要设计好原子操作的响应时长。当合理的原子请求不能在规定的时间内得到响应,说明服务器服务需要优化,资源需要增加。因此,rest请求的响应能力,是判定服务能力的重要的参考依据。我们可以通过压力测试,找到服务能力的数值。 
服务进程数,当服务器性能允许的情况下,这个数值越大,表示服务能力越强。但是,当进程太多,会拖慢机器的性能,这个值,在理论上也存在极值。一般情况下,我们开启32 或者64进程。具体的检测方法同上。也可以通过rest请求的压力测试得出。 
token的格式,从上述的几种token的逻辑处理上,毋庸置疑,fernet的优势非常明显。 
cache的大小设置,如果条件允许,并且token会被多次利用的概率较大,cache大小设置大一点。另外,在实际的生产环境中,获取了token后,95%的情况下,token会需要被验证,因此,token的改进措施,就是在生成了token后,就可以将token加入到cache中,这样在验证的时候,直接可以通过cache机制认证。这一点需要一定的cache大小空间的支撑,在下面的cache策略中再详述。 
cache策略,在当前keystone服务中,token认证通过了,会被加入到cache中。token过期或者达到缓存时长,将会从cache中移除。如果token被回收,存储在cache中token会被标记为Invalid Token。Keystone发展到O版,service-token引入,并且允许过期token的使用,在私有云环境下,尤其是内部使用的项目,在cache策略上,service-token认证的流程,应该可以简化,甚至注释掉。但是,前面的策略只是某些个列情况下,当前比较优化的方案是,当token生成了后,直接将token放入cache中,在正常的业务流程中,该token会被用来发送请求。这样的话,在压力负载较大的情况下,优势会比较明显。 
以上仅是个人的观点,如有问题,请及时与我探讨分析。

keystone 认证深度研究分析的更多相关文章

  1. Django drf:序列化增删改查、局部与全局钩子源码流程、认证源码分析、执行流程

    一.序列化类的增.删.改.查 用drf的序列化组件   -定义一个类继承class BookSerializer(serializers.Serializer):   -写字段,如果不指定source ...

  2. opencv的实用研究--分析轮廓并寻找边界点

    opencv的实用研究--分析轮廓并寻找边界点 ​      轮廓是图像处理中非常常见的.对现实中的图像进行采样.色彩变化.灰度变化之后,能够处理得到的是“轮廓”.它直接地反应你了需要分析对象的边界特 ...

  3. SQL中的Null深入研究分析

    SQL中的Null深入研究分析 虽然熟练掌握SQL的人对于Null不会有什么疑问,但总结得很全的文章还是很难找,看到一篇英文版的, 感觉还不错. Tony Hoare 在1965年发明了 null 引 ...

  4. TCP异常关闭研究分析

    版权声明:本文由谢代斌原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/108 来源:腾云阁 https://www.qclo ...

  5. OAuth认证协议原理分析及同步消息到Twitter和Facebook使用方法

    OAuth有什么用?为什么要使用OAuth? twitter或豆瓣用户一定会发现,有时候,在别的网站,点登录后转到 twitter登录,之后转回原网站,你会发现你已经登录此网站了,这种网站就是这个效果 ...

  6. Linux下基于LDAP统一用户认证的研究

    Linux下基于LDAP统一用户认证的研究                   本文出自 "李晨光原创技术博客" 博客,谢绝转载!

  7. 深度研究:回归模型评价指标R2_score

    回归模型的性能的评价指标主要有:RMSE(平方根误差).MAE(平均绝对误差).MSE(平均平方误差).R2_score.但是当量纲不同时,RMSE.MAE.MSE难以衡量模型效果好坏.这就需要用到R ...

  8. Dotnet Core IHttpClientFactory深度研究

    今天,我们深度研究一下IHttpClientFactory.   一.前言 最早,我们是在Dotnet Framework中接触到HttpClient. HttpClient给我们提供了与HTTP交互 ...

  9. Django(64)频率认证源码分析与自定义频率认证

    前言 有时候我们发送手机验证码,会发现1分钟只能发送1次,这是做了频率限制,限制的时间次数,都由开发者自己决定 频率认证源码分析 def check_throttles(self, request): ...

随机推荐

  1. HDU 1846 Brave Game 巴什博奕

    解题报告:Alice和Bob在做一个取石子游戏,有一堆n个石子,然后规定每个人每次最少要去1个石子,最多可以取m个石子,最后一次取完石子的人为胜. 巴什博奕,关键是找到必胜点和必败点,我们可以先列举出 ...

  2. STL-map and multimap

    定义 map<int,int> a; map<int,string> a; map<double,int> a; …… 首先要知道的一些 Map是STL的一个关联容 ...

  3. 【微服务架构】SpringCloud之Ribbon

    一:Ribbon是什么? Ribbon是Netfix发布的开源项目,主要负责客户端的软件负载均衡算法,将Netfix的中间层连接在一起,Ribbon客户端组件提供一系列完善的配置项如连接超时,重试等. ...

  4. STL容器基本功能与分类

    STL有7中容器. 分别为: vector 向量 <vector>(头文件) 随机访问容器.顺序容器 deque 双端队列 <deque> 随机访问容器.顺序容器 list   ...

  5. java 判断上传文件大小

    /** * 判断文件大小 * * @param file * 文件 * @param size * 限制大小 * @param unit * 限制单位(B,K,M,G) * @return */ pu ...

  6. 33 Introducing the Go Race Detector

    Introducing the Go Race Detector 26 June 2013 Introduction Race conditions are among the most insidi ...

  7. vue总结07 常用插件

    插件 开发插件 插件通常会为 Vue 添加全局功能.插件的范围没有限制——一般有下面几种: 添加全局方法或者属性,如: vue-custom-element 添加全局资源:指令/过滤器/过渡等,如 v ...

  8. 浅谈js设计模式之策略模式

    策略模式有着广泛的应用.本节我们就以年终奖的计算为例进行介绍. 很多公司的年终奖是根据员工的工资基数和年底绩效情况来发放的.例如,绩效为 S的人年终奖有 4倍工资,绩效为 A的人年终奖有 3倍工资,而 ...

  9. OBJECT_ID()的使用方法

    数据库中每个对像都有一个唯一的ID值,用Object_name(id)可以根据ID值得到对像的名称,object_id(name)可以根据对像名称得到对象的ID object_id()只能返回用户创建 ...

  10. PowerTool x64驱动模块逆向分析(持续更新)

    比赛打完了,来继续搞了,因为那个主动防御正在写,所以想找找思路正好想到可以来逆向一下PT的驱动模块看看pt大大是怎么写的程序. PT x64版本的驱动模块是这个kEvP64.sys. 0x0 先来看看 ...