OpenStack Identity Keystone基本概念及验证进化过程

一、概念与关系

    先上图,看user、credential、group、role、project/tenant、service、endpoint、domain、region;token、authentication、scope等彼此间的关系。

OpenStack Identity Keystone基本概念及验证进化过程_第1张图片

1. resource:project、domain

2. credential:可以是3个配对,username/password,username/API key,token

3. token:token是由keystone进行账户验证后返回给客户端的字符串,作为后续验证凭证,有3种,UUID、PKI/PKIZ(PKI的压缩版)、fernet token(有加密解密过程)

4. authentication:

    a. keystone针对用户的请求进行授权验证,验证对象为credential的3个配对

    b. scope:验证结果的token是有范围或者说是标的的,比如project范围还是domain范围

5. username/domain:用户名属于并在一个domain中唯一,userid全局唯一

6. group/project、group/domain:太常见了,不解释

7. role:可分配给user和group,全局唯一;权限地位的象征,VIP等级的高低,类似QQ的银钻黄钻

8. project/domain:project项目属于并在一个domain中唯一;资源集合;project在Identity API V3(Kilo)之前叫tenant

9. domain:project项目的抽象层,标示一个具体客户(公司、组织、机构等)的 管理边界和范围,也就是可以在一个domain下管理多个project了,默认名为Default

10. region:

    a. OpenStack部署的地理位置,这个层面是为了识别多地域部署,比如阿里云虚机可选择深圳或者北京的IDC,默认为regionOne

    b. 各个region具有独立的全部资源,regions之间共享一个Keystone和Horizon

11. service:比如计算的nova,块的cinder,网络的neutron等;service在keystone看来是个user

12. endpoint/service:service对外服务的窗口,就如同电信的营业厅,酒吧的吧台;endpoint有3个地址,public、private、admin分别对应不同权限用途

最后,为啥要用token,而不是直接用户名/密码对了事?因为,每个请求都指向一个对应的API比如nova-api,而API干事之前都需要验证你这个客户端,可能是Horizon,可能是Python-client,或者干脆赤裸裸的REST,如果每次都用对应的用户名密码对就不便于统一管理也不太安全。但是用token,因为token有过期这个么时间限制便于客户端缓存,只是一串统一的的字符。

# 客户端POST上去的请求:
{
    "auth": {
        "identity": {
            "methods": [
                "password"
            ],
            "password": {
                "user": {
                    "domain": {
                        "name": "acme"
                    }
                    "name": "userA",
                    "password": "secretsecret"
                }
            }
        },
        "scope": {
            "project": {
                "domain": {
                    "id": "1789d1"
                },
                "name": "project-x"
            }
        }
    }
}
# 整成一个环境变量
$ export OS_PROJECT_DOMAIN_ID=1789d1
$ export OS_USER_DOMAIN_NAME=acme
$ export OS_USERNAME=userA
$ export OS_PASSWORD=secretsecret
$ export OS_PROJECT_NAME=project-x

二、Keystone的验证过程

1. UUID (通用唯一识别码,Universally Unique Identifier)

OpenStack Identity Keystone基本概念及验证进化过程_第2张图片


①. Keystone:

    a. 生成UUID,存储UUID在后端比如Mysql,把这个UUID返回给客户端

    b. 客户端发送过来的UUID endpoint API(service)都需要拿到后端去验证,包括过期日期

    c. 验证成功就返回success,否则failure给API

②. 客户端:把Keystone返回的UUID给缓存起来,客户端的每个请求都要附带这个UUID

③. 如此,客户端的每次请求,Keystone都要参与验证(下发UUID时还需要存储,token过期时还要去删除),多用户多操作时对后端的压力着实有点大

# 查看Mysql中数据库keystone中的token表格
MariaDB [keystone]> select id,expires from token;
+----------------------------------+---------------------+
| id                            | expires       |
+----------------------------------+---------------------+
| 7007133585f849f78b482546ebdc9fb6 | 2016-06-29 08:00:02 |
| 188575d329534b00822fae8f83040ced | 2016-06-29 08:00:03 |
| 4d0c793a331a4476bb85e7090ee059a4 | 2016-06-29 08:00:03 |
| 0f72278b68304d508ae0c9c64db29876 | 2016-06-29 08:00:04 |
| c059b199828f4df388907bd814cf79bc | 2016-06-29 08:00:04 |
| 5548b3bab4ca412e806841d907842d72 | 2016-06-29 08:00:05 |
| 9fe5ebbcbca74251bb2e8187c5af1bd0 | 2016-06-29 08:00:05 |
| 228d211c42444f1fb04c7435ad1a9434 | 2016-06-29 08:51:43 |
| a6f5f50f47294dea866fdcc2a46129a3 | 2016-06-29 08:51:43 |
+----------------------------------+---------------------+

2. PKI/PKIZ(Public Key Infrastructure,Openssl,走PKI那套公私秘钥对的路子,Grizzly)

OpenStack Identity Keystone基本概念及验证进化过程_第3张图片

