跳至主内容
版本:4.3

身份验证、授权、访问控制

概述

本文档介绍了 RabbitMQ 中的 身份验证授权 功能。它们共同允许操作员控制对系统的访问。

不同的用户只能被授予对特定 虚拟主机 (vhost) 的访问权限。他们在每个虚拟主机中的权限也可以受到限制。

RabbitMQ 支持两种主要的 身份验证机制 以及多种 身份验证和授权后端

本指南涵盖了各种身份验证、授权和用户管理主题,例如:

基于密码的 身份验证有专门的指南。OAuth 2 支持TLS 支持(包括基于 x.509 证书的身份验证)这两个密切相关的主题也在专门的指南中进行了介绍。

术语和定义

身份验证和授权经常被混淆或互换使用。这是不对的,在 RabbitMQ 中,两者是分开的。为简单起见,我们将身份验证定义为“识别用户是谁”,将授权定义为“确定用户被允许做什么和不被允许做什么”。

基础知识

当客户端 连接 到 RabbitMQ 时,它们会指定一组凭据:用户名-密码对、JWT 令牌x.509 证书。每个连接都有一个已通过身份验证的关联用户。它还针对一个 虚拟主机,用户必须在该主机上拥有一定的权限集。

用户凭据、目标虚拟主机和(可选)客户端 证书 在连接初始化时指定。

存在一对默认的凭据,称为 默认用户。默认情况下,此用户只能 用于主机本地连接。使用默认用户的远程连接将被拒绝。

生产环境 不应使用默认用户。请改为使用生成的凭据创建新的用户账户。

默认虚拟主机和用户

当服务器首次启动并检测到其数据库未初始化或已被重置/删除(节点为“空白节点”)时,它会初始化一个全新的数据库,包含以下资源:

  • 一个名为 /(斜杠)的 虚拟主机
  • 一个名为 guest 的用户,默认密码为 guest,被授予对 / 虚拟主机的完全访问权限

如果空白节点 在启动时导入定义,则不会创建此默认用户。

强烈建议 预先配置一个带有生成用户名和密码的新用户,或者 删除 guest 用户,或者至少将其密码 更改 为公众不知道的、合理的安全生成值。

身份验证:你是谁?

在应用程序连接到 RabbitMQ 并且能够执行操作之前,它必须进行身份验证,即出示并证明其身份。有了该身份,RabbitMQ 节点就可以查找其权限并 授权 其访问资源,例如 虚拟主机、队列、交换机等。

验证客户端身份的两种主要方式是 用户名/密码对X.509 证书。用户名/密码对可以与各种 身份验证后端 一起使用,这些后端会对凭据进行验证。

未能通过身份验证的连接将被关闭,并在 服务器日志 中显示错误消息。

使用客户端 TLS (x.509) 证书数据进行身份验证

要使用 X.509 证书验证客户端连接,必须启用内置插件 rabbitmq-auth-mechanism-ssl,并且客户端必须 配置为使用 EXTERNAL 机制。使用此机制时,客户端提供的任何密码都将被忽略。

“guest”用户只能从本地主机连接

默认情况下,禁止 guest 用户从远程主机连接;它只能通过环回接口(localhost)连接。这适用于 所有协议的连接。任何其他用户(默认情况下)不会受到这种限制。

使用默认用户的远程连接将被拒绝,并显示类似于以下的 日志消息

[error] <0.918.0> PLAIN login refused: user 'guest' can only connect via localhost
提示

在生产系统中解决此问题的推荐方法是创建一个带有生成凭据的新用户,或一组用户,并授予其访问必要虚拟主机的权限。这可以通过 定义文件CLI 工具HTTP API 来完成。

环回用户列表通过 配置文件 中的 loopback_users 项进行配置。默认情况下,它包含一个条目:用户 guest,因为它拥有广为人知的默认凭据。

危险

可以通过将 loopback_users 配置键设置为 none 来允许 guest 用户从远程主机连接。

强烈建议不要允许使用众所周知的默认凭据的默认用户进行远程连接:这样做会极大地降低集群的安全性。

