Ceph用户管理

Ceph用户管理

本文档叙述了Ceph客户端的用户身份,以及Ceph存储集群的认证和授权。用户可以是个人或是系统角色(像应用程序),它们用Ceph客户端和Ceph服务器守护进程进行交互。

ceph-user-auth-2020-07-26

当Ceph开启用户认证时(默认开启),你必须指定一个用户名和密钥环来证明一个用户认证通过后才可以对Ceph进行相关操作。如果不指明用户名和密钥环,Ceph将会使用client.admin作为用户名,通过查找Ceph keyring设置搜索名称匹配的密钥环。

假如我们执行ceph health命令时没有指明任何用户名和密钥环文件存放地址。那么Ceph会自动的将其解析为如下命令并执行:

ceph -n client.admin --keyring=/etc/ceph/ceph.client.admin.keyring health

另外也可以用CEPH_ARGS环境变量来避免多次输入用户名和密钥。

概述

不论Ceph是从块设备、对象存储、文件系统、还是API中接收数据,最后都会将它们作为对象存储在Pool池中。

Ceph用户必须有权访问池才能读取和写入数据。此外,Ceph用户还应该具有执行权限才能使用Ceph的管理命令。下面的更多概念将会帮助了解Ceph用户管理。

用户

一个用户可以是一个个体,也可以是一个应用程序。通过创建用户,您可以控制哪些人(或什么人)可以访问您的Ceph存储集群以及Pool池中的数据。

Ceph有一个type的用户观念,这是出于用户管理的目的,类型总是client,并且以(.)分割标识不同的用户,以Type.ID这种形式表现。例如client.adminclient.user1

区分用户类型有助于区分客户端和其他用户的访问控制,更方便的进行用户监控和可追溯用户。

有时候Ceph的用户type类型会让你感到很迷惑,因为既可以指定Type来执行Ceph命令,也可以只使用用户名来进行访问。其实这取决于执行Ceph命令行时所使用的选项。当你使用--user或者 --id来指明一个用户时,此时client.user1可以省略为user1。如果使用--name-n来指定用户时,你就必须要加上Type类型了。

推荐使用--name-n提供Type类型和名称的方式进行用户访问。

授权

Ceph用能力(capabilities,caps)这个term术语来描述给某个已认证用户的授权。有一定权限后才可以使用mon、osd和元数据服务器等功能。能力也用于限制对一存储池内的数据、存储池内命名空间、或由应用标签所标识的一系列存储池的访问。

Ceph管理用户可以在创建或更新某一用户时赋予、更新他的能力。

能力的语法符合下面的形式:

{daemon-type} '{cap-spec}[, {cap-spec} ...]'

  • mon 监视器能力:监视器能力包括r 、 w 、 x 访问选项或 profile {name},例如:

    1
    2
    mon 'allow {access-spec} [network {network/prefix}]'
    mon 'profile {name}'

    {access-spec} 语法如下:

    * | all | [r][w][x]

    可选项 {network/prefix} 是个标准网络名和前缀长度( CIDR 表示法,如 10.3.0.0/16 )。如果设置了,此能力就仅限于从这个网络连接过来的客户端。

  • OSD 能力:OSD能力包括 r 、 w 、 x 、 class-read 、 class-write 访问选项和 profile {name} 。此外,OSD能力还支持存储池和命名空间的配置。

    1
    2
    osd 'allow {access-spec} [{match-spec}] [network {network/prefix}]'
    osd 'profile {name} [pool={pool-name} [namespace={namespace-name}]] [network {network/prefix}]'

    其中, {access-spec} 语法是下列之一:

    1
    2
    3
    * | all | [r][w][x] [class-read] [class-write]

    class {class name} [{method name}]

    可选的 {match-spec} 语法是下列之一:

    1
    2
    3
    pool={pool-name} [namespace={namespace-name}] [object_prefix {prefix}]

    [namespace={namespace-name}] tag {application} {key}={value}

    可选的 {network/prefix} 是一个标准网络名、且前缀长度遵循 CIDR 表示法(如 10.3.0.0/16 )。如果配置了,对此能力的使用就仅限于从这个网络连入的客户端。

  • 元数据服务器能力:对于管理员,设置 allow * 。对于其它的所有用户,如 CephFS 客户端,参考 CephFS 客户端用户

