管理 RabbitMQ 用户与权限:命令行指南
掌握使用 `rabbitmqctl` 命令进行 RabbitMQ 用户和权限管理的技巧。本指南提供逐步说明,涵盖创建新用户、通过标签分配管理员或应用程序角色、设置精细的虚拟主机权限(读/写/配置)以及安全地撤销访问权限,确保通过命令行实现可控管理。
管理 RabbitMQ 用户与权限:命令行指南
RabbitMQ 的权限配置很容易接近正确,但仍有细节需要注意。用户可能存在却无法发布消息;用户可能拥有 management 标签,却无法访问应用程序的虚拟主机;一个宽泛的正则表达式可能意外地允许某个服务创建它本应只消费的队列。大多数权限问题源于混淆了三个独立的概念:用户、标签和虚拟主机权限。
本指南使用 rabbitmqctl 来介绍常见的用户管理工作流程:创建用户、分配标签、设置虚拟主机权限、验证访问、轮换密码以及安全地移除访问权限。
前提条件
在开始之前,请确保您已具备以下条件:
- 已安装 RabbitMQ 服务器: 代理必须正在运行。
rabbitmqctl访问权限: 您需要对节点或集群拥有管理访问权限。命令通常在 RabbitMQ 节点上运行,但在环境配置允许的情况下,也可以远程使用 CLI。- 正确的虚拟主机名称: 权限是按虚拟主机划分的。
/、/prod和prod不可互换。
使用 rabbitmqctl 管理用户
rabbitmqctl 工具使用 user_* 系列命令来处理所有与用户相关的操作。理解 RabbitMQ 用户与操作系统用户是不同的,这一点至关重要。
1. 列出现有用户
要查看当前谁有权访问代理,请使用 list_users 命令:
rabbitmqctl list_users
示例输出:
Listing users ...
user: guest tags: [administrator]
user: app_prod tags: [policymaker]
2. 创建新用户
在设置新的服务账户或管理员时,您必须创建用户并分配初始密码。
要创建一个名为 api_user 的用户并设置初始密码:
rabbitmqctl add_user api_user 'replace-with-a-long-random-password'
避免将真实的生产密码保存在 shell 历史记录中。在自动化系统中,建议使用您的密钥管理器以及平台已使用的配置机制。
3. 修改用户标签(角色)
用户标签定义了预定义的角色,这些角色授予特定的管理能力。最常见的标签是 administrator、policymaker 和 management。
administrator:可以管理用户、权限、虚拟主机、策略以及集群范围的设置。policymaker:可以在用户有权访问的虚拟主机上管理策略和参数。management:可以登录管理 UI/API,但虚拟主机权限仍然控制用户可以使用的资源。monitoring:可以查看管理信息,适用于可观测性账户。
查看当前标签
使用 list_user_tags 查看当前角色:
rabbitmqctl list_user_tags api_user
设置标签
要为 api_user 分配 management 标签:
rabbitmqctl set_user_tags api_user management
set_user_tags 会将用户的标签列表替换为您提供的标签。要同时赋予 administrator 和 policymaker 标签,请在同一个命令中包含两者:
rabbitmqctl set_user_tags api_user administrator policymaker
移除标签
要移除用户的所有标签:
rabbitmqctl set_user_tags api_user
某些 RabbitMQ 版本还提供了 clear_user_tags 命令。在编写脚本之前,请检查您安装的版本中 rabbitmqctl help clear_user_tags 的输出。
4. 更改用户密码
如果需要轮换凭据,请使用 change_password 命令:
rabbitmqctl change_password api_user newsecurepass123
5. 删除用户
要完全移除用户并撤销所有相关访问权限:
rabbitmqctl delete_user api_user
警告: 在生产环境中,出于安全考虑,通常建议删除
guest用户,但这需要先创建一个新的管理用户。
管理虚拟主机权限
RabbitMQ 中的权限是基于每个虚拟主机(vhost)定义的。虚拟主机充当队列、交换器和绑定的命名空间。默认情况下,RabbitMQ 有一个名为 / 的根虚拟主机。
1. 列出虚拟主机
首先,确定可用的虚拟主机:
rabbitmqctl list_vhosts
2. 为用户设置虚拟主机权限
set_permissions 命令对于应用程序安全至关重要。它授予用户在特定虚拟主机内配置、读取或写入资源的权限。
语法: rabbitmqctl set_permissions -p <vhost> <user> <configure> <write> <read>
权限值是正则表达式。.* 表示所有资源名称。^$ 表示没有资源名称。
示例:授予对特定虚拟主机的完全访问权限
如果我们希望 app_prod 仅对 /prod_vhost 拥有完全的 CRUD(配置、读取、写入)访问权限:
rabbitmqctl set_permissions -p /prod_vhost app_prod "^.*" "^.*" "^.*"
| 权限 | 含义 | 典型用途 |
|---|---|---|
| Configure | 创建、删除或修改与正则表达式匹配的队列、交换器和绑定。 | 部署人员或声明自身拓扑的应用程序。 |
| Write | 向匹配的交换器发布消息。 | 生产者。 |
| Read | 从匹配的队列消费消息。 | 消费者。 |
示例:限制用户仅能发布
对于流式生产者,一种常见模式是限制其仅能写入:
# 用户 'publisher' 可以写入,但不能配置或读取 /analytics_vhost 中的消息
rabbitmqctl set_permissions -p /analytics_vhost publisher "^$" "^events\\." "^$"
该示例允许向名称以 events. 开头的交换器发布消息。它不允许用户配置拓扑或消费消息。
示例:限制消费者
# 可以从以 worker. 开头的队列读取,但不能发布或配置
rabbitmqctl set_permissions -p /jobs worker_consumer "^$" "^$" "^worker\\."
正则表达式权限功能强大,但也容易过于宽泛。如果您的队列在同一个虚拟主机中命名为 prod.orders.created 和 staging.orders.created,那么像 .*orders.* 这样的正则表达式可能会覆盖超出预期的范围。使用独立的虚拟主机通常比复杂的正则表达式边界更清晰。
3. 清除权限
要完全移除用户在特定虚拟主机上的所有权限,请使用 clear_permissions:
rabbitmqctl clear_permissions -p /prod_vhost app_prod
4. 列出用户权限
要验证在虚拟主机上授予的权限:
rabbitmqctl list_permissions -p /prod_vhost
要查看分配给一个用户在所有虚拟主机上的所有权限:
rabbitmqctl list_user_permissions app_prod
用户管理最佳实践
- 遵循最小权限原则: 生产者通常需要写入权限,消费者通常需要读取权限,只有拓扑所有者需要配置权限。
- 使用专用虚拟主机: 使用虚拟主机来隔离环境和租户,而不是试图用正则表达式解决所有问题。
- 谨慎处理
guest用户: 默认的guest用户默认仅限于本地主机。许多生产团队在创建真实的管理员账户后会删除它。 - 将期望状态脚本化: 将用户、虚拟主机和权限设置纳入部署自动化,这样重建的代理就不依赖于记忆。
- 更改后进行验证: 在生产环境中每次更改后,运行
list_users、list_permissions和list_user_permissions。
一个实用的应用程序设置通常如下所示:
rabbitmqctl add_vhost /orders
rabbitmqctl add_user orders_publisher 'replace-with-secret'
rabbitmqctl add_user orders_worker 'replace-with-secret'
rabbitmqctl set_permissions -p /orders orders_publisher "^$" "^orders\\." "^$"
rabbitmqctl set_permissions -p /orders orders_worker "^$" "^$" "^orders\\."
rabbitmqctl list_user_permissions orders_publisher
rabbitmqctl list_user_permissions orders_worker
这样可以将发布和消费的凭据分开。如果工作者的密码泄露,它无法发布新消息。如果发布者的密码泄露,它无法清空队列。这种分离很简单,但却是 RabbitMQ 最有用的安全习惯之一。