凭证和密码
概述
本指南涵盖了与内部身份验证后端使用的凭据和密码相关的各种主题。如果使用了不同的身份验证后端,本指南中的大部分内容将不适用。
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_sha512rabbit_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
# Outputs
# Will hash password foobarbaz
# 27cx5+wEi8R8uwTeTr3hk5azuV3yYxxAtwPPhCyrbdsxVhqq
通过 rabbitmqadmin 哈希
rabbitmqadmin passwords salt_and_hash foobarbaz
# Outputs
# ┌───────────────┬──────────────────────────────────────────────────┐
# │ Result │
# ├───────────────┼──────────────────────────────────────────────────┤
# │ key │ value │
# ├───────────────┼──────────────────────────────────────────────────┤
# │ password hash │ 5ZbXJB3OWQlCzUNybwJ/XcL6ZqJA9zNQvXlwYnWQikQSP3lz │
# └───────────────┴──────────────────────────────────────────────────┘
通过 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值。