存储池

存储池是用户存储数据的逻辑分区。在Ceph部署中,经常创建存储池作为逻辑分区、用以归类相似的数据。例如,用Ceph作为Openstack的后端时,典型的部署通常会创建多个存储池,分别用于存储卷宗、映像、备份和虚拟机。

应用程序标签

可以将访问限定于指定存储池,正如其应用程序元数据所定义的那样。通配符 * 可以用于key参数、value参数或者二者全部。all* 同义。

命名空间

对象Object在Pool池中可以关联到命名空间,他是池中对象的逻辑组。用户对Pool池的访问可以与命名空间想关联,比如限制一个用户在命名空间内的读写权限。

命名空间主要适用于 librados 之上的应用程序,逻辑分组可减少新建存储池的必要。 Ceph 对象网关(从 luminous 起)就把命名空间用于各种元数据对象。

用 namespace 能力可以把访问权限局限于特定的 RADOS 命名空间。命名空间支持有限的通配;如果指定的命名空间最后一个字符是 * ,那就把访问权限授予所有以所提供参数打头的命名空间。

管理用户

用户管理功能赋予Ceph存储集群管理员直接从Ceph存储集群中间、更新和删除用户及能力。

挡在Ceph存储集群中创建或删除用户的时候,可能得把密钥文件分发到各客户端,一边加入他们的密钥环。详见密钥环管理

罗列显示用户

罗列显示集群内的用户,使用ceph auth ls命令。Ceph将罗列出集群内的所有用户。例如,在一个上节点示例集群中,ceph auth ls会显示类似如下的内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
installed auth entries:

osd.0
key: AQCvCbtToC6MDhAATtuT70Sl+DymPCfDSsyV4w==
caps: [mon] allow profile osd
caps: [osd] allow *
osd.1
key: AQC4CbtTCFJBChAAVq5spj0ff4eHZICxIOVZeA==
caps: [mon] allow profile osd
caps: [osd] allow *
client.admin
key: AQBHCbtT6APDHhAA5W00cBchwkQjh3dkKsyPjw==
caps: [mds] allow
caps: [mon] allow *
caps: [osd] allow *
client.bootstrap-mds
key: AQBICbtTOK9uGBAAdbe5zcIGHZL3T/u2g6EBww==
caps: [mon] allow profile bootstrap-mds
client.bootstrap-osd
key: AQBHCbtT4GxqORAADE5u7RkpCN/oo4e5W0uBtw==
caps: [mon] allow profile bootstrap-osd

Type.ID 这种表示方法对于用户来说,如osd.0标示用户类型是osd,其ID是0;client.admin表示用户类型是client,ID是admin(即默认的client.admin)用户。还有,每条都有一行 key: 条目、和一或多行 caps: 条目。

你可以给 ceph auth ls加上-o {filename}选项,把输出保存到一个文件。

获取用户

想要获取一个用户的key和能力,执行下面的命令:

ceph auth get {Type.ID}

ceph auth get client.admin

得到如下结果:

1
2
3
4
5
6
7
8
[ceph@serverc ~]$ ceph auth get client.admin
exported keyring for client.admin
[client.admin]
key = AQDtYxJf2UeZHRAAZmPGLhLr3kLzHXh3Glba6g==
caps mds = "allow *"
caps mgr = "allow *"
caps mon = "allow *"
caps osd = "allow *"

如果想要保存输出结果到文本文件中,可以使用-o 选项,和上面的一样。

ceph auth export {Type.ID} 使用export命令等价于get。它会把auid显示到终端上。

新增用户

添加一个用户,让其拥有密钥和应该有的能力。

