03 Ceph X认证与授权
Ceph使用cephx协议对客户端进行身份认证。每个MON都可以对客户端进行身份验正并分发密钥,不存在单点故障和性能瓶颈。
当一个 Client 需要连接 Ceph 集群时,它首先通过自己的用户名和秘钥(client.cinder/client.nova…) 来连接到 /etc/ceph/ceph.conf配置文件指定IP的MON,认证成功后,可以获取集群的很多MAP( monmap,osdmap,crushmap…),通过这些 MAP,即可向 Ceph 集群读取数据。

Client向MON发起认证请求,MON使用客户端密钥对session key进行加密,会返回用于身份验正的数据结构,其包含获取Ceph服务时用到的session key;
Client收到加密的session key,通过客户端密钥进行解密;
Client使用session key向MON请求所需的服务的ticket;MON向客户端提供一个ticket,该ticket使用session key进行加密(还是使用客户端秘钥加密???),用于向实际处理数据的OSD等验正客户端身份。
Clent收到加密后的ticket后,进行解密,此后使用该ticket向OSD发起请求。MON和OSD共享同一个secret,因此OSD会信任由MON发放的ticket。此外ticket存在有效期限。
注意:CephX身份验正功能仅限制Ceph的各组件之间,它不能扩展到其它非Ceph组件;它并不解决数据传输加密的问题;

