keystone认证方式:UUID、PKI、Fernet;

知识点复习:

通俗的讲,token 是用户的一种凭证,需拿正确的用户名/密码向 Keystone 申请才能得到。如果用户每次都采用用户名/密码访问 OpenStack API,容易泄露用户信息,带来安全隐患。所以 OpenStack 要求用户访问其 API 前,必须先获取 token,然后用 token 作为用户凭据访问 OpenStack API。

公开密钥加密,也称为非对称加密(asymmetric cryptography,加密密钥和解密密钥不相同),在这种密码学方法中,需要一对密钥,分别为公钥(Public Key)和私钥(Private Key),公钥是公开的,私钥是非公开的,需用户妥善保管。如果把加密和解密的流程当做函数 C(x) 和 D(x),P 和 S 分别代表公钥和私钥,对明文 A 和密文 B 而言,数学的角度上有以下公式:

B = C(A, S)

A = D(B, P)

其中加密函数 C(x), 解密函数 D(x) 以及公钥 P 均是公开的。采用公钥加密的密文只能用私钥解密,采用私钥加密的密文只能用公钥解密。非对称加密广泛运用在安全领域,诸如常见的 HTTPS,SSH 登录等。

数字签名又称为公钥数字签名,首先采用 Hash 函数对消息生成摘要,摘要经私钥加密后称为数字签名。接收方用公钥解密该数字签名,并与接收消息生成的摘要做对比,如果二者一致,便可以确认该消息的完整性和真实性。

(1)UUID认证原理:

当用户需要进行操作时(比如访问nova创建虚拟机),用户拿着有效的用户名/密码先去keystone认证,keystone返回给用户一个token(即UUID)。之后用户进行其他操作(如访问nova),先出示这个token给nova-api,nova收到请求后,就用这个token去向keystone进行请求验证。keystone通过比对token,以及检查token的有效期,判断token的有效性,最后返回给nova结果。

缺陷:每次请求都要经过keystone进行验证,造成性能瓶颈。

1.用户输入用户名密码,发送给keystone。

2.Keystone验证用户名密码,并且生成token(UUID),发送给客户端。

3.客户端缓存UUID token

4.客户端发送具体的执行请求(nova boot)和UUID给keystone。

5.Keystone从http请求中获取token,并检查token是否有效

6.Token有效,处理请求,并返回客户端请求结果

7.Token失效,拒绝客户端请求,返回401。

UUID方式源码分析:

UUID token 是长度固定为 32 Byte 的随机字符串,由 uuid.uuid4().hex 生成。

def _get_token_id(self, token_data):    return uuid.uuid4().hex

生成的样例:144d8a99a42447379ac37f78bf0ef608

(2)PKI认证原理:

在keystone初始化时,keystone生成了CA的公钥CA.pem和私钥CA.key,同时keystone产生了自己的公钥keystone.pub和私钥keystone.key,然后将keystone.pub进行CA的签名,生成keystone.pem。

当用户拿着用户名/密码去keystone认证后,keystone将用户的基本信息通过keystone.key进行加密,并将密文作为token返还给用户。当用户拿着token发送请求时(例如访问nova),nova拿到用户token时,通过事先拿到keystone的证书keystone.pem(这一过程只需要进行一次)进行解密,获取用户信息。

对于用户的token,还需进行token的合法时间,以及token还是否存在进行判断。所以当nova每一次拿到token后还需向keystone询问一次token的失败列表,检查token是否失效。这一过程对于keystone的负载还是相当轻的,所以PKI还是有效解决了keystone性能瓶颈的问题。

小结:OpenStack服务中的每一个API Endpoint都有一份keystone签发的证书,失效列表和根证书。API不用在直接去keystone认证token是否合法,只需要根据keystone的证书和失效列表就可以确定token是否合法。但是这里还是会有每次都需要请求keystone去获取失效列表的操作,不可避免。

PKI的流程,首先需要使用 keystone-manage pki_setup命令生成CA及相关的令牌机制,其代码如下所示:

def _get_token_id(self, token_data):

try:

token_json = jsonutils.dumps(token_data, cls=utils.PKIEncoder)

token_id = str(cms.cms_sign_token(token_json,

CONF.signing.certfile,

CONF.signing.keyfile))   #DEFAULT_TOKEN_DIGEST_ALGORITHM=sha256

其中,‘token_data’是获取的user、role、endpoint、catlog等信息集合,而最重要的语句是cms使用签名生成token的过程:cms_sign_token,使用默认的sha256方式加密,处理过程使用process,进行数据的读取、处理,

