1
2
3
4
5
6
7
作者:李晓辉

联系方式:

1. 微信:Lxh_Chat

2. 邮箱:939958092@qq.com

Keystone 令牌概述

在 OpenStack 里,Keystone服务就像是个“守门人”,它通过一系列验证流程来确认你是谁,然后给你发一张“通行证”——也就是令牌。这个令牌可不是随便用的,它有明确的“作用域”,也就是规定了你能用它干啥,比如能访问哪些资源、有什么权限。不过,这个令牌的有效期是有限的,等它到期了或者被撤销了,你就得重新验证身份才能继续用服务。

这种有作用域的令牌其实还挺厉害的,它会清楚地列出你的权限和特权,比如你在当前项目里的角色所定义的那些权限。当你向 OpenStack 服务发起请求时,服务会根据你提供的角色来验证你是否有权访问请求的资源,然后决定是让你通过还是拒绝你。

如果想看看自己当前的令牌,任何用户都可以用 openstack token issue 命令来请求。这个命令的输出会显示你的用户 ID、项目,还有新的令牌到期时间。其实,这种令牌有三种类型:无作用域、项目作用域和域作用域。

Fernet 密钥

在 OpenStack 里,各种令牌提供程序可真是不断升级换代呢!Fernet 是最新的“小能手”,它把之前的 UUID、PKI 和 PKIZ 提供程序里的那些小毛病都给解决了,比如令牌大小、安全性和性能啥的。

令牌这东西,得定期换,这样才能最大程度地防止别人伪造 Fernet 令牌。Fernet 令牌提供程序有个“轮换”绝招,能启用新的对称密钥,同时还能保证用旧密钥创建的 Fernet 令牌能正常解密,一点儿也不耽误事儿。

Fernet 令牌是数字形式的,每个密钥根据轮换中的索引命名,通常放在 Keystone 的配置文件夹里,也就是 /etc/keystone/fernet-keys。在轮换过程中,Fernet 会用到三种类型的密钥:

  1. 主密钥

    • 主密钥就是当前正在用的“主力”。一个身份服务节点上只能有一个主密钥,它的文件名总是带有最高的索引编号。 主密钥负责加密和解密 Fernet 令牌,是核心中的核心。
  2. 辅助密钥

    • 辅助密钥就是之前当过主密钥,后来被替换(轮出)的密钥。它只用来解密 Fernet 令牌,具体来说,就是解密那些之前用它加密的剩余 Fernet 令牌。辅助密钥的文件名带有低于最高编号的索引,但索引值绝不会是 0
  3. 暂存密钥

    • 暂存密钥是新加入的“候补”,它会在下一次密钥轮换时成为下一个主密钥,文件名是 0

这样一套流程下来,Fernet 令牌的管理既安全又高效,完全不用担心令牌被滥用或者失效的问题!

轮转 Fernet 密钥

默认情况下,overcloud 的 Fernet 密钥管理由 Director 使⽤ Mistral 来执⾏。管理员应该使⽤ Mistral来启动 Fernet 密钥轮转,先看看controller上现有的密钥

1
2
3
4
5
6
7
8
9
[root@controller0 fernet-keys]# pwd
/var/lib/config-data/puppet-generated/keystone/etc/keystone/fernet-keys
[root@controller0 fernet-keys]# ls
0 1
[root@controller0 fernet-keys]# cat 0
BFdmfu__yYFapx1vxxw6B7tlYvmbMT-aWv6gdEZJd94=
[root@controller0 fernet-keys]# cat 1
p-g9V2EsPONhrSEkS3-x-gyGQGTTSqHSTTXP8ukwix8=
[root@controller0 fernet-keys]#

来进行轮转,记得登录director,这里要注意,从官方复制粘贴,需要自己加单引号才行

官方链接在此

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
(undercloud) [stack@director ~]$ source stackrc
(undercloud) [stack@director ~]$ openstack workflow execution create tripleo.fernet_keys.v1.rotate_fernet_keys '{"container": "overcloud"}'
+--------------------+-------------------------------------------+
| Field | Value |
+--------------------+-------------------------------------------+
| ID | c20542eb-462e-4b6f-a298-284f52aadbe8 |
| Workflow ID | e4fbacec-a504-45e3-9d35-6268573c79d5 |
| Workflow name | tripleo.fernet_keys.v1.rotate_fernet_keys |
| Workflow namespace | |
| Description | |
| Task Execution ID | <none> |
| Root Execution ID | <none> |
| State | RUNNING |
| State info | None |
| Created at | 2024-01-01 13:35:15 |
| Updated at | 2024-01-01 13:35:15 |
+--------------------+-------------------------------------------+

轮转可能需要一会儿,你可以用下面的看看是否成功

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
(undercloud) [stack@director ~]$ openstack workflow execution show c20542eb-462e-4b6f-a298-284f52aadbe8
+--------------------+-------------------------------------------+
| Field | Value |
+--------------------+-------------------------------------------+
| ID | c20542eb-462e-4b6f-a298-284f52aadbe8 |
| Workflow ID | e4fbacec-a504-45e3-9d35-6268573c79d5 |
| Workflow name | tripleo.fernet_keys.v1.rotate_fernet_keys |
| Workflow namespace | |
| Description | |
| Task Execution ID | <none> |
| Root Execution ID | <none> |
| State | SUCCESS |
| State info | None |
| Created at | 2024-01-01 13:35:15 |
| Updated at | 2024-01-01 13:35:31 |
+--------------------+-------------------------------------------+

验证轮转效果

看看默认密钥存在哪儿了

看上去我们的密钥后端程序是fernet,并且存在/etc/keystone/fernet-keys

1
2
3
4
5
6
7
8
[root@controller0 keystone]# pwd
/var/lib/config-data/puppet-generated/keystone/etc/keystone
[root@controller0 keystone]# crudini --get keystone.conf token provider
fernet
[root@controller0 keystone]# crudini --get keystone.conf catalog driver
sql
[root@controller0 keystone]# crudini --get keystone.conf fernet_tokens key_repository
/etc/keystone/fernet-keys

再去看看我们的密钥情况

1
2
3
4
5
6
7
8
9
10
(undercloud) [stack@director ~]$ ssh root@controller0
[root@controller0 ~]# cd /var/lib/config-data/puppet-generated/keystone/etc/keystone/fernet-keys/
[root@controller0 fernet-keys]# ls
0 1 2
[root@controller0 fernet-keys]# cat 0
JM-2KPqMR5qSB1bIyNh94Kltf_pUJpqHt0VXm7qYwSk=
[root@controller0 fernet-keys]# cat 1
p-g9V2EsPONhrSEkS3-x-gyGQGTTSqHSTTXP8ukwix8=
[root@controller0 fernet-keys]# cat 2
BFdmfu__yYFapx1vxxw6B7tlYvmbMT-aWv6gdEZJd94=

设定过期时间的间隔

看上去我的间隔是3600秒

1
2
[root@controller0 fernet-keys]# crudini --get ../keystone.conf token expiration
3600

设定最多有几个密钥

1
2
[root@controller0 fernet-keys]# crudini --get ../keystone.conf fernet_tokens max_active_keys
5