5 Ceph X 认证机制
Ceph 使用 cephx 协议对客户端进行身份认证
客户端访问 Ceph 集群需要通过认证机制
在生产环境中一般不使用 admin 账户,客户端都是使用普通用户
5.1 授权流程
每个 mon 节点都可以对客户端进行身份认证并分发秘钥,因此多个 mon 节点就不存在单点故障和认证性能瓶颈
mon 节点会返回用于身份认证的数据结构给客户端,其中包含获取 ceph 服务时用到的 session key, session key 通过客户端秘钥进行加密,秘钥是在客户端提前配置好的 , /etc/ceph/ceph.client.admin.keyring
客户端使用 session key 向 mon 请求所需要的服务,mon 向客户端提供一个 tiket,用于向实际处理数据的 OSD 等服务验证客户端身份,MON 和 OSD 共享同一个 secret,因此 OSD 会信任所有 MON 发放的 tiket,tiket 存在有效期
注意:
CephX 身份验证功能仅限制在 Ceph 的各组件之间,不能扩展到其他非 ceph 组件
Ceph 只负责认证授权,不能解决数据传输的加密问题
-
客户端访问之前先加载
/etc/ceph/ceph.conf
文件,该文件就有对应的 mon 服务器地址,拿到 mon 发送请求认证 -
mon 接收到客户端请求认证之后生成 session key 然后加密返回给客户端
-
客户端解密得到 session key 申请 tiket
-
mon 验证 session key 是否正确然后返回 tiket
-
客户端使用 tiket 访问 OSD
-
OSD 验证 tiket 并返回数据
5.2 访问流程
无论 ceph 客户端是哪种类型,例如块设备、对象存储、文件系统,ceph 都会在存储池中将所有数据存储为对象:
ceph 用户需要拥有存储池访问权限,才能读取和写入数据
ceph 用户必须拥有执行权限才能使用 ceph 的管理命令
5.3 ceph 用户
用户是指个人(ceph 管理者)或系统参与者(MON/OSD/MDS)。通过创建用户,可以控制用户或哪个参与者能够访问 ceph 存储集群、以及可访问的存储池及存储池中的数据。
ceph 支持多种类型的用户,但可管理的用户都属于 client 类型区分用户类型的原因在于,MON/OSD/MDS 等系统组件特使用 cephx 协议,但是它们为非
客户端。 通过点号来分割用户类型和用户名,格式为 TYPE.ID,例如 client.admin。
通常我们创建的都是 client 类型,一般提供给虚拟机和 K8S 容器使用
root@ceph-node1:~# cat /etc/ceph/ceph.client.admin.keyring
[client.admin]
key = AQC/hB9hmcMEHBAAbRGwWgJQ+OXacHEPvTM6BA==
caps mds = "allow *"
caps mgr = "allow *"
caps mon = "allow *"
caps osd = "allow *"
5.3.1 列出指定用户信息
通过 get 列出指定的某个账号
# 获取 client.admin 用户信息
root@ceph-node1:~# ceph auth get client.admin
[client.admin]
key = AQC/hB9hmcMEHBAAbRGwWgJQ+OXacHEPvTM6BA==
caps mds = "allow *"
caps mgr = "allow *"
caps mon = "allow *"
caps osd = "allow *"
exported keyring for client.admin
注意:TYPE.ID
表示法
针对用户采用 TYPE.ID 表示法,例如 osd.0 指定是 osd 类并且 ID 为 0 的用户(节点), client.admin 是 client 类型的用户,其 ID 为 admin,另请注意,每个项包含一个 key=xxxx 项,以及一个或多个 caps 项。 可以结合使用 -o 文件名选项和 ceph auth list 将输出保存到某个文件。
5.3.2 列出所有用户信息
通过下面命令列出 ceph 集群默认所有用户
root@ceph-node1:~# ceph auth list
mds.ceph-mgr1
key: AQAcpCdhtVxbAxAAfk5RVgiXmT64SfKoOhj5+Q==
caps: [mds] allow
caps: [mon] allow profile mds
caps: [osd] allow rwx
osd.0
key: AQDdxB9hOsGALBAA7BbstuNpDKsgUBEt24NtLg==
caps: [mgr] allow profile osd
caps: [mon] allow profile osd
caps: [osd] allow *
........省略........
5.4 Ceph 授权和使用
ceph 基于使能/能力(Capabilities,简称 caps )来描述用户可针对 MON/OSD 或 MDS 使用的授权范围或级别。
通用的语法格式:daemon-type 'allow caps' [...]
能力一览表:
r:向用户授予读取权限。访问监视器(mon)以检索 CRUSH 运行图时需具有此能力。
w:向用户授予针对对象的写入权限。 一般是针对客户端对 OSD 数据的写入问题
x:授予用户调用类方法(包括读取和写入)的能力,以及在监视器中执行 auth 操作的能 力。
*:授予用户对特定守护进程/存储池的读取、写入和执行权限,以及执行管理命令的能力
class-read:授予用户调用类读取方法的能力,属于是 x 能力的子集。
class-write:授予用户调用类写入方法的能力,属于是 x 能力的子集。
profile osd:授予用户以某个 OSD 身份连接到其他 OSD 或监视器的权限。授予 OSD 权 限,使 OSD 能够处理复制检测信号流量和状态报告(获取 OSD 的状态信息)。
profile mds:授予用户以某个 MDS 身份连接到其他 MDS 或监视器的权限。
profile bootstrap-osd:授予用户引导 OSD 的权限(初始化 OSD 并将 OSD 加入 ceph 集群), 授权给部署工具,使其在引导 OSD 时有权添加密钥。
profile bootstrap-mds:授予用户引导元数据服务器的权限,授权部署工具权限,使其在引 导元数据服务器时有权添加密钥。
MON 能力:
包括 r/w/x 和 allow profile cap(ceph 的运行图)
例如:
mon 'allow rwx'
mon 'allow profile osd'
OSD 能力:
包括 r、w、x、class-read、class-write(类读取))和 profile osd(类写入),另外 OSD 能力还允许进行存储池和名称空间设置。
osd 'allow capability' [pool=poolname] [namespace=namespace-name]
MDS 能力:
只需要 allow 或空都表示允许。
mds 'allow'
5.5 Ceph 用户管理
用户管理功能可让 Ceph 集群管理员能够直接在 Ceph 集群中创建、更新和删除用户。在 Ceph 集群中创建或删除用户时,可能需要将密钥分发到客户端,以便将密钥添加到密 钥环文件中 /etc/ceph/ceph.client.admin.keyring
,此文件中可以包含一个或者多个用户认证信息,凡是拥有此文件的节点,将具备访问 ceph 的权限,而且可以使用其中任何一个账户的权限,此文件类似于 linux 系统的中的/etc/passwd 文件。
5.5.1 用户管理
添加一个用户会创建用户名 (TYPE.ID)、机密密钥,以及包含在命令中用于创建该用户的所有能力,用户可使用其密钥向 Ceph 存储集群进行身份验证。用户的能力授予该用户在 Ceph monitor (mon)、Ceph OSD (osd) 或 Ceph 元数据服务器 (mds) 上进行读取、写入或执行的能力,可以使用以下几个命令来添加用户:
5.5.1.1 创建用户
此命令是添加用户的规范方法。它会创建用户、生成密钥,并添加所有指定的能力。
# 创建用户,并且这个用户只能对 mypool 有读写执行请求,其他 pool 不能访问
root@ceph-deploy:~# ceph auth add client.tom mon 'allow r' osd 'allow rwx pool=mypool'
added key for client.tom
# ceph auth add client.tom :创建 tom 用户类型为 client
# mon 'allow r' :对 mon 只读权限
# osd 'allow rwx pool=mypool' :对 osd 读写执行权限,并且指定了存储池为 mypool
指定查看 tom 用户信息
root@ceph-deploy:~# ceph auth get client.tom
[client.tom]
# 这个 key 是 ceph 自己生成
key = AQCfQCxhOW62GxAAL+cHDePUBA3/Xph6HD+qRw==
caps mon = "allow r"
caps osd = "allow rwx pool=mypool"
exported keyring for client.tom
但是这个用户文件我们在后续使用需要单独保存和导出
5.5.1.2 创建用户并返回 key
ceph auth get-or-create
此命令是创建用户并仅返回用户密钥,对于只需要密钥的客户端(例如 libvirt),此命令非常有用。如果该用户已存在,此命令只返回密钥。您可以使用 -o 文件名选项将输出保存到某个文件。
创建客户端用户时,可以创建不具有能力的用户。不具有能力的用户可以进行身份验证,但不能执行其他操作,此类客户端无法从监视器检索集群地图,但是,如果希望稍后再添加能力,可以使用 ceph auth caps 命令创建一个不具有能力的用户。
典型的用户至少对 Ceph monitor 具有读取功能,并对 Ceph OSD 具有读取和写入功能。此外,用户的 OSD 权限通常限制为只能访问特定的存储池。
# 通过 ceph auth get-or-create 命令创建用户并返回 key
root@ceph-deploy:~# ceph auth get-or-create client.jack mon 'allow r' osd 'allow rwx pool=mypool'
[client.jack]
key = AQAIRSxhmNiwKhAAOMV20tJYMkPG9VtFrymR+w== # 返回的 key 信息
# client.jack:创建一个 client 类型的 jack 用户
# mon 'allow r' :对 mon 只读权限
# osd 'allow rwx pool=mypool':对 osd 有读写执行,并且只对 mypool 这个存储池有该权限
5.5.1.3 获取单个指定用户的 key 信息
通过 ceph auth print-key
获取指定用户的 key 信息
root@ceph-deploy:~# ceph auth print-key client.jack
AQAIRSxhmNiwKhAAOMV20tJYMkPG9VtFrymR+w==
5.5.1.4 修改用户权限
使用 ceph auth caps
命令可以指定用户以及更改该用户的能力,设置新能力会完全覆盖当前的能力,因此要加上之前的用户已经拥有的能和新的能力,通过修改用户权限并不会涉及到修改该用户的 key
如果看当前能力,可以运行 ceph auth get USERTYPE.USERID
,
如果要添加能力,使用以下格式时还需要指定现有能力:
比如这个用户之前的权限太小了或者太大了,这里我想给他增加权限
范例:
# 查看 jack 用户权限
root@ceph-deploy:~# ceph auth get client.jack
[client.jack]
key = AQAIRSxhmNiwKhAAOMV20tJYMkPG9VtFrymR+w==
caps mon = "allow r"
caps osd = "allow rwx pool=mypool" # 修改之前 jack 用户对 mypool 有 rwx 权限
exported keyring for client.jack
# 通过 ceph auth caps 修改用户权限
root@ceph-deploy:~# ceph auth caps client.jack mon 'allow r' osd 'allow rw pool=mypool'
updated caps for client.jack
# 查看修改后的 jack 用户
root@ceph-deploy:~# ceph auth get client.jack
[client.jack]
key = AQAIRSxhmNiwKhAAOMV20tJYMkPG9VtFrymR+w== # 并且 Key 没有变化
caps mon = "allow r"
caps osd = "allow rw pool=mypool" # 修改后该用户对 mypool 只有 rw 权限
exported keyring for client.jack
5.5.1.5 删除用户
要删除用户使用 ceph auth del TYPE.ID
,其中 TYPE 是 client、osd、mon 或 mds 之一, ID 是用户名或守护进程的 ID。
# 删除 Jack
root@ceph-deploy:~# ceph auth del client.jack
updated
# 提示错误没有找到 jack 的 key
root@ceph-deploy:~# ceph auth get client.jack
Error ENOENT: failed to find client.jack in keyring
5.6 秘钥环管理
ceph 的秘钥环是一个保存了 secrets、keys、certificates 并且能够让客户端通认证访问 ceph 的 keyring file(集合文件),一个 keyring file 可以保存一个或者多个认证信息,每一个 key 都有一个实体名称加权限,类型为:
{client、mon、mds、osd}.name
如下图红框中的文件都是密钥环文件格式如下:
集群名称.类型.账号名.keyring
当客户端访问 ceph 集群时,ceph 会使用以下四个密钥环文件预设置密钥环设置:
/etc/ceph/<$cluster name>.<user $type>.<user $id>.keyring # 保存单个用户的 keyring
/etc/ceph/cluster.keyring # 保存多个用户的 keyring
/etc/ceph/keyring # 未定义集群名称的多个用户的 keyring
/etc/ceph/keyring.bin # 编译后的二进制文件
5.6.1 通过秘钥环文件备份与恢复用户
如果我们的用户被删除了,我们可以从这个秘钥环文件中将用户还原,在还原之后权限不变,主最要的是 key 也不变
因为在 K8S 中容器可以能有上百个,而且都会对同一个用户的 key 进行认证,如果我们把这个用户删了那这些容器则不能正常访问 ceph 集群
使用 ceph auth add 等命令添加的用户还需要额外使用 ceph-authtool 命令为其创建用户秘钥环文件。
创建 keyring 文件命令格式:
ceph-authtool --create-keyring FILE
5.6.1.1 导出用户认证信息至 keyring 文件
将用户信息导出至 keyring 文件,对用户信息进行备份。
范例如下:
# 创建 user1 用户,对 mon 只读、对 mypool 全部权限
root@ceph-deploy:~# ceph auth get-or-create client.user1 mon 'allow r' osd 'allow * pool=mypool'
[client.user1]
key = AQANTixhQiF5NhAA5/U3C7AZLQGIJaBtRHzvbQ==
# 创建 keyring 文件,并且这个文件名要和密钥环文件的格式保持一致
root@ceph-deploy:~# ceph-authtool --create-keyring ceph.client.user1.keyring
creating ceph.client.user1.keyring
# 通过 -o 导出 keyring 至指定文件
root@ceph-deploy:~# ceph auth get client.user1 -o ceph.client.user1.keyring
exported keyring for client.user1
# 查看 ceph.client.user1.keyring 文件 key 已经导出
root@ceph-deploy:~# cat ceph.client.user1.keyring
[client.user1]
key = AQANTixhQiF5NhAA5/U3C7AZLQGIJaBtRHzvbQ==
caps mon = "allow r"
caps osd = "allow * pool=mypool"
在创建包含单个用户的密钥环时,通常建议使用 ceph 集群名称、用户类型和用户名及 keyring 来 命 名 , 并 将其保存在 /etc/ceph 目录中。 例如为 client.user1 用户创建 ceph.client.user1.keyring。
5.6.1.2 从 keyring 文件恢复用户认证信息
可以使用 ceph auth import -i
指定 keyring 文件并导入到 ceph,其实就是起到用户备份和恢复的目的:
范例如下:
# 验证用户的认证文件
root@ceph-deploy:~# cat ceph.client.user1.keyring
[client.user1]
key = AQANTixhQiF5NhAA5/U3C7AZLQGIJaBtRHzvbQ==
caps mon = "allow r"
caps osd = "allow * pool=mypool"
# 误操作删除 user1 用户
root@ceph-deploy:~# ceph auth del client.user1
updated
# 验证 user1 用户确实被删除
root@ceph-deploy:~# ceph auth get client.user1
Error ENOENT: failed to find client.user1 in keyring
# 导入 user1 的 keyring 文件
root@ceph-deploy:~# ceph auth import -i ceph.client.user1.keyring
imported keyring
# 验证 user1 用户恢复成功
root@ceph-deploy:~# ceph auth get client.user1
[client.user1]
key = AQANTixhQiF5NhAA5/U3C7AZLQGIJaBtRHzvbQ== # 并且 key 恢复同步成功
caps mon = "allow r"
caps osd = "allow * pool=mypool"
exported keyring for client.user1
5.6.2 秘钥环文件多用户
一个 keyring 文件中可以包含多个不同用户的认证文件。 一般情况下我们都是放一个用户单独放一个 keyring 文件
5.6.2.1 将多用户到处至秘钥环
范例如下:
# 先创建 keyring 文件:
root@ceph-deploy:~# ceph-authtool --create-keyring ceph.client.users.keyring
creating ceph.client.users.keyring
# 把指定的 admin 用户的 keyring 文件内容导入到 users 的 keyring 文件:
root@ceph-deploy:~# ceph-authtool ./ceph.client.users.keyring --import-keyring /home/ceph/ceph-cluster/ceph.client.admin.keyring
importing contents of /home/ceph/cepsh-cluster/ceph.client.admin.keyring into ./ceph.client.users.keyring
# /home/ceph/ceph-cluster/ceph.client.admin.keyring 为 admin 用户的 keyring 文件路径
# 验证 users.keyring 文件已经将 admin 导入
root@ceph-deploy:~# ceph-authtool -l ceph.client.users.keyring
[client.admin]
key = AQC/hB9hmcMEHBAAbRGwWgJQ+OXacHEPvTM6BA==
caps mds = "allow *"
caps mgr = "allow *"
caps mon = "allow *"
caps osd = "allow *"
# 导入 user1 的 keyring 文件至 users 中
root@ceph-deploy:~# ceph-authtool ./ceph.client.users.keyring --import-keyring ceph.client.user1.keyring
importing contents of ceph.client.user1.keyring into ./ceph.client.users.keyring
# 验证 admin 和 user1 已经导入
root@ceph-deploy:~# ceph-authtool -l ceph.client.users.keyring
[client.admin]
key = AQC/hB9hmcMEHBAAbRGwWgJQ+OXacHEPvTM6BA==
caps mds = "allow *"
caps mgr = "allow *"
caps mon = "allow *"
caps osd = "allow *"
[client.user1]
key = AQANTixhQiF5NhAA5/U3C7AZLQGIJaBtRHzvbQ==
caps mon = "allow r"
caps osd = "allow * pool=mypool"