process = subprocess.Popen(['openssl', 'cms', '-sign',

'-signer', signing_cert_file_name,

'-inkey', signing_key_file_name,

'-outform', 'PEM',

'-nosmimecap', '-nodetach',

'-nocerts', '-noattr',

'-md', message_digest, ],

stdin=subprocess.PIPE,

stdout=subprocess.PIPE,

stderr=subprocess.PIPE,

close_fds=True)

最后output, err = process.communicate(data) 生成Token-id,这个过程涉及到openssl相关的加密技术。

CMS token一般都超过1600个字节,样例:

(3)Fernet认证原理:

1.user在客户端输入用户名密码,发送给keystone。

2.Keystone验证用户名密码,并且生成token(UUID),发送给客户端。

3.客户端缓存token(UUID)

4.客户端发送具体的执行请求给openstack API

5、OpenStack API向 keystone请求token认证

6.Keystone从http请求中获取token,并检查token是否有效

7.Token有效,处理请求,并返回openstack api请求结果

8.Token失效,拒绝客户端请求,返回401。

当集群运行较长一段时间后,访问其 API 会变得奇慢无比,究其原因在于 Keystone 数据库存储了大量的 token 导致性能太差,解决的办法是经常清理 token。为了避免上述问题,社区提出了Fernet token,fernet 是当前主流推荐的token格式,它采用 cryptography 对称加密库(symmetric cryptography,加密密钥和解密密钥相同) 加密 token,具体由 AES-CBC 加密和散列函数 SHA256 签名。Fernet 是专为 API token 设计的一种轻量级安全消息格式,不需要存储于数据库,减少了磁盘的 IO,带来了一定的性能提升。为了提高安全性,需要采用 Key Rotation 更换密钥。

以上代码表明,token 包含了 user_id,project_id,domain_id,methods,expires_at 等信息,重要的是,它没有 service_catalog,所以 region 的数量并不影响它的大小。self.pack() 最终调用如下代码对上述信息加密:

该token 的大小一般在 200 多 Byte 左右,样例:

gAAAAABWfX8riU57aj0tkWdoIL6UdbViV-632pv0rw4zk9igCZXgC-sKwhVuVb-wyMVC9e5TFc 7uPfKwNlT6cnzLalb3Hj0K3bc1X9ZXhde9C2ghsSfVuudMhfR8rThNBnh55RzOB8YTyBnl9MoQ XBO5UIFvC7wLTh_2klihb6hKuUqB6Sj3i_8

简要叙述一下fernet采用 Key Rotation 更换密钥的原理,默认的轮换长度是3,当以keystone-manage fernet-setup生成密钥时,会看到0、1两个索引表征,这分别是什么意思呢?

在此,需要提一下三个概念:

primary key(主密钥)有且只有一个,名为为x,当前用于加密解密token

secondary key(次次密钥)有x-1个,从Primary退役下来的,用于解密当初它加密过的token

staged key(次密钥)有且只有一个,命名为0,准备下一个rotation时变为Primary key,可以解密token

那么上述0 表示的是staged key,1 表示的是primary key,

primary key相比较另外两种key,它的索引最高,并且可以加密、也可以解密;

staged key 相较于secondary key,它更有机会变为primary key。

AES256加密token,SHA256 HMAC验证完整性,

只要Keystone具有访问这些key的权限,token就不需要在keystone数据库中存储

fernet的数据性能最好,原因是它不需要后端持久化操作(采用 Key Rotation定期 更换密钥,只要Keystone具有访问这些key的权限,更新后的token就不需要在keystone数据库中存储,缓解了数据库负载压力),并且token的认证,使用的是密钥进行解密,能够直接得出token Data的信息,从而进行token的过期认证。它的失败原因,只可能是token过期了,或者是token放到了cache缓存中,但是已经被回收了。归根到底,还是token过期了。

