目录
前言
常规的身份认证系统无非三点:
- 账户
- 角色权限
- 认证鉴权
本篇也从这三个角度来解析 Ceph 的用户管理与认证。
Ceph 的用户管理
Ceph 的用户可以是一个具体的人或系统角色(e.g. 应用程序),Ceph 管理员通过创建用户并设置权限来控制谁可以访问、操作 Ceph Cluster、Pool 或 Objects 等资源。
查看用户清单与权限示例(展示部分):
[root@ceph-node1 ~]# ceph auth ls
installed auth entries:
# MDS 守护进程用户
mds.ceph-node1
# 用户密钥
key: AQBFD8BcjASRNRAAye8Z9tMVe4if2vU0BdQJBg==
# 用户授权
caps: [mds] allow
caps: [mon] allow profile mds
caps: [osd] allow rwx
...
# OSD 守护进程用户
osd.0
key: AQBu575cdhmoMxAAj0b4L25hgdqBJFwJb7MDoQ==
caps: [mgr] allow profile osd
caps: [mon] allow profile osd
caps: [osd] allow *
...
# Admin 管理员用户
client.admin
key: AQB3175cZrKQEBAApE+rBBXNvbZs16GkpOjXhw==
caps: [mds] allow *
caps: [mgr] allow *
caps: [mon] allow *
caps: [osd] allow *
# OpenStack Cinder 用户
client.cinder
key: AQDVgMFcn/7sEhAA1sLOM+CTWkkGGJ47GRqInw==
caps: [mon] profile rbd
caps: [osd] profile rbd pool=volumes, profile rbd pool=vms, profile rbd pool=images
client.cinder-backup
key: AQDZgMFcBAAbNRAAepH+HZds85HvAYuV1wwTKQ==
caps: [mon] profile rbd
caps: [osd] profile rbd pool=backups
# OpenStack Glance 用户
client.glance
key: AQDOgMFcq+DEBhAAr4iu86M6h7rCcyYcPQogwQ==
caps: [mon] profile rbd
caps: [osd] profile rbd pool=images
Ceph 的用户类型可以分为以下几类:
- 客户端用户
- 操作用户(e.g. client.admin)
- 应用程序用户(e.g. client.cinder)
- 其他用户
- Ceph 守护进程用户(e.g. mds.ceph-node1、osd.0)
用户命名遵循 <TYPE.ID>
的命名规则,其中 Type 有 mon,osd,client 三者,L 版本以后添加了 mgr 类型。
NOTE:为 Ceph 守护进程创建用户,是因为 MON、OSD、MDS 等守护进程同样遵守 CephX 协议,但它们不能属于真正意义上的客户端。
Ceph 用户的密钥:相当于用户的密码,本质是一个唯一字符串。e.g. key: AQB3175c7fuQEBAAMIyROU5o2qrwEghuPwo68g==
Ceph 用户的授权(Capabilities, caps):即用户的权限,通常在创建用户的同时进行授权。只有在授权之后,用户才可以使用权限范围内的 MON、OSD、MDS 的功能,也可以通过授权限制用户对 Ceph 集群数据或命名空间的访问范围。以 client.admin 和 client.cinder 为例:
client.admin
key: AQB3175cZrKQEBAApE+rBBXNvbZs16GkpOjXhw==
# 允许访问 MDS
caps: [mds] allow *
# 允许访问 Mgr
caps: [mgr] allow *
# 允许访问 MON
caps: [mon] allow *
# 允许访问 OSD
caps: [osd] allow *
client.cinder
key: AQDVgMFcn/7sEhAA1sLOM+CTWkkGGJ47GRqInw==
# 在 MON 中具有引导 RBD 的权限
caps: [mon] profile rbd
# 在 OSD 中具有通过 RBD 访问 Pool volumes、vms、images 中的数据权限
caps: [osd] profile rbd pool=volumes, profile rbd pool=vms, profile rbd pool=images
授权类型:
- allow:在守护进程进行访问设置之前就已经具有特定权限,常见于管理员和守护进程用户。
- r:授予用户读的权限,读取集群各个组件(MON/OSD/MDS/CRUSH/PG)的状态,但是不能修改。
- w:授予用户写对象的权限,与 r 配合使用,修改集群的各个组件的状态,可以执行组件的各个动作指令。
- x:授予用户调用类方法的能力,仅仅和 ceph auth 操作相关。
- class-read:授予用户调用类读取方法的能力,是 x 的子集。
- class-write:授予用户调用类写入方法的能力,是 x 的子集。
- *:授予用户 rwx 权限。
- profile osd:授权用户以 OSD 身份连接到其它 OSD 或 MON,使得 OSD 能够处理副本心跳和状态汇报。
- profile mds:授权用户以 MDS 身份连接其它 MDS 或 MON。
- profile bootstrap-osd:授权用户引导 OSD 守护进程的能力,通常授予部署工具(e.g. ceph-deploy),让它们在引导 OSD 时就有增加密钥的权限了。
- profile bootstrap-mds:授权用户引导 MDS 守护进程的能力。同上。
NOTE:可见 Ceph 客户端不直接访问 Objects,而是必须要经过 OSD 守护进程的交互。
用户管理常规操作
Ceph 用户管理指令 auth
:
[root@ceph-node1 ~]# ceph auth --help
...
auth add <entity> {<caps> [<caps>...]} add auth info for <entity> from input file, or random key if no input is given, and/or any caps specified in the command
auth caps <entity> <caps> [<caps>...] update caps for <name> from caps specified in the command
auth export {<entity>} write keyring for requested entity, or master keyring if none given
auth get <entity> write keyring file with requested key
auth get-key <entity> display requested key
auth get-or-create <entity> {<caps> [<caps>...]} add auth info for <entity> from input file, or random key if no input given, and/or any caps specified in the command
auth get-or-create-key <entity> {<caps> [<caps>...]} get, or add, key for <name> from system/caps pairs specified in the command. If key already exists, any given caps must match the
existing caps for that key.
auth import auth import: read keyring file from -i <file>
auth ls list authentication state
auth print-key <entity> display requested key
auth print_key <entity> display requested key
auth rm <entity> remove all caps for <name>
获取指定用户的权限信息:
[root@ceph-node1 ~]# ceph auth get client.admin
exported keyring for client.admin
[client.admin]
key = AQB3175cZrKQEBAApE+rBBXNvbZs16GkpOjXhw==
caps mds = "allow *"
caps mgr = "allow *"
caps mon = "allow *"
caps osd = "allow *"
新建用户:
# 授权的格式为:`{守护进程类型} 'allow {权限}'`
# 创建 client.john 用户,并授权可读 MON、可读写 OSD Pool livepool
ceph auth add client.john mon 'allow r' osd 'allow rw pool=liverpool'
# 获取或创建 client.paul,若创建,则授权可读 MON,可读写 OSD Pool livepool
ceph auth get-or-create client.paul mon 'allow r' osd 'allow rw pool=liverpool'
# 获取或创建 client.george,若创建,则授权可读 MON,可读写 OSD Pool livepool,输出用户秘钥环文件
ceph auth get-or-create client.george mon 'allow r' osd 'allow rw pool=liverpool' -o george.keyring
ceph auth get-or-create-key client.ringo mon 'allow r' osd 'allow rw pool=liverpool' -o ringo.key
为指定用户授权:
# 格式:ceph auth caps USERTYPE.USERID {daemon} 'allow [r|w|x|*|...] [pool={pool-name}] [namespace={namespace-name}]' [{daemon} 'allow [r|w|x|*|...] [pool={pool-name}] [namespace={namespace-name}]']
ceph auth get client.john
ceph auth caps client.john mon 'allow r' osd 'allow rw pool=liverpool'
ceph auth caps client.paul mon 'allow rw' osd 'allow rwx pool=liverpool'
ceph auth caps client.brian-manager mon 'allow *' osd 'allow *'
删除用户:
ceph auth del {TYPE}.{ID}
CephX 认证系统
Ceph 提供了两种身份认证方式:None 和 CephX。前者表示客户端不需要通过密钥访问即可访问 Ceph 存储集群,显然这种方式是不被推荐的。所以我们一般会启用 CephX 认证系统,通过编辑 ceph.conf 开启:
[global]
...
# 表示存储集群(mon,osd,mds)相互之间需要通过 keyring 认证
auth_cluster_required = cephx
# 表示客户端(比如gateway)到存储集群(mon,osd,mds)需要通过 keyring 认证
auth_service_required = cephx
# 表示存储集群(mon,osd,mds)到客户端(e.g. gateway)需要通过 keyring 认证
auth_client_required = cephx
CephX 的本质是一种对称加密协议,加密算法为 AES,用于识别用户的身份、对用户在客户端上的操作进行认证,以此防止中间人攻击、数据篡改等网络安全问题。应用 CephX 的前提是创建一个用户,当我们使用上述指令创建一个用户时,MON 会将用户的密钥返回给客户端,同时自己也会保存一份副本。这样客户端和 MON 就共享了一份密钥。CephX 使用共享密钥的方式进行认证,客户端和 MON 集群都会持有一份用户密钥,它提供了一个相互认证的机制,MON 集群确定客户端持有用户密钥,而客户端确定 MON 集群持有用户密钥的的副本。
身份认证原理
- 用户通过客户端向 MON 发起请求。
- 客户端将用户名传递到 MON。
- MON 对用户名进行检查,若用户存在,则通过加密用户密钥生成一个 session key 并返回客户端。
- 客户端通过共享密钥解密 session key,只有拥有相同用户密钥环文件的客户端可以完成解密。
- 客户端得到 session key 后,客户端持有 session key 再次向 MON 发起请求
- MON 生成一个 ticket,同样使用用户密钥进行加密,然后发送给客户端。
- 客户端同样通过共享密钥解密得到 ticket。
- 往后,客户端持有 ticket 向 MON、OSD 发起请求。
这就是共享密钥认证的好处,客户端、MON、OSD、MDS 共同持有用户的密钥,只要客户端与 MON 完成验证之后,客户端就可以与任意服务进行交互。并且只要客户端拥有任意用户的密钥环文件,客户端就可以执行特定用户所具有权限的所有操作。当我们执行 ceph -s
时候,实际上执行的是 ceph -s --conf /etc/ceph/ceph.conf --name client.admin --keyring /etc/ceph/ceph.client.admin.keyring
。客户端会从下列默认路径查看 admin 用户的 keyring:
/etc/ceph/ceph.client.admin.keyring
/etc/ceph/ceph.keyring
/etc/ceph/keyring
/etc/ceph/keyring.bin
使用 ceph-authtool 进行密钥环管理
NOTE:密钥环文件 .keyring 是 Ceph 用户的载体,当客户端拥有了密钥环文件就相当于可以通过对应的用户来执行客户端操作。
MON、OSD、admin client 的初始密钥环文件:
- /var/lib/ceph/mon/ceph-$hostname/keyring
- /var/lib/ceph/osd/ceph-$hostname/keyring
- /etc/ceph/ceph.client.admin.keyring
指定密钥环(admin 用户)来执行集群操作:
ceph -n client.admin --keyring=/etc/ceph/ceph.client.admin.keyring health
rbd create -p rbd volume01 --size 1G --image-feature layering --conf /etc/ceph/ceph.conf --name client.admin --keyring /etc/ceph/ceph.client.admin.keyring
查看用户密钥:
ceph auth print-key {TYPE}.{ID}
将用户密钥导入到密钥环:
sudo ceph auth get client.admin -o /etc/ceph/ceph.client.admin.keyring
创建用户并生产密钥环文件:
sudo ceph-authtool -n client.ringo --cap osd 'allow rwx' --cap mon 'allow rwx' /etc/ceph/ceph.keyring
sudo ceph-authtool -C /etc/ceph/ceph.keyring -n client.ringo --cap osd 'allow rwx' --cap mon 'allow rwx' --gen-key
修改用户授权:
sudo ceph-authtool /etc/ceph/ceph.keyring -n client.ringo --cap osd 'allow rwx' --cap mon 'allow rwx'
从密钥环文件导入一个用户:
ceph auth import -i /path/to/keyring
将用户导出到一个密钥环文件:
sudo ceph auth get client.admin -o /etc/ceph/ceph.client.admin.keyring
注意事项
当 auth 配置为 cephx 时:
- 必须要密钥环文件来访问 Ceph 集群
- MON 启动是需要 /var/lib/ceph/mon/ceph-node1/ceph-mon.keyring 密钥环文件进行认证
- MON keyring 的内容被修改也不影响 MON 的启动,但会影响共享密钥认证
- OSD 启动需要正确的 keyring,否则无法启动,正确的 keyring 会被存在 MON 数据库中
- Client 访问集群和 OSD 一样,需要正确的 keyring 与存在 MON 数据库中对应的 keyring 相匹配