①. Keystone: 做为CA,只管用自己专用签发私钥(对应有签发证书)去签发准备给客户端的token形成CMS格式的token,同时维护一份CRL(Certificate Revocation List)

②. 各个API:持有Keystone所有家当的一份copy,包括签发证书,CA自身的证书,以及CRL,就像它自己也是个CA

③. 如此,Keystone不必每次客户端请求都亲自处理了,各个API自己去验证,验证标的不是token本身,而是keystone签发的签名

④. 但是,这个CMS token太长了,服务越多越长,一般都超过1600个字节,如下

MIIDsAYJKoZIhvcNAQcCoIIDoTCCA50CAQExCTAHBgUrDgMCGjCCAokGCSqGSIb3DQEHAaCCAnoEggJ2ew0KICAgICJhY2Nlc3MiOiB7DQogICAgICAgICJtZ\
XRhZGF0YSI6IHsNCiAgICAgICAgICAgIC4uLi5tZXRhZGF0YSBnb2VzIGhlcmUuLi4uDQogICAgICAgIH0sDQogICAgICAgICJzZXJ2aWNlQ2F0YWxvZyI6IF\
sNCiAgICAgICAgICAgIC4uLi5lbmRwb2ludHMgZ29lcyBoZXJlLi4uLg0KICAgICAgICBdLA0KICAgICAgICAidG9rZW4iOiB7DQogICAgICAgICAgICAiZXh\
waXJlcyI6ICIyMDEzLTA1LTI2VDA4OjUyOjUzWiIsDQogICAgICAgICAgICAiaWQiOiAicGxhY2Vob2xkZXIiLA0KICAgICAgICAgICAgImlzc3VlZF9hdCI6\
ICIyMDEzLTA1LTI1VDE4OjU5OjMzLjg0MTgxMSIsDQogICAgICAgICAgICAidGVuYW50Ijogew0KICAgICAgICAgICAgICAgICJkZXNjcmlwdGlvbiI6IG51b\
GwsDQogICAgICAgICAgICAgICAgImVuYWJsZWQiOiB0cnVlLA0KICAgICAgICAgICAgICAgICJpZCI6ICI5MjVjMjNlYWZlMWI0NzYzOTMzZTA4YTRjNDE0M2\
YwOCIsDQogICAgICAgICAgICAgICAgIm5hbWUiOiAidXNlciINCiAgICAgICAgICAgIH0NCiAgICAgICAgfSwNCiAgICAgICAgInVzZXIiOiB7DQogICAgICA\
gICAgICAuLi4udXNlcmRhdGEgZ29lcyBoZXJlLi4uLg0KICAgICAgICB9DQogICAgfQ0KfQ0KMYH/MIH8AgEBMFwwVzELMAkGA1UEBhMCVVMxDjAMBgNVBAgT\
BVVuc2V0MQ4wDAYDVQQHEwVVbnNldDEOMAwGA1UEChMFVW5zZXQxGDAWBgNVBAMTD3d3dy5leGFtcGxlLmNvbQIBATAHBgUrDgMCGjANBgkqhkiG9w0BAQEFA\
ASBgEh2P5cHMwelQyzB4dZ0FAjtp5ep4Id1RRs7oiD1lYrkahJwfuakBK7OGTwx26C+0IPPAGLEnin9Bx5Vm4cst/0+COTEh6qZfJFCLUDj5b4EF7r0iosFsc\
pnfCuc8jGMobyfApz/dZqJnsk4lt1ahlNTpXQeVFxNK/ydKL+tzEjg
⑤. 同时,这个PKI只是签名,和UUID一样都没有加密,用Firefox F12或者Wireshark等抓包就能看到明文的token,这时需要做下HTTPS


3. fernet token(Kilo)

①. Staged key:有且只有一个,命名为0,准备下一个rotation时变为Primary key,可以解密token

②. Primary key:有且只有一个,名为为x,当前用于加密解密token

③. Secondary key: 有x-1个,从Primary退役下来的,用于解密当初它加密过的token

④.  AES256加密token,SHA256 HMAC验证完整性,只有Keystone具有访问这些key的权限,token不用存储,250字节以下大小

# vim /etc/keystone/keystone.conf
[fernet_tokens]
key_repository = /etc/keystone/fernet-keys/ /*基于文件的秘钥仓库*/
token_expiration=24
rotation_frequency=6
max_active_keys=(token_expiration/rotation_frequency)+2 /*2=1个staged key+1个将要删掉的secondary key*/

 
  
$ ls -la /etc/keystone/fernet-keys/
drwx------ 2 keystone keystone 4096 .
drwxr-xr-x 3 keystone keystone 4096 ..
-rw------- 1 keystone keystone   44 0    (staged key)
-rw------- 1 keystone keystone   44 2    (secondary key)
-rw------- 1 keystone keystone   44 3    (secondary key)
-rw------- 1 keystone keystone   44 4    (secondary key)
-rw------- 1 keystone keystone   44 5    (secondary key)
-rw------- 1 keystone keystone   44 6    (primary key)


你可能感兴趣的:(DevOps)