用户的密钥是用户可以通过Ceph存储集群进行身份认证。可以对用户的能力进行授予,使他们拥有在Ceph监视器mon,Ceph OSD,或者Ceph元数据mds上的读取、写入或执行权限。

有下面几种方式添加用户:

  • ceph auth add:这种添加用户的方式是最规范的方法。它将创建用户,生成密钥并添加任何指定的能力。
  • ceph get-or-create-key:这个命令添加用户后并返回用户密钥环文件信息。这对于需要密钥的客户端非常方便。如果用户已经存在,那么会返回密钥文件格式,并不会重新生成一个新的用户去替换重名用户。使用-o选项将密钥环保存在本地文件。
  • ceph auth get-or-create-key:这种方式创建用户后会输出到控制台密钥,仅仅是密钥而不包括更多的钥匙环格式。
  • 如果需要批量新建用户,可以尝试使用密钥环批量创建用户

当创建了用户之后,可能没有给用户赋予任何的能力。一个用户如果没有任何能力就是一个毫无卵用的用户,因为客户端无法从监视器mon中获得任何集群信息。当然,你可以先创建一个没有能力的用户,之后再使用ceph auth caps命令赋予能力给用户。

标准的用户至少要用用Ceph监视器mon的可读的能力,并且在Ceph osd上具有读写的能力。此外,用户的OSD权限通常会限定至一个特定的Pool池中。

1
2
3
4
5
6
ceph auth add client.yeefire mon 'allow r' osd 'allow rw pool=rbd'
ceph auth get-or-create client.paul mon 'allow r' osd 'allow rw pool=liverpool'
ceph auth get-or-create client.yeefire mon 'allow r' osd 'allow * pool=rbd namespace=system' -o ceph.client.yeefire.keyring
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

如果你给用户分配了访问 OSD 的能力,但是没有限制他可以访问哪些存储池,那么他可以访问集群内的所有存储池!最好对用户能力再进行namespace上的限制,以达到最小能力。

更改用户能力

ceph auth caps 命令可以用来修改指定用户的能力。设置新能力时会覆盖当前能力。

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}]']

1
2
3
4
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}命令:

ceph auth del client.yeefire

查看用户密钥

要想查看用户的密钥,可以通过以下方式进行获取:

1
2
3
ceph auth print-key client.yeefire
ceph auth get-key client.yeefire
ceph auth get-or-create-key client.yeefire -o key

他们都可以使用-o选项将标准输出内容输出到文件中。

使用auth print-keyauth get-key auth get-or-create-key返回的结果基本都是一样的。只不过 auth get-or-create-key在输出key的时候会在行末尾添加一个换行符。

导入用户

通过ceph auth getceph auth export导出的用户文件可以通过ceph auth import导入的方式恢复用户及他们的能力。

要导入一个或多个用户,可以用 ceph auth import 命令,并指定一个密钥环:

ceph auth import -i /path/to/all.keyring

Ceph 存储集群会新增用户、他们的密钥以及其能力,也会更新已有的用户们、他们的密钥和他们的能力。

管理密钥环

当你访问Ceph使,你的客户端会在一些目录下寻找当前用户的keyring。Ceph默认情况下会使用下面四个路径来搜索与当前用户对应的密钥环。

  • /etc/ceph/$cluster.$name.keyring
  • /etc/ceph/$cluster.keyring
  • /etc/ceph/keyring
  • /etc/ceph/keyring.bin

$cluster是你的集群名称,如client$name是你的用户类型和用户ID,如client.admin。因此合起来的话是/etc/ceph/ceph.client.admin.keyring

用户管理部分详细介绍了如何直接在Ceph存储群集中列出,获取,添加,修改和删除用户。Ceph还提供了ceph-authtool实用程序,使您可以从Ceph客户端管理密钥环。

把用户加入到密钥环

当你在 Ceph 存储集群中创建用户后,你可以用获取用户里面的方法获取此用户、及其密钥、能力,并存入一个密钥环文件。

当你希望每个密钥环中只有一个用户时,使用ceph auth get命令与-o选项搭配,将该用户的钥匙环保存在文件中。