允许 guest 进行远程连接的极简 RabbitMQ 配置文件 如下所示

# DANGER ZONE!
#
# allowing remote connections for default user is highly discouraged
# as it dramatically decreases the security of the cluster. Delete the default user
# instead and create a new one with generated secure credentials, or use JWT tokens,
# or x.509 certificates for clients to authenticate themselves
loopback_users = none

管理用户和权限

用户和权限可以使用 CLI 工具 和定义导入(见下文)进行管理。

开始之前:Shell 转义和生成密码

生成复杂的密码(通常涉及非字母数字字符)是一种常见的安全实践。这种做法完全适用于 RabbitMQ 用户。

Shell(bashzsh 等)将某些字符(!?&^"'*~ 等)解释为控制字符。

当在命令行中为 rabbitmqctl add_userrabbitmqctl change_password 以及其他接受密码的命令指定密码时,必须针对所使用的 shell 对这些控制字符进行适当的转义。如果不正确转义,命令将失败,或者 RabbitMQ CLI 工具将从 shell 接收到不同的值。

当生成将在命令行上传递的密码时,使用极少数符号(例如 :=)的长(例如 40 到 100 个字符)字母数字值是最安全的选择。

当通过 HTTP API 创建用户而不需要使用 shell(例如 curl)时,控制字符的限制不适用。但是,根据使用的编程语言,可能需要不同的转义规则。

添加用户

要添加用户,请使用 rabbitmqctl add_userrabbitmqadmin users declare。两者都有多种指定 密码 的方法

# will prompt for password, only use this option interactively
rabbitmqctl add_user "username"

# Password is provided via standard input.
# Note that certain characters such as !, &, $, #, and so on must be escaped to avoid
# special interpretation by the shell.
echo '2a55f70a841f18b97c3a7db939b7adc9e34a0f1b' | rabbitmqctl add_user 'username'

# Password is provided as a command line argument.
# Note that certain characters such as !, &, $, #, and so on must be escaped to avoid
# special interpretation by the shell.
rabbitmqctl add_user 'username' '2a55f70a841f18b97c3a7db939b7adc9e34a0f1b'

# This example uses a salted password hash instead of a plaintext value.
# To produce a salted hash of a password, use
# 'rabbitmqctl hash_password "my-secret-password"'
rabbitmqctl add_user --pre-hashed-password 'username' '{value produced by "rabbitmqctl hash_password"}'

新添加的用户必须被 授予权限 访问一个或多个虚拟主机,否则其连接将被拒绝。

列出用户

要列出集群中的用户,请使用 rabbitmqctl list_usersrabbitmqadmin users list

rabbitmqctl list_users

删除用户

要删除用户,请使用 rabbitmqctl delete_userrabbitmqadmin users delete

rabbitmqctl delete_user 'username'

授予用户权限

要在 虚拟主机 中向用户授予 权限,请使用 rabbitmqctl set_permissionsrabbitmqadmin declare permissions

# First ".*" for configure permission on every entity
# Second ".*" for write permission on every entity
# Third ".*" for read permission on every entity
rabbitmqctl set_permissions -p "custom-vhost" "username" ".*" ".*" ".*"

清除用户在虚拟主机中的权限

要从用户在 虚拟主机 中的 权限 中撤销,请使用 rabbitmqctl clear_permissionsrabbitmqadmin delete permissions

# Revokes permissions in a virtual host
rabbitmqctl clear_permissions -p "custom-vhost" "username"

为新虚拟主机预配置默认用户权限

可以在 rabbitmq.conf 中预配置默认用户权限,以便在创建名称匹配模式的新虚拟主机时自动授予权限。

## Grants user 'monitoring' access to all virtual hosts
## with certain permissions
default_users.monitoring.vhost_pattern = .*
default_users.monitoring.tags = monitoring
default_users.monitoring.configure = ^$
default_users.monitoring.read = .*
default_users.monitoring.write = ^$

此功能仅应用于授予服务账户(例如监控和自动化工具)对虚拟主机的访问权限。

对多个虚拟主机执行操作

每个 rabbitmqctlrabbitmqadmin 权限管理操作都仅限于单个虚拟主机。批量操作必须通过脚本编写,虚拟主机列表来自 rabbitmqctl list_vhosts --silentrabbitmqadmin vhosts list

# Assumes a Linux shell.
# Grants a user permissions to all virtual hosts.
for v in $(rabbitmqctl list_vhosts --silent); do rabbitmqctl set_permissions -p $v "a-user" ".*" ".*" ".*"; done

播种(预创建)用户和权限

生产环境 通常需要预先配置(播种)多个虚拟主机、用户和用户权限。

这可以通过几种方式完成:

CLI 工具

参见 用户管理 部分。

节点启动时导入定义

此过程涉及以下步骤:

  • 设置临时节点,并使用 CLI 工具创建必要的虚拟主机、用户、权限等
  • 将定义导出到定义文件
  • 删除文件中不相关的部分
  • 配置节点在启动时或启动后导入文件

请参阅定义指南中的 节点启动时导入定义 以了解更多信息。

节点启动后导入定义

请参阅定义指南中的 节点启动后导入定义

覆盖默认用户凭据

可以使用两个配置选项来覆盖默认用户凭据。此用户将仅在 节点首次启动时 创建,因此它们必须在首次启动之前存在于配置文件中。

这些设置是:

# default is "guest", and its access is limited to localhost only.
# See ./access-control#default-state
default_user = a-user
# default is "guest"
default_pass = 768a852ed69ce916fa7faa278c962de3e4275e5f

rabbitmq.conf 中的所有值一样,# 字符开始注释,因此在生成的凭据中必须避免使用此字符。

默认用户凭据也可以加密。此主题在 配置值加密 中有更详细的介绍。

授权:权限如何工作

当 RabbitMQ 客户端与服务器建立连接并进行 身份验证 时,它会指定一个打算在其中操作的虚拟主机。此时将强制执行第一级访问控制,服务器检查用户是否拥有访问该虚拟主机的任何权限,否则将拒绝连接尝试。

资源(即交换机和队列)是特定虚拟主机内的命名实体;相同的名称在每个虚拟主机中表示不同的资源。当在资源上执行某些操作时,会强制执行第二级访问控制。

RabbitMQ 区分资源上的 configure(配置)、write(写入)和 read(读取)操作。configure 操作创建或销毁资源,或更改其行为。write 操作将消息注入到资源中。read 操作从资源中检索消息。

为了在资源上执行操作,必须向用户授予相应的权限。

下表显示了执行权限检查的所有 AMQP 0-9-1 命令所需的资源权限类型。

AMQP 0-9-1 操作配置writeread
exchange.declare(passive=false)exchange
exchange.declare(passive=true)
exchange.declare(带 AE)exchange交换机 (AE)exchange
exchange.deleteexchange
queue.declare(passive=false)queue
queue.declare(passive=true)
queue.declare(带 DLX)queue交换机 (DLX)queue
queue.deletequeue
exchange.bind交换机 (destination)交换机 (source)
exchange.unbind交换机 (destination)交换机 (source)
queue.bindqueueexchange
queue.unbindqueueexchange
basic.publishexchange
basic.getqueue
basic.consumequeue
queue.purgequeue

权限以正则表达式的三元组表示(每个分别用于配置、写入和读取),基于每个虚拟主机。用户被授予对名称与正则表达式匹配的所有资源执行相应操作的权限。

例如,上表显示 queue.bind 协议操作需要在目标 queue 上具有 write 权限,而在目标 exchange 上需要 read 权限。

换句话说,为了允许用户将名为 queueA 的队列绑定到名为 exchangeB 的交换机,用户需要 write 权限正则表达式(针对正确的虚拟主机)匹配 queueA,而 read 权限正则表达式匹配 exchangeB

为了方便起见,RabbitMQ 在执行权限检查时将 AMQP 0-9-1 默认交换机的空名称映射为 'amq.default'。

正则表达式 '^$'(即仅匹配空字符串)涵盖所有资源,并有效阻止用户执行任何操作。内置的 AMQP 0-9-1 资源名称以 amq. 为前缀,服务器生成的名称以 amq.gen 为前缀。

例如,'^(amq\.gen.*|amq\.default)$' 为用户提供对服务器生成名称和默认交换机的访问权限。空字符串 '''^$' 的同义词,并以完全相同的方式限制权限。

RabbitMQ 可能会 缓存 基于连接或频道的访问控制检查结果。因此,用户权限的更改可能仅在用户重新连接时生效。

有关如何设置访问控制的详细信息,请参阅 用户管理 部分以及 rabbitmqctl 手册页

用户标签和管理 UI 访问

除了上述权限外,用户还可以拥有与他们关联的标签。目前只有管理 UI 访问受用户标签控制。

标签使用 rabbitmqctl 进行管理。新创建的用户默认没有任何标签。

请参阅 管理插件指南 以了解支持哪些标签以及它们如何限制管理 UI 访问。

主题授权

RabbitMQ 支持主题交换机的主题授权。当强制执行发布授权时,会考虑发布到主题交换机的消息的路由键(例如,在 RabbitMQ 默认授权后端中,将路由键与正则表达式匹配以决定消息是否可以路由到下游)。主题授权针对 STOMP 和 MQTT 等协议,这些协议围绕主题构建并在底层使用主题交换机。

主题授权是发布者现有检查之上的附加层。将消息发布到主题类型交换机将同时经过 basic.publish 和路由键检查。如果前者拒绝访问,则永远不会调用后者。

主题授权也可以针对主题消费者强制执行。请注意,它对不同的协议工作方式不同。主题授权的概念仅对 MQTT 和 STOMP 等面向主题的协议真正有意义。例如,在 AMQP 0-9-1 中,消费者从队列消费,因此适用标准的资源权限。此外,对于 AMQP 0-9-1,AMQP 0-9-1 主题交换机和队列/交换机之间的绑定路由键会根据配置的主题权限(如果有)进行检查。有关 RabbitMQ 如何处理主题授权的更多信息,请参阅 STOMPMQTT 文档指南。

当使用默认授权后端时,如果未定义主题权限(这是全新 RabbitMQ 安装的情况),则始终授权发布到主题交换机或从主题消费。因此,使用此授权后端时,主题授权是可选的:您不需要批准任何交换机。因此,要使用主题授权,您需要选择加入并为一或多个交换机定义主题权限。有关详细信息,请参阅 rabbitmqctl 手册页

内部(默认)授权后端支持权限模式中的变量扩展。支持三个变量:usernamevhostclient_id。请注意,client_id 仅适用于 MQTT。例如,如果 tonyg 是连接的用户,则权限 ^{username}-.* 扩展为 ^tonyg-.*

如果使用不同的授权后端(例如 LDAPHTTPOAuth 2),请参阅这些后端的文档。

如果使用自定义授权后端,则通过实现 rabbit_authz_backend 行为的 check_topic_access 回调来强制执行主题授权。

撤销用户访问和凭据轮换

撤销用户访问

要撤销用户访问权限,推荐的过程是 删除用户。属于已删除用户的所有打开连接都将被关闭。

也可以清除用户权限,但这不会影响任何当前打开的连接。连接使用授权操作缓存,因此客户端操作最终会被拒绝。时间长短取决于所使用的 授权后端

凭据轮换

存储在内部数据存储中的用户凭据的轮换通常涉及以下步骤:

  • 使用 CLI 工具 更改用户密码 或使用 PUT /api/users/{user} HTTP API 端点对其进行更新
  • 使用 rabbitmqctl close_all_user_connectionsrabbitmqctl close_all_connections 关闭所有现有连接
  • 确保应用程序能够发现新凭据并重新连接,例如通过重新启动它们

如果怀疑凭据泄露,可以采用更彻底的凭据轮换程序:

  • 评估用户的权限并 获取完整的集群定义文件
  • 删除用户,从而撤销其访问权限并关闭所有使用这些凭据的现有连接
  • 使用新的生成密码重新添加用户
  • 重新授予用户访问其先前有权访问的所有虚拟主机的权限
  • 确保应用程序能够发现新凭据并重新连接,例如通过重新启动它们

使用外部 authN 后端(如 LDAP)时,用户账户在 RabbitMQ 外部进行管理,因此凭据轮换程序也将在 RabbitMQ 外部进行。

身份验证和授权后端

身份验证和授权是可插拔的。插件可以提供以下实现:

  • 身份验证("authn")后端:它们确定客户端身份并决定是否允许客户端连接
  • 授权("authz")后端:它们确定已识别(已认证)的客户端是否被授权执行特定操作

插件提供这两个后端是可能的且常见的。RabbitMQ 附带了以下 内置插件,它们提供身份验证和授权后端:

以下内置插件提供授权后端实现:

某些插件(例如 源 IP 范围插件)也仅提供授权后端。

身份验证通常由内部数据库、LDAP 等处理。

可以将特殊的 缓存后端 与其他后端 组合使用,以显着减少它们在 LDAP 或 HTTP 服务器等外部服务上产生的负载。

组合后端

可以使用 auth_backends 配置键为 authnauthz 使用多个后端。当使用多个身份验证后端时,链中后端返回的第一个积极结果被视为最终结果。这不应与混合后端混淆(例如,使用 LDAP 进行身份验证,使用内部后端进行授权)。

以下示例将 RabbitMQ 配置为仅使用内部后端(这是默认设置):

# rabbitmq.conf
#
# 1 here is a backend name. It can be anything.
# Since we only really care about backend
# ordering, we use numbers throughout this guide.
#
# "internal" is an alias for rabbit_auth_backend_internal
auth_backends.1 = internal

上面的示例使用 rabbit_auth_backend_internal 的别名 internal。以下别名可用:

  • internal 代表 rabbit_auth_backend_internal
  • ldap 代表 rabbit_auth_backend_ldap(来自 LDAP 插件
  • oauthoauth2 代表 rabbit_auth_backend_oauth2(来自 OAuth 2.0 插件
  • http 代表 rabbit_auth_backend_http(来自 HTTP 身份验证后端插件
  • dummy 代表 rabbit_auth_backend_dummy

对于没有快捷方式的插件,必须使用完整的模块名称(不是插件的名称!)

# note that the module name begins with a "rabbit_", not "rabbitmq_", like plugin
# names usually do
auth_backends.1 = rabbit_auth_backend_ip_range

使用第三方插件时,必须提供完整的模块名称。

以下示例将 RabbitMQ 配置为使用 LDAP 后端 进行身份验证和授权。不会咨询内部数据库。

auth_backends.1 = ldap

这将首先检查 LDAP,如果用户无法通过 LDAP 进行身份验证,则回退到内部数据库。

auth_backends.1 = ldap
auth_backends.2 = internal

与上述相同,但将回退到 HTTP 后端

# rabbitmq.conf
#
auth_backends.1 = ldap
# uses module name instead of a short alias, "http"
auth_backends.2 = rabbit_auth_backend_http

# See HTTP backend docs for details
auth_http.user_path = http://my-authenticator-app/auth/user
auth_http.vhost_path = http://my-authenticator-app/auth/vhost
auth_http.resource_path = http://my-authenticator-app/auth/resource
auth_http.topic_path = http://my-authenticator-app/auth/topic

以下示例将 RabbitMQ 配置为使用内部数据库进行身份验证,并使用 源 IP 范围后端 进行授权。

# rabbitmq.conf
#
auth_backends.1.authn = internal
# uses module name because this backend is from a 3rd party
auth_backends.1.authz = rabbit_auth_backend_ip_range

以下示例将 RabbitMQ 配置为使用 LDAP 后端 进行身份验证,并使用内部后端进行授权。

# rabbitmq.conf
#
auth_backends.1.authn = ldap
auth_backends.1.authz = internal

下面的示例相当高级。它将首先检查 LDAP。如果用户在 LDAP 中找到,则根据 LDAP 检查密码,随后的授权检查将根据内部数据库执行(因此 LDAP 中的用户也必须存在于内部数据库中,但在那里不需要密码)。如果用户未在 LDAP 中找到,则仅使用内部数据库进行第二次尝试。

# rabbitmq.conf
#
auth_backends.1.authn = ldap
auth_backends.1.authz = internal
auth_backends.2 = internal

身份验证机制

RabbitMQ 支持多种 SASL 身份验证机制。服务器内置了四种此类机制:PLAINAMQPLAINANONYMOUSRABBIT-CR-DEMO,以及一种作为 插件 提供的机制 — EXTERNAL

更多身份验证机制可以由插件提供。有关常规插件开发的更多信息,请参阅 插件开发指南

内置身份验证机制

内置机制包括:

机制描述
PLAIN

SASL PLAIN 身份验证。这在 RabbitMQ 服务器和客户端中默认启用,并且是大多数其他客户端的默认设置。

AMQPLAIN

非标准版本的 PLAIN,保留用于向后兼容性。这在 RabbitMQ 服务器中默认启用。

ANONYMOUS

此机制默认启用,允许匿名客户端连接而不提供任何凭据。RabbitMQ 将在内部使用配置在 anonymous_login_useranonymous_login_pass 中的凭据对客户端进行身份验证和授权(两者默认都设置为 guest)。换句话说,任何未经身份验证的客户端都将能够连接并以配置的 anonymous_login_user 身份行事。 对于生产环境,请删除此机制。 请参阅 部署指南

EXTERNAL

身份验证使用带外机制进行,例如 x509 证书对等验证、客户端 IP 地址范围或类似机制。此类机制通常由 RabbitMQ 插件提供。

RABBIT-CR-DEMO非标准机制,演示质询-响应身份验证。此机制具有等同于 PLAIN 的安全性,并且 默认不在 RabbitMQ 服务器中启用。

服务器中的机制配置

auth_mechanisms 配置键决定向连接的客户端提供哪些安装的机制。

此变量应为与机制名称对应的接受值列表,例如,以下列表

auth_mechanisms.1 = PLAIN
auth_mechanisms.2 = AMQPLAIN
auth_mechanisms.3 = ANONYMOUS

默认使用。

服务器机制按优先顺序降序排列。请参阅 配置文件 文档。

客户端中的机制配置

应用程序必须选择加入才能使用不同的身份验证机制,例如 EXTERNAL

Java 中的机制配置

Java 客户端默认不使用 javax.security.sasl 包,因为这在非 Oracle JDK 上可能是不可预测的,并且在 Android 上完全缺失。有一个特定于 RabbitMQ 的 SASL 实现,由 SaslConfig 接口配置。提供了一个 DefaultSaslConfig 类,使 SASL 配置在常见情况下更加方便。提供了一个 JDKSaslConfig 类作为到 javax.security.sasl 的桥梁。

ConnectionFactory.getSaslConfig()ConnectionFactory.setSaslConfig(SaslConfig) 是与身份验证机制交互的主要方法。

.NET 中的机制配置

.NET 客户端基于 AuthMechanismAuthMechanismFactory 接口提供了自己的 SASL 机制实现。ConnectionFactory.AuthMechanisms 属性是按优先顺序排列的身份验证机制工厂列表。

Erlang 中的机制配置

Erlang 客户端在 amqp_auth_mechanisms 模块中提供了自己的 SASL 机制实现。可以为 #amqp_params 记录提供按优先顺序排列的网络连接身份验证功能列表。

故障排除:身份验证

本节涵盖与身份验证相关的几个非常常见的问题。有关授权(权限)错误,请参阅 下方的另一个部分

提示

检查 服务器日志 在调查与身份验证相关的问题时至关重要。

不正确的权限

失败的身份验证尝试(即客户端指定了不正确的凭据时)将导致 服务器日志消息 如下所示:

2019-03-25 12:28:19.047 [info] <0.1613.0> accepting AMQP connection <0.1613.0> (127.0.0.1:63839 -> 127.0.0.1:5672)
2019-03-25 12:28:19.056 [error] <0.1613.0> Error on AMQP connection <0.1613.0> (127.0.0.1:63839 -> 127.0.0.1:5672, state: starting):
PLAIN login refused: user 'user2' - invalid credentials
2019-03-25 12:28:22.057 [info] <0.1613.0> closing AMQP connection <0.1613.0> (127.0.0.1:63839 -> 127.0.0.1:5672)

在使用 X.509 证书进行身份验证 的连接上的身份验证失败将被记录得不同。有关详细信息,请参阅 TLS 故障排除指南

rabbitmqctl authenticate_user 可用于测试用户名和密码对的身份验证。

rabbitmqctl authenticate_user "a-username" "a/password"

如果身份验证成功,它将以代码 0 退出。如果失败,将使用非零退出代码,并将打印失败错误消息。

rabbitmqctl authenticate_user 将使用 CLI 到节点的通信连接,尝试根据内部 API 端点验证用户名/密码对。连接被假定为受信任的。如果不是这种情况,其流量可以 使用 TLS 加密

默认用户从远程主机的连接被拒绝

危险

默认用户不能从远程主机连接是有原因的。启用此类连接会极大地降低集群的安全性。考虑为所有生产集群创建一个 带有生成凭据的唯一用户

如果凭据被报告为正确,本地主机的连接成功但远程连接失败,则问题是 默认用户连接限制

在这种情况下,错误如下所示:

2024-08-24 17:28:32.153698-04:00 [error] <0.1567.0> PLAIN login refused: user 'guest' can only connect via localhost

必须为从远程主机连接的客户端(包括 shovels联邦链接创建一个 带有生成凭据的单独用户。

AMQP 0-9-1 中的身份验证失败通知

根据 AMQP 0-9-1 规范,身份验证失败应导致服务器立即关闭 TCP 连接。然而,使用 RabbitMQ,客户端可以选择通过 身份验证失败通知 扩展接收更具体的通知。现代客户端库可以对用户透明地支持该扩展:无需配置,身份验证失败将导致可见的返回错误、异常或特定编程语言或环境中使用的其他问题通信方式。

故障排除:授权

提示

检查 服务器日志 在调查与授权相关的问题时至关重要。

缺少权限

授权失败中最常见的情况是用户已创建,但未被 授予权限 以访问客户端尝试连接到的虚拟主机。

在这种情况下,连接将被拒绝,消息如下所示:

2019-03-25 12:26:16.301 [info] <0.1594.0> accepting AMQP connection <0.1594.0> (127.0.0.1:63793 -> 127.0.0.1:5672)
2019-03-25 12:26:16.309 [error] <0.1594.0> Error on AMQP connection <0.1594.0> (127.0.0.1:63793 -> 127.0.0.1:5672, user: 'user2', state: opening):
access to vhost '/' refused for user 'user2'
2019-03-25 12:26:16.310 [info] <0.1594.0> closing AMQP connection <0.1594.0> (127.0.0.1:63793 -> 127.0.0.1:5672, vhost: 'none', user: 'user2')

权限不足

另一种非常常见的情况是定义了权限,但对于客户端尝试执行的操作,它们 不足以执行操作

在这种情况下,连接将被接受。

rabbitmqctl list_permissionsrabbitmqadmin users permissions 可用于检查用户在给定虚拟主机中的权限。

rabbitmqctl list_permissions --vhost /
# => Listing permissions for vhost "/" ...
# => user configure write read
# => user2 .* .* .*
# => guest .* .* .*
# => temp-user .* .* .*

rabbitmqctl list_permissions --vhost gw1
# => Listing permissions for vhost "gw1" ...
# => user configure write read
# => guest .* .* .*
# => user2 ^user2 ^user2 ^user2

授权失败(权限冲突)通过以下消息进行记录:

2019-03-25 12:30:05.209 [error] <0.1627.0> Channel error on connection <0.1618.0> (127.0.0.1:63881 -> 127.0.0.1:5672, vhost: 'gw1', user: 'user2'), channel 1:
operation queue.declare caused a channel exception access_refused: access to queue 'user3.q1' in vhost 'gw1' refused for user 'user2'
© . This site is unofficial and not affiliated with VMware.