无论Ceph客户端是何类型,Ceph都会在存储池中将所有数据存储为对象,Ceph用户需要拥有存储池访问权限才能读取和写入数据,Ceph用户必须拥有执行权限才能使用Ceph的管理命令。
用户是指个人或系统参与者(例如应用)。通过创建用户,可以控制谁(或哪个参与者)能够访问Ceph存储集群、以及可访问的存储池及存储池中的数据。Ceph支持多种类型的用户,但可管理的用户都属于Client类型,区分用户类型的原因在于,MON、OSD和MDS等系统组件也使用cephx协议,但它们不是客户端(是系统参与者);
完整的用户标识:通过点号来分隔用户类型和用户名,格式为TYPE.ID,例如client.admin等
Ceph基于“使能(capabilities)”来描述用户可针对MON、OSD或MDS使用的权限范围或级别。
通用语法格式:daemon-type 'allow caps' […]
各组件的使能:
MON使能:
1、包括r、w、x和allow profile cap
2、例如:
mon 'allow rwx',以及mon 'allow profile osd'等OSD:
1、包括r、w、x、class-read、class-write和profile osd
2、此外,osd还允许进行存储池和名称空间设置权限。默认对整个集群所有osd上的所有pool设置权限。
MDS:
1、只需要allow,或留空,等同于allow rw。
各项使能的解释说明
- allow:
- 需先于守护进程的访问设置指定;
- 仅对MDS表示rw,其他的表示字面意思。
- r:读取权限,访问MON以检索CRUSH时依赖此使能
- w:对象写入权限
- x:调用类方法(读取和写入)的能力,以及在MON上执行auth操作的能力
- class-read:x能力的子集,授予用户调用类读取方法的能力
- class-write:x的子集,授予用户调用类写入方法的能力
- *:授予用户对特定守护进程/存储池的读取、写入和执行权限,以及执行管理命令的能力
- profile osd:
- 授予用户以某个OSD身份连接到其他 OSD 或监视器的权限。
- 授予OSD权限,使OSD能够处理复制检测信号流量和状态报告
- profile mds:
- 授予用户以某个mds身份连接到其他mds或监视器的权限
- profile bootstrap-osd:
- 授予用户引导OSD的权限。
- 授权给部署工具,使其在引导 OSD 时有权添加密钥。
- profile bootstrap-mds:
- 授予用户引导mds的权限。
- 授权给部署工具,使其在引导元数据服务器时有权添加密钥
- Profile rbd:
- 授予用户以某个rbd身份连接到其他组件的权限。
ceph auth get-or-create client.kubernetes mon 'profile rbd' osd 'profile rbd pool=kubernetes' mgr 'profile rbd pool=kubernetes'
- 授予用户以某个rbd身份连接到其他组件的权限。
- ……
Ceph集群管理员能够直接在Ceph集群中创建、更新和删除用户。创建用户时,可能需要将密钥分发到客户端,以便将密钥添加到密钥环。
ceph auth list
用户标识:TYPE.ID,因此,osd.0表示OSD类型的用户,用户ID为0
示例:
[cephadm@ceph-admin ceph-cluster]$ ceph auth list
mds.stor01
key: AQAoY15h4itZHRAAvra+bxGw4lGAhnM6AO/AJg== #base64编码的key
caps: [mds] allow
caps: [mon] allow profile mds
caps: [osd] allow rwx
osd.0
key: AQAVVl5h/JShOhAATWjlUZw1ikhB+CleLH64Lw==
caps: [mgr] allow profile osd
caps: [mon] allow profile osd
caps: [osd] allow *
client.admin
key: AQCyTV5h3JXiNxAAiKDlKkHrblFYM9Inh6fBjA==
caps: [mds] allow *
caps: [mgr] allow *
caps: [mon] allow *
caps: [osd] allow *
秘钥环本身信息是放在集群内部的,但是可以导出到文件中(秘钥环文件),一般导出的文件为/etc/ceph/ceph.client.admin.keyring
ceph auth get TYPE.ID
或者
ceph auth export TYPE.ID
ceph auth add #规范方法,它能够创建用户、生成密钥并添加指定的caps
ceph auth get-or-create #简便方法,创建用户并返回密钥文件格式的密钥信息,或者在用户存在时返回用户名及密钥文件格式的密钥信息
ceph auth get-or-create-key #简便方法,创建用户并返回密钥信息,或者在用户存在时返回密钥信息
注意:典型的用户至少对 Ceph monitor 具有读取功能,并对 Ceph OSD 具有读取和写入功能;另外,用户的 OSD 权限通常应该限制为只能访问特定的存储池,否则,他将具有访问集群中所有存储池的权限
[root@stor01 ~]# ceph auth add client.testuser mon 'allow r' osd 'allow rw pool=rbdpool'
added key for client.testuser
[root@stor01 ~]# ceph auth get client.testuser
[client.testuser]
key = AQBPql5hTWj1BxAAf9GEel56XQo8b0dbfVSIlw==
caps mon = "allow r"
caps osd = "allow rw pool=rbdpool"
exported keyring for client.testuser
[root@stor01 ~]# ceph auth get-or-create client.testuser mon 'allow r' osd 'allow rw pool=rbdpool'
[client.testuser]
key = AQBPql5hTWj1BxAAf9GEel56XQo8b0dbfVSIlw==
[root@stor01 ~]# ceph auth get-or-create-key client.testuser mon 'allow r' osd 'allow rw pool=rbdpool'
AQBPql5hTWj1BxAAf9GEel56XQo8b0dbfVSIlw==
ceph auth print-key TYPE.ID
[root@stor01 ~]# ceph auth print-key client.testuser
AQBPql5hTWj1BxAAf9GEel56XQo8b0dbfVSIlw==
ceph auth import #需要指定密钥环
ceph auth caps会覆盖用户现有的caps,因此修改前,需要事先使用ceph auth get TYPE.ID命令查看用户的caps;
若添加caps,则需要先指定原有的caps;
如取消某个用户对特定守护进程的所有访问权限,可以指定一个空的字符串。
ceph auth caps TYPE.ID DAEMON 'allow [r|w|x|*|...] [pool=pool-name] [namespace=namespace-name]' ...
[root@stor01 ~]# ceph auth get client.testuser
[client.testuser]
key = AQBPql5hTWj1BxAAf9GEel56XQo8b0dbfVSIlw==
caps mon = "allow r"
caps osd = "allow rw pool=rbdpool"
exported keyring for client.testuser
[root@stor01 ~]# ceph auth caps client.testuser mon 'allow rw' osd "allow rw pool=rbdpool"
updated caps for client.testuser
[root@stor01 ~]# ceph auth get client.testuser
[client.testuser]
key = AQBPql5hTWj1BxAAf9GEel56XQo8b0dbfVSIlw==
caps mon = "allow rw"
caps osd = "allow rw pool=rbdpool"
exported keyring for client.testuser
ceph auth del TYPE.ID
[root@stor01 ~]# ceph auth del client.testuser
updated
[root@stor01 ~]# ceph auth get client.testuser
Error ENOENT: failed to find client.testuser in keyring
keyring是一个存储多个用户的secrets、passwords、keys、certificates的集合,并且能够被某个应用程序使用。
密钥环文件存储一个或多个 Ceph 身份验证密钥以及可能的相关功能规范(caps)。
每个key都与某个实体名称相关联,形式为 {client,mon,mds,osd}.name。
ceph-authtool是一个create、view、modify秘钥环文件的工具。
访问Ceph集群时,客户端会于本地查找密钥环,默认情况下,Ceph会使用以下四个密钥环名称预设密钥环:
- /etc/ceph/cluster-name.user-name.keyring:保存单个用户的keyring
- /etc/ceph/cluster-name.keyring:保存多个用户的keyring
- /etc/ceph/keyring
- /etc/ceph/keyring.bin
cluster-name是为集群名称,默认为ceph,user-name是为用户标识(TYPE.ID)。例如client.admin用户的在名为ceph的集群上的密钥环文件名为ceph.client.admin.keyring
ceph auth add等命令添加的用户只是存在于ceph集群中,如果将其放置在秘钥环文件中,还需要额外使用ceph-authtool命令为其创建用户密钥环。
ceph客户端通过keyring文件查找用户名并检索密钥。
ceph-authtool --create-keyring /path/to/kerying #此时keyring文件为空文件
- keyring文件一般应该保存于/etc/ceph目录中,以便客户端能自动查找
- 创建包含多个用户的keyring文件时,应该使用cluster-name.keyring作为文件名
- 创建仅包含单个用户的kerying文件时,应该使用cluster-name.user-name.keyring作为文件名
可将某个用户从包含多个用户的keyring中导出,并保存于一个专用的keyring文件:
ceph auth get TYPE.ID -o /etc/ceph/cluster-name.user-name.keyring
也可将用户的keyring合并至一个统一的keyring文件中:
ceph-authtool /etc/ceph/cluster-name.keyring --import-keyring /etc/ceph/cluster-name.user-name.keyring
示例:
[root@stor01 ~]# ceph auth get-or-create client.kube mon 'allow r' osd 'allow * pool=kube'
[client.kube]
key = AQAHsF5h4W4sMhAAxBIAUb8i0PxUSpfdOiug0g=
#创建一个空的keyring
[root@stor01 ~]# ceph-authtool --create-keyring ceph0.keyring
creating ceph0.keyring
[root@stor01 ~]# cat ceph0.keyring
#导出keyring
[root@stor01 ~]# ceph auth get client.kube -o ceph.client.kube.keyring
exported keyring for client.kube
[root@stor01 ~]# cat ceph.client.kube.keyring
[client.kube]
key = AQAHsF5h4W4sMhAAxBIAUb8i0PxUSpfdOiug0g==
caps mon = "allow r"
caps osd = "allow * pool=kube"
#导入第1个keyring
[root@stor01 ~]# ceph-authtool /root/ceph.keyring --import-keyring /root/ceph.client.kube.keyring
importing contents of ceph.client.kube.keyring into ceph.keyring
[root@stor01 ~]# cat ceph.keyring
[client.kube]
key = AQAHsF5h4W4sMhAAxBIAUb8i0PxUSpfdOiug0g==
caps mon = "allow r"
caps osd = "allow * pool=kube"
#导入第2个keyring
[root@stor01 ~]# ceph-authtool ceph.keyring --import-keyring /tmp/ceph.client.testuser.keyring
importing contents of /tmp/ceph.client.testuser.keyring into ceph.keyring
[root@stor01 ~]# cat ceph.keyring
[client.kube]
key = AQAHsF5h4W4sMhAAxBIAUb8i0PxUSpfdOiug0g==
caps mon = "allow r"
caps osd = "allow * pool=kube"
[client.testuser]
key = AQCHrl5hednRLRAAqUX5oICf/8vMNm3H4Y0Rlg==
caps mon = "allow r"
caps osd = "allow rw pool=rbdpool"
#查看
[root@stor01 ~]# ceph-authtool -l ceph.keyring
[client.kube]
key = AQAHsF5h4W4sMhAAxBIAUb8i0PxUSpfdOiug0g==
caps mon = "allow r"
caps osd = "allow * pool=kube"
[client.testuser]
key = AQCHrl5hednRLRAAqUX5oICf/8vMNm3H4Y0Rlg==
caps mon = "allow r"
caps osd = "allow rw pool=rbdpool"
ceph-authtool命令可直接创建用户、授予caps并创建keyring,但创建的用户只存在于keyring中,没有在ceph集群中创建。手动安装集群时,在集群不存在的时候,可以使用该命令创建keyring:
ceph-authtool keyringfile [-C | --create-keyring] [-n | --name entityname] [--gen-key] [-a | --add-key base64_key] [--cap | --caps capfile]
命令选项:
- -C, –create-keyring:will create a new keyring, overwriting any existing keyringfile
- –gen-key:will generate a new secret key for the specified entityname
- –add-key:will add an encoded key to the keyring
- –cap subsystem capability:will set the capability for given subsystem
- –caps capsfile:will set all of capabilities associated with a given key, for all subsystems
注意:此种方式添加的用户仅存在于keyring文件中,管理员还需要额外将其添加至Ceph集群上;
ceph auth add TYPE.ID -i /PATH/TO/keyring #将keyring文件中用户加入到ceph集群