ceph auth get client.yeefire -o ceph.client.admin.keyring

当你想把其他用户的钥匙环导入到一个目标钥匙环里,为了方便import的话,可以使用ceph-authtool工具进行导入:

ceph-authtool ceph.client.yeefire.keyring --import-keyring ceph.client.yeefire.sirius.keyring

通过钥匙环创建用户

Ceph提供了创建用户的功能,可以直接在集群中创建用户。但是如果要是批量新建用户,先在密钥环上创建用户之后再导入到Ceph集群中也是一个不错的选择!

可以将用户导入Ceph存储集群。例如:

ceph-authtool -C ceph.42team.keyring -n client.42team.admin --cap mon 'allow *' --cap osd 'allow *' --cap mgr 'allow *' --gen-key

可以继续创建新的用户,然后导入到ceph.42team.keyring密钥环文件中:

ceph-authtool -n client.42team.sirius --cap mon 'allow r' --cap osd 'allow rw pool=42team' ceph.42team.keyring -g

现在查看ceph.42team.keyring密钥环文件中的内容:

1
2
3
4
5
6
7
8
9
10
[ceph@serverc ~]$ cat ceph.42team.keyring
[client.42team.admin]
key = AQCmVB1fTffGIBAAoBiwyBPEgggX+UtPzsnFoQ==
caps mgr = "allow *"
caps mon = "allow *"
caps osd = "allow *"
[client.42team.sirius]
key = AQDLVx1fxsuyOBAAvLtLw6vqnAqTLu5uND+LgQ==
caps mon = "allow r"
caps osd = "allow rw pool=42team"

将密钥环文件导入到Ceph中创建用户:

ceph auth import -i ceph.42team.keyring

导入完成后使用ceph auth ls命令进行验证:

1
2
3
4
5
6
7
8
9
10
11
12
[ceph@serverc ~]$ ceph auth ls | grep client.42team -A5
installed auth entries:

client.42team.admin
key: AQCmVB1fTffGIBAAoBiwyBPEgggX+UtPzsnFoQ==
caps: [mgr] allow *
caps: [mon] allow *
caps: [osd] allow *
client.42team.sirius
key: AQDLVx1fxsuyOBAAvLtLw6vqnAqTLu5uND+LgQ==
caps: [mon] allow r
caps: [osd] allow rw pool=42team

成功将2个用户导入到Ceph集群。

接下来将钥匙环放置到/etc/ceph/ceph.keyring

cp ceph.42team.keyring /etc/ceph/ceph.keyring

尝试使用client.42team.admin用户去执行Ceof osd命令:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[ceph@serverc ~]$ ceph osd tree -n client.42team.admin
ID CLASS WEIGHT TYPE NAME STATUS REWEIGHT PRI-AFF
-1 0.16644 root default
-3 0.05548 host serverc
0 hdd 0.01849 osd.0 up 1.00000 1.00000
3 hdd 0.01849 osd.3 up 1.00000 1.00000
8 hdd 0.01849 osd.8 up 1.00000 1.00000
-7 0.05548 host serverd
2 hdd 0.01849 osd.2 up 1.00000 1.00000
4 hdd 0.01849 osd.4 up 1.00000 1.00000
6 hdd 0.01849 osd.6 up 1.00000 1.00000
-5 0.05548 host servere
1 hdd 0.01849 osd.1 up 1.00000 1.00000
5 hdd 0.01849 osd.5 up 1.00000 1.00000
7 hdd 0.01849 osd.7 up 1.00000 1.00000

修改密钥环中用户能力

要修改密钥环中用户的能力,请指定密钥环,然后再指定用户,修改用户的能力不会重置用户的key

ceph-authtool ceph.42team.keyring -n client.42team.sirius --cap mon 'allow r'

撤销client.42team.sirius用户对osd的所有权限,目前该用户仅可以查看mon信息。

