Ceph 生产环境搭建 | 第 14 天:Ceph 认证体系 cephx 与用户权限管理

第 14/20 天

在 Ceph 生产环境中,安全永远是不可妥协的一环。前 13 天我们完成了从系统准备到块存储、对象存储、文件系统、网络分离的部署,集群已经可以对外提供存储服务。然而,一个没有任何认证机制的存储集群,等同于在网络中”裸奔”——任何能访问到 6789 端口的客户端都能随意读写数据。今天我们就来彻底搞定 Ceph 的认证体系 cephx,从原理到实战,把集群的安全水位提升到生产可用水平。

Ceph 生产环境认证

一、架构与原理:cephx 认证体系深度解析

1.1 为什么需要 cephx

Ceph 作为一个分布式存储系统,其客户端(RBD、RGW、CephFS)、内部组件(MON、OSD、MDS)之间通过原生网络协议直接通信。如果没有认证层,攻击者只需要知道一个 MON 的 IP 地址,就能通过 ceph 命令直接访问集群数据,这对生产环境是致命的。

cephx 是 Ceph 自研的认证协议,本质类似 Kerberos 的共享密钥认证机制,但更轻量。它解决三个核心问题:

  • 身份验证:通信双方确认对方身份,防止中间人攻击
  • 数据完整性:通过对每个消息附加 HMAC 签名,防止传输过程被篡改
  • 权限控制:通过 capability(caps)机制,精确控制每个 key 能访问哪些资源、执行哪些操作

1.2 cephx 的工作机制

cephx 采用对称密钥体系,工作流程如下:

阶段 参与方 说明
密钥分发 管理员 → 客户端 管理员通过 ceph auth 创建用户并生成 keyring
握手认证 客户端 ↔ MON 客户端用共享密钥向 MON 证明身份,MON 返回 session key
会话建立 客户端 ↔ OSD/MDS 用 session key 建立加密会话,后续通信带 HMAC 签名
权限校验 OSD/MDS 每次操作根据 caps 判断是否允许执行

关键点在于:cephx 只认证不加密。它保证消息完整性和身份真实性,但消息内容本身是明文传输的。如果需要传输加密,需要配合 msgr2 的 secure 模式(第 13 天网络架构已有铺垫,今天会从认证角度再做加固)。

1.3 cephx 的实体与凭证模型

Ceph 的认证实体叫 client,每个 client 有一个名字,格式为 type.id:

  • client.admin —— 集群超级管理员
  • client.rbd —— 专供 RBD 块存储使用的客户端
  • client.rgw.instance —— RGW 守护进程
  • client.fs —— CephFS 客户端
  • mon. —— Monitor 集群级实体(注意 mon 用点号但无 id)
  • osd.0 —— 某个具体 OSD

每个实体的凭证存储在 keyring 文件中,格式类似:

💻 代码示例

[client.admin]

key = AQAT4VdmAAAAABAA9P…==

caps mds = "allow *"

caps mon = "allow *"

caps osd = "allow *"

caps 中的 * 是通配符,表示所有权限。生产环境绝不应该给业务客户端这样的权限。

1.4 权限粒度设计

Ceph 的 caps 分为三类:

  • mon caps:控制对 MON 的访问,常见 allow r(只读)、allow rw(读写)、allow *(完全控制,包括 auth 变更)
  • osd caps:控制对 OSD 的访问,粒度可到 pool 级别,如 allow rw pool=rbd-pool
  • mds caps:控制对 MDS 的访问,常用 allow * 或 allow r, allow rws path=/foo

合理设计 caps 是最小权限原则(Principle of Least Privilege)在 Ceph 中的落地方式。

二、部署实战:cephx 配置与用户权限管理

2.1 环境准备:检查 cephx 当前状态

Ceph Squid(v19)默认启用 cephx,但我们仍需确认。在管理节点上执行:

💻 代码示例

# 查看 cluster 配置中与认证相关的设置

ceph config get mon auth_cluster_required

ceph config get mon auth_service_required

ceph config get client auth_service_required

 

# 期望输出均为 cephx

# 如果输出 none,说明认证被禁用,生产环境必须修正

如果发现 none(通常发生在从老版本迁移的集群),需要强制开启:

💻 代码示例

# 开启 mon 之间认证

ceph config set mon auth_cluster_required cephx

# 开启 mon 对 client 的认证要求

ceph config set mon auth_service_required cephx

# 开启 client 对 mon 的认证要求

ceph config set client auth_service_required cephx

ceph config set client auth_client_required cephx

 

# 重启 monitor 后生效(生产环境逐节点滚动重启)

Ceph 认证流程

2.2 核心配置文件:ceph.conf 中的认证段

虽然 cephadm 部署的集群优先使用 ceph config set(集中配置库),但 ceph.conf 仍然是兜底配置。理解其结构对排查认证问题至关重要:

💻 代码示例

