凭据和密码
概述
本指南涵盖了与内部身份验证后端使用的凭据和密码相关的各种主题。如果使用不同的身份验证后端,本指南中的大多数材料将不适用。
RabbitMQ 支持多种 身份验证机制。其中一些使用用户名/密码对。这些凭据对随后被传递给执行身份验证的 身份验证后端。其中一个后端称为内部或内置后端,它使用内部 RabbitMQ 数据存储来存储用户凭据。当使用 rabbitmqctl
添加新用户时,用户的密码会与盐值组合并进行哈希处理。
RabbitMQ 可以配置为使用不同的密码哈希函数
- SHA-256
- SHA-512
默认情况下使用 SHA-256。插件可以提供更多算法。
配置要使用的算法
可以通过 RabbitMQ 配置文件 更改使用的算法,例如,使用 SHA-512
password_hashing_module = rabbit_password_hashing_sha512
开箱即用,提供以下哈希模块
rabbit_password_hashing_sha256
(默认)rabbit_password_hashing_sha512
rabbit_password_hashing_md5
(为了向后兼容)
更新后的哈希算法将应用于新创建的用户或使用 rabbitmqctl 更改密码时。
凭据验证
RabbitMQ 支持凭据验证器。验证器仅对内部身份验证后端有效,并在添加新用户或更改现有用户的密码时启动。
验证器是实现验证函数的模块。要使用验证器,有必要在 配置文件 中指定它及其附加设置。
开箱即用,有三个凭据验证器可用
rabbit_credential_validator_accept_everything
:无条件接受所有值。为了向后兼容,默认情况下使用此验证器。rabbit_credential_validator_min_password_length
:验证密码长度rabbit_credential_validator_password_regexp
:验证密码是否与正则表达式匹配(有一些限制,见下文)
以下示例演示了如何使用 rabbit_credential_validator_min_password_length
credential_validator.validation_backend = rabbit_credential_validator_min_password_length
credential_validator.min_length = 30
以下示例演示了如何使用 rabbit_credential_validator_password_regexp
credential_validator.validation_backend = rabbit_credential_validator_password_regexp
credential_validator.regexp = ^[a-bA-Z0-9$]{20,100}
凭据验证器限制
凭据验证器有一些限制,这些限制与配置文件语法和在命令行上指定凭据时 shell 对某些字符的解释有关。
新式配置格式 使用 #
作为注释字符。这意味着验证规则不能在正则表达式值中使用 #
。配置文件解析器还会剥离值中的前导和尾随空格。
还要注意,当密码与管理用户的 CLI 工具命令一起使用时,必须考虑某些字符的 shell 转义 必须考虑。
自定义凭据验证器
每个凭据验证器都是一个模块,它实现了一个单一的功能行为,rabbit_credential_validator。因此,插件可以提供更多实现。
凭据验证器还可以验证用户名或应用任何其他逻辑(例如,确保提供的用户名和密码不相同)。
无密码用户
内部身份验证后端 允许没有密码或空白密码的用户(假设凭据验证器也允许)。此类用户仅用于无密码 身份验证机制,例如 使用 x509 证书进行身份验证。
要创建无密码用户,请使用通过验证的任何密码创建一个用户,并使用 rabbitmqctl 的 clear_password
命令清除密码
rabbitmqctl add_user passwordless-user "pa$$wordless"
rabbitmqctl clear_password passwordless-user
# don't forget to grant the user virtual host access permissions using set_permissions
# ...
使用空白密码进行的身份验证尝试将被 内部身份验证后端 无条件拒绝,并在 服务器日志 中显示一条独特的错误消息。使用 x509 证书进行身份验证或使用外部服务进行身份验证(例如 LDAP)的连接可以使用空白密码。
使用 TLS (x509) 证书进行身份验证
可以使用 使用 x509 证书进行身份验证 的连接,完全避免使用密码。然后,身份验证过程将依赖于 TLS 对等证书链验证。
为此
- 创建一个无密码用户(见上文)
- 启用 rabbitmq-auth-mechanism-ssl 插件
- 按照插件的配置说明进行操作
- 配置客户端连接以使用 TLS 和
EXTERNAL
身份验证机制 - 配置客户端连接以提供证书/密钥对和 CA 证书(或证书链)。证书链将由服务器验证,因此其中至少有一个证书必须受目标节点信任。
计算密码哈希
有时需要计算用户的密码哈希以通过 HTTP API 更新,或生成 定义文件 以导入。
通过 rabbitmqctl
进行哈希
rabbitmqctl hash_password foobarbaz
# Output:
# Will hash password foobarbaz
# 27cx5+wEi8R8uwTeTr3hk5azuV3yYxxAtwPPhCyrbdsxVhqq
通过 HTTP API 进行哈希
curl -4su guest:guest -X GET localhost:15672/api/auth/hash_password/foobarbaz
# Output:
# {"ok":"TBybOvomyVw6BqBU/fHCEpVhDO7fLdQ4kxZDUpt6hagCxV8I"}
算法如下:
- 生成一个随机的 32 位盐。在本例中,我们将使用
908D C60A
。当 RabbitMQ 创建或更新用户时,会生成一个随机盐。 - 使用所需密码的 UTF-8 表示在生成的盐前面加上前缀。如果密码是
test12
,在这一步中,中间结果将是908D C60A 7465 7374 3132
- 获取哈希值(本例假设使用默认的 哈希函数,SHA-256):
A5B9 24B3 096B 8897 D65A 3B5F 80FA 5DB62 A94 B831 22CD F4F8 FEAD 10D5 15D8 F391
- 再次在前面加上盐值:
908D C60A A5B9 24B3 096B 8897 D65A 3B5F 80FA 5DB62 A94 B831 22CD F4F8 FEAD 10D5 15D8 F391
- 将值转换为 Base64 编码:
kI3GCqW5JLMJa4iX1lo7X4D6XbYqlLgxIs30+P6tENUV2POR
- 在 HTTP API 请求和生成的定义文件中,使用最终的 Base64 编码值作为
password_hash
值