1
2
3
[client.42team.sirius]
key = AQDLVx1fxsuyOBAAvLtLw6vqnAqTLu5uND+LgQ==
caps mon = "allow r"

要将刚刚在密钥环上的修改应用到ceph集群,必须将密钥环的用户更新到Ceph集群中的用户条目。

ceph auth import -i ceph.42team.keyring

成功导入后对修改进行验证:

ceph auth ls | grep ^client.42team -A5

1
2
3
4
5
6
7
8
9
10
11
[ceph@serverc ~]$ ceph auth ls | grep ^client.42team -A5
installed auth entries:

client.42team.admin
key: AQCmVB1fTffGIBAAoBiwyBPEgggX+UtPzsnFoQ==
caps: [mgr] allow *
caps: [mon] allow *
caps: [osd] allow *
client.42team.sirius
key: AQDLVx1fxsuyOBAAvLtLw6vqnAqTLu5uND+LgQ==
caps: [mon] allow r

对导入用户不了解可以参见导入用户

不想使用ceph-authtool工具或者不想以密钥环方式添加用户可以参见更改用户能力新增用户

身份验证命令行

Ceph命令行几乎全局支持用户名和密钥的下列用法:

  • --id | --user:Ceph 用一个类型和 ID( 如 TYPE.ID 或 client.admin 、 client.user1 )来标识用户, id 、 name 、和 -n 选项可用于指定用户名(如 admin 、 user1 、 foo 等)的 ID 部分,你可以用 –id 指定用户并忽略类型,例如可用下列命令指定 client.foo 用户:
    1
    2
    ceph --id foo --keyring /path/to/keyring health
    ceph --user foo --keyring /path/to/keyring health
  • --name | -n:Ceph 用一个类型和 ID (如 TYPE.ID 或 client.admin 、 client.user1 )来标识用户, –name 和 -n 选项可用于指定完整的用户名,但必须指定用户类型(一般是 client )和用户 ID ,例如:
    1
    2
    ceph --name client.foo --keyring /path/to/keyring health
    ceph -n client.foo --keyring /path/to/keyring health
  • --keyring:包含一或多个用户名、密钥的密钥环路径。 --secret 选项提供了相同功能,但它不能用于 RADOS 网关,其 --secret 另有用途。你可以用 ceph auth get-or-create 获取密钥环并保存在本地,然后您就可以改用其他用户而无需重指定密钥环路径了。
    ceph --id 42team.admin --keyring /etc/ceph/ceph.keyring health

Ceph认证的局限性

cephx协议提供Ceph客户端和服务器间的相互认证,并没打算认证人类用户或者应用程序。如果有访问控制需求,那必须用另外一种机制,他对于前端用户访问Ceph对象存储可能是特定的,其任务是确保只有此机器上可接受的用户和程序才能访问Ceph的对象存储。

用于认证Ceph客户端和服务器的密钥通常以纯文本存储在权限合适的文件里,并保存于可信主机上。

密钥存储为纯文本文件有安全缺陷,但很难避免,它给了 Ceph 可用的基本认证方法,设置 Ceph 时应该注意这些缺陷。

尤其是任意用户、特别是移动机器不应该和 Ceph 直接交互,因为这种用法要求把明文认证密钥存储在不安全的机器上,这些机器的丢失、或盗用将泄露可访问 Ceph 集群的密钥。

相比于允许潜在的欠安全机器直接访问 Ceph 对象存储,应该要求用户先登录安全有保障的可信机器,这台可信机器会给人们存储明文密钥。未来的 Ceph 版本也许会更彻底地解决这些特殊认证问题。

当前,没有任何 Ceph 认证协议保证传送中消息的私密性。所以,即使物理线路窃听者不能创建用户或修改它们,但可以听到、并理解客户端和服务器间发送过的所有数据。此外, Ceph 没有可加密用户数据的选项,当然,用户可以手动加密、然后把它们存在对象库里,但 Ceph 没有自己加密对象的功能。在 Ceph 里存储敏感数据的用户应该考虑存入 Ceph 集群前先加密。