# /etc/ceph/ceph.conf 关键认证段

[global]

# 集群级认证要求

auth_cluster_required = cephx

auth_service_required = cephx

auth_client_required = cephx

 

# msgr2 协议(v2 messenger),与认证配合提升安全

ms_cluster_mode = secure crc

ms_service_mode = secure crc

ms_client_mode = secure crc

 

# 密钥轮换相关

auth_rx_token_timeout = 86400

 

[client.admin]

keyring = /etc/ceph/ceph.client.admin.keyring

参数详解:

参数 含义 推荐值
auth_cluster_required 集群内部组件互访时必须的认证 cephx
auth_service_required 服务端要求客户端提供的认证 cephx
auth_client_required 客户端要求服务端提供的认证 cephx
ms_cluster_mode 集群内部消息模式 secure crc(优先加密,兼容 CRC)
ms_service_mode 服务端向客户端开放的模式 secure crc
ms_client_mode 客户端使用的模式 secure crc
auth_rx_token_timeout 会话 token 有效期(秒) 86400(24h)

注意 secure crc 的顺序:secure 在前表示优先使用 msgr2 的 TLS-like 加密通道,crc 在后表示降级时使用 CRC32 完整性校验。生产环境建议直接用 secure,不要给降级留口子。

2.3 部署命令:创建和管理用户

查看所有认证实体:

💻 代码示例

# 列出所有 auth 实体

ceph auth list

 

# 查看具体用户详情(含 caps)

ceph auth get client.admin

 

# 以 OSD 视角查看 caps 摘要

ceph auth caps client.rbd mon 'allow r' osd 'allow rw pool=rbd-pool'

下面创建一个专供业务使用的 RBD 客户端,体现最小权限原则:

💻 代码示例

# 创建 client.rbd-app,仅对 rbd-pool 有读写权限

ceph auth get-or-create client.rbd-app

mon 'allow r'

osd 'allow rw pool=rbd-pool'

-o /etc/ceph/ceph.client.rbd-app.keyring

 

# 查看生成的 keyring 文件

cat /etc/ceph/ceph.client.rbd-app.keyring

# 输出形如:

# [client.rbd-app]

# key = AQBx…==

# caps mon = "allow r"

# caps osd = "allow rw pool=rbd-pool"

为 CephFS 客户端创建权限,限制只能访问特定子目录:

💻 代码示例

# 创建只能访问 /finance 子目录的客户端

ceph auth get-or-create client.finance-app

mon 'allow r'

mds 'allow r, allow rws path=/finance'

osd 'allow rw pool=cephfs_data, allow rw pool=cephfs_metadata'

-o /etc/ceph/ceph.client.finance-app.keyring

修改已有用户的 caps(注意:每次 set 都要写完整 caps,不会增量合并):

💻 代码示例

# 误操作:只写了一行 caps,原有 caps 会丢失

ceph auth caps client.rbd-app mon 'allow r'

# 正确做法:完整列出所有 caps

ceph auth caps client.rbd-app

mon 'allow r'

osd 'allow rw pool=rbd-pool'

 

# 验证修改结果

ceph auth get client.rbd-app

2.4 验证状态:用新用户测试权限

将 keyring 拷贝到客户端节点(这里以同一节点的另一个用户模拟):

💻 代码示例

# 拷贝 keyring 到客户端节点

scp /etc/ceph/ceph.client.rbd-app.keyring client-host:/etc/ceph/

 

# 在客户端节点测试只读权限(应成功)

ceph –user rbd-app -s

 

# 测试写入 rbd-pool(应成功)

rbd –id rbd-app create rbd-pool/test-image –size 1G

 

# 测试访问其他 pool(应被拒绝)

rbd –id rbd-app ls cephfs_data

# 期望报错:error 13: permission denied

如果权限不符合预期,用 ceph auth get 核对 caps 是否写全。

2.5 高级操作:密钥轮换与导入导出

生产环境密钥需要定期轮换。Ceph 支持为现有用户重新生成 key:

💻 代码示例

# 重置 client.rbd-app 的 key(旧 key 立即失效)

ceph auth get client.rbd-app

ceph auth get-or-create-key client.rbd-app mon 'allow r' osd 'allow rw pool=rbd-pool'

 

# 注意:重置 key 后,所有用旧 key 的客户端会立刻断连

# 生产流程应先部署新 key 到客户端,再做轮换

批量导入导出,用于集群迁移或灾备:

💻 代码示例

# 导出整个集群的 auth 到文件

ceph auth export > /tmp/cluster-auth-backup.txt

 

# 导入(在目标集群执行,会覆盖同名实体)

ceph auth import -i /tmp/cluster-auth-backup.txt

三、生产环境注意事项与踩坑提示

3.1 永远不要在生产用 client.admin 对外服务

