一、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. (转载) 天梯赛 L2-018. 多项式A除以B

    题目链接 题目描述 这仍然是一道关于A/B的题,只不过A和B都换成了多项式.你需要计算两个多项式相除的商Q和余R,其中R的阶数必须小于B的阶数. 输入格式: 输入分两行,每行给出一个非零多项式,先给出 ...

  2. HDU 1073 Online Judge (字符串处理)

    题目链接 Problem Description Ignatius is building an Online Judge, now he has worked out all the problem ...

  3. Memcached与KVDB的区别

    Memcached将数据存储在内存中,数据易丢失,不适合对数据进行长期存储. KVDB则是将数据存储在磁盘中,数据安全性级别高,不易丢失.

  4. JavaScript 实用技巧和写法建议

    1.前言 从大学到现在,接触前端已经有几年了,感想方面,就是对于程序员而言,想要提高自己的技术水平和编写易于阅读和维护的代码,我觉得不能每天都是平庸的写代码,更要去推敲,去摸索和优化代码,总结当中的技 ...

  5. C++的各种初始化方式

    C++小实验测试:下面程序中main函数里a.a和b.b的输出值是多少? #include <iostream> struct foo { foo() = default; int a; ...

  6. CentOS6.6 编译Redis报错:"Newer version of jemalloc required"

    一.前言 不同系统同一个问题,可能解决方法不一样,也可能会遇到不同的问题,所以具体情况具体分析,我的系统是Centos6.6, 查看系统命令  cat /etc/issue 二.安装redis后编译报 ...

  7. Ubuntu使用apt-get upgrade升级时出错

    今天在按照常规的sudo apt-get update更新软件列表后,再使用sudo apt-get upgrade升级软件时,出现了以下的错误: 正在设置 linux-image-extra-4.4 ...

  8. Windows执行命令与下载文件总结

    1.前言 在渗透或是病毒分析总是会遇到很多千奇百怪的下载文件和执行命令的方法. 2.实现方式 2.1.Powershell win2003.winXP不支持 $client = new-object ...

  9. CentOS7.3下的一个iptables配置

    centos7.3默认使用的防火墙应该是firewall,而不是iptables.而我们xxmj服务器使用的是iptables防火墙.所以,在配置防火墙之前,我们需要先关闭firewall,安装ipt ...

  10. SPI子系统分析之二:数据结构【转】

    转自:http://www.cnblogs.com/jason-lu/articles/3164901.html 内核版本:3.9.5 spi_master struct spi_master用来描述 ...