keystone令牌三种生成方式的更多相关文章

  1. java的三种随机数生成方式

    随机数的产生在一些代码中很常用,也是我们必须要掌握的.而java中产生随机数的方法主要有三种: 第一种:new Random() 第二种:Math.random() 第三种:currentTimeMi ...

  2. hibernate笔记--继承映射关系的三种实现方式

    单表继承映射(一张表): 假设我们现在有三个类,关系如下: Person类有两个子类Student和Teacher,并且子类都具有自己独有的属性.这种实体关系在hibernate中可以使用单表的继承映 ...

  3. SP避免Form重复提交的三种方案

    SP避免Form重复提交的三种方案  1) javascript ,设置一个变量,只允许提交一次.   <script language="javascript">  ...

  4. 初学者易上手的SSH-hibernate02 三种查询方式

    在上一章中已经搭建好了一个hibernate的环境,那么这一章我们就使用这个环境来进行基本CRUD.在这之前我们先了解一个东西:主键生成策略.就是当向数据库表中插入记录的时候,这个记录的主键该如何生成 ...

  5. 【转】ABP webapi三种方式

    作者:圣杰 链接:https://www.jianshu.com/p/d14733432dc2 來源:简书 著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 1. 引言 上一节我们 ...

  6. (转)理解Keystone的四种Token

    Token 是什么 通俗的讲,token 是用户的一种凭证,需拿正确的用户名/密码向 Keystone 申请才能得到.如果用户每次都采用用户名/密码访问 OpenStack API,容易泄露用户信息, ...

  7. nginx限流方案的实现(三种方式)

    通过查看nginx官方文档,小弟查看到了三种nginx限流方式. 1.limit_conn_zone 2.limit_req_zone 3.ngx_http_upstream_module 前两种只能 ...

  8. Secret的三种形式

    Secret ConfigMap这个资源对象是Kubernetes当中非常重要的一个对象,一般情况下ConfigMap是用来存储一些非安全的配置信息,如果涉及到一些安全相关的数据的话用ConfigMa ...

  9. 华为云计算IE面试笔记-FusionSphere Openstack有哪些关键组件,各组件主要功能是什么?三种存储接入组件的差异有哪些?

    1. Nova:在OpenStack环境中提供计算服务,负责计算实例(VM,云主机)生命周期的管理,包括生成.调度和回收.Nova不负责计算实例的告警上报(FC管). 2. Cinder:为计算实例提 ...

随机推荐

  1. Android get current Locale, not default

    he default Locale is constructed statically at runtime for your application process from the system ...

  2. JVM 运行时数据区详解

    一.运行时数据区 Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同数据区域. 1.有一些是随虚拟机的启动而创建,随虚拟机的退出而销毁,所有的线程共享这些数据区. 2.第二种则 ...

  3. CFileDialog类的详情

    CFileDialog类封装了Windows常用的文件对话框. 常用的文件对话框提供了一种简单的与Windows标准相一致的文件打开和文件存盘对话框功能. void CnotepadDlg::OnOp ...

  4. wordpress添加文章阅读数量

    将下面代码添加到functions.php //取得文章的阅读次数 function post_views($before = '点击 ', $after = ' 次', $echo = 1) { g ...

  5. 和我一起打造个简单搜索之ElasticSearch集群搭建

    我们所常见的电商搜索如京东,搜索页面都会提供各种各样的筛选条件,比如品牌.尺寸.适用季节.价格区间等,同时提供排序,比如价格排序,信誉排序,销量排序等,方便了用户去找到自己心里理想的商品. 站内搜索对 ...

  6. Ice简介+Qt代码示例

    1.ICE是什么? ICE是ZEROC的开源通信协议产品,它的全称是:The Internet Communications Engine,翻译为中文是互联网通信引擎,是一个面向对象的中间件,它封装并 ...

  7. Linux 技巧:让进程在后台可靠运行的几种方法(转)

    我们经常会碰到这样的问题,用 telnet/ssh 登录了远程的 Linux 服务器,运行了一些耗时较长的任务, 结果却由于网络的不稳定导致任务中途失败.如何让命令提交后不受本地关闭终端窗口/网络断开 ...

  8. 分布式理论(八)—— Consistent Hash(一致性哈希算法)

    前言 在分布式系统中,常常需要使用缓存,而且通常是集群,访问缓存和添加缓存都需要一个 hash 算法来寻找到合适的 Cache 节点.但,通常不是用取余hash,而是使用我们今天的主角-- 一致性 h ...

  9. 并发编程——ConcurrentHashMap#addCount() 分析

    前言 ConcurrentHashMap 精华代码很多,前面分析了 helpTransfer 和 transfer 和 putVal 方法,今天来分析一下 addCount 方法,该方法会在 putV ...

  10. .20-浅析webpack源码之compile流程-Template模块

    这里的编译前指的是开始触发主要的事件流this-compilaiton.compilation之前,由于还有一些准备代码,这一节全部弄出来. 模块基本上只走构造函数,具体的方法调用的时候再具体讲解. ...