最常见的事故:开发同学图省事,直接把 ceph.client.admin.keyring 拷给应用,应用一旦被入侵,攻击者就拥有了集群的全部控制权,包括删除 pool。正确做法是为每个业务单独建 client,caps 限定到具体 pool。

3.2 caps 修改是覆盖不是增量

这是最隐蔽的坑。ceph auth caps 命令执行时,会完全替换该用户的所有 caps,而不是在原有基础上追加。很多运维同学执行 ceph auth caps client.x mon 'allow r' 后,发现该用户的 osd caps 全部丢失,业务直接中断。安全做法:先 ceph auth get 查看现有 caps,再拼接完整命令执行。

3.3 msgr2 secure 模式与认证的协同

secure 模式使用 NSS 的 TLS 算法进行消息加密,与 cephx 是叠加而非替代关系。即使开启了 secure,cephx 的握手认证仍然执行。某些老版本客户端只支持 v1 messenger,如果集群强制 ms_client_mode = secure,老客户端会被拒绝连接。排查时用 ceph daemon mon.$(hostname -s) dump_historic_ops 查看握手失败原因。

3.4 keyring 文件权限必须最小化

💻 代码示例

# 错误:默认 644,同主机其他用户可读

ls -l /etc/ceph/ceph.client.admin.keyring

 

# 正确:仅 root 可读

chmod 600 /etc/ceph/ceph.client.admin.keyring

chown root:root /etc/ceph/ceph.client.admin.keyring

 

# 业务专用 keyring 可放 /var/lib/ceph/,chown 给业务账号

3.5 Monitor quorum 中 cephx 状态必须一致

如果集群的多个 MON 在 auth_cluster_required 上不一致,会出现部分 MON 拒绝 OSD 心跳的诡异现象。排查命令:

💻 代码示例

for m in $(ceph mon dump | awk '/^mon./{print $1}'); do

echo "=== $m ==="

ceph config get $m auth_cluster_required 2>/dev/null ||

ssh $m 'ceph config get mon auth_cluster_required'

done

3.6 删除用户前先确认无引用

💻 代码示例

# 删除用户前,先全局搜索其引用

grep -r "client.rbd-app" /etc/ceph /var/lib/ceph

 

# 再执行删除

ceph auth del client.rbd-app

直接删除一个正在被 RGW 使用的用户会导致 RGW 进程崩溃,需先停止 RGW 再删除。

四、常见问题 FAQ

Q1:开启 cephx 后,客户端报错 “authenticate timed out” 怎么办?

A:99% 的情况是 keyring 没拷贝到客户端,或者 --user 参数写错。先用 ceph auth get client.x 在管理节点确认 key 正确,再用 ceph --user x -k /path/to/keyring -s 显式指定 keyring 路径测试。如果还是超时,检查 ceph.conf 中 auth_client_required 是否与集群端一致。

Q2:为什么给业务客户端只配了 mon 的 allow r,却报错 “denied”?

A:MON 的 allow r 只允许查看集群状态。如果业务需要挂载 RBD 或创建 image,必须在 osd caps 里显式授予对应 pool 的 rw 权限。常见误区是只配 mon,忘了 osd。完整的 caps 三件套(mon/osd/mds)需要分别配置。

Q3:如何在不重启服务的情况下让新 caps 生效?

A:Ceph 的 caps 是动态读取的,ceph auth caps 执行后,MON 会立即把新 caps 推给相关 OSD/MDS。但已经建立的连接不会自动断开重连,旧连接继续使用旧 caps。要让旧连接也刷新,需要在客户端重建连接(卸载并重新挂载 RBD,或重启业务进程)。

五、总结

今天我们完成了 Ceph 认证体系 cephx 的完整搭建。核心要点:

  • cephx 提供身份验证 + 数据完整性,但不加密内容,加密由 msgr2 secure 模式叠加
  • 认证实体格式为 type.id,凭证存储在 keyring 文件
  • caps 分 mon/osd/mds 三类,粒度可到 pool 甚至子目录
  • 生产环境必须遵循最小权限原则,禁用 client.admin 对外
  • ceph auth caps 是覆盖操作,修改前先 get 当前值
  • 密钥文件权限 600,定期轮换,删除前先查引用

安全不是一次性的配置,而是持续的运维。建议把 cephx 用户清单纳入月度审计,清理不再使用的 client,轮换长期未变动的 key。

六、下期预告

第 15 天:Ceph 集群监控:Prometheus + Grafana + 内置仪表盘

明天我们将部署完整的监控体系,利用 Ceph 内置的 Prometheus exporter 和 Manager dashboard,配合 Grafana 构建可视化监控大屏,让集群健康状态一目了然,提前发现性能瓶颈和故障隐患。

七、系列目录

微信公众号二维码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发
头像 - 恒星
欢迎您留下宝贵的见解!
提交
头像 - 恒星

昵称

取消
昵称表情代码图片快捷回复

    暂无评论内容