Credentials and Passwords
Overview
This guide covers a variety of topics related to credentials and passwords used by the internal authentication backend. If a different authentication backend is used, most material in this guide will not be applicable.
RabbitMQ supports multiple authentication mechanisms. Some of them use
username/password pairs. These credential pairs are then handed over to authentication backends
that perform authentication. One of the backends, known as internal or built-in, uses internal RabbitMQ data store
to store user credentials. When a new user is added using rabbitmqctl
, the user's password is combined with a salt value
and hashed.
RabbitMQ can be configured to use different password hashing functions:
- SHA-256
- SHA-512
SHA-256 is used by default. More algorithms can be provided by plugins.
Configuring Algorithm to Use
It is possible to change what algorithm is used via RabbitMQ configuration file, for example, to use SHA-512:
password_hashing_module = rabbit_password_hashing_sha512
Out of the box, the following hashing modules are provided:
rabbit_password_hashing_sha256
(default)rabbit_password_hashing_sha512
rabbit_password_hashing_md5
(for backwards compatibility)
Updated hashing algorithm will be applied to newly created users or when password is changed using rabbitmqctl.
Upgrading from pre-3.6.0 Versions
When upgrading from a pre-3.6 version to RabbitMQ 3.6.1 or later, all existing users are marked as using the legacy password hashing function, therefore they will be able to authenticate. No upgrade steps are required.
When importing definitions exported from versions earlier than 3.6.0 into a 3.6.1 or later release, existing user records will use MD5 for password hashing. In order to migrate them to a more secure algorithm, use rabbitmqctl or definition import with an updated hash to update their passwords.
Credential Validation
RabbitMQ supports credential validators. The validator only has an effect on the internal authentication backend and kicks in when a new user is added or password of an existing user is changed.
Validators are modules that implement a validation function. To use a validator, it is necessary to specify it and its additional settings in the config file.
There are three credential validators available out of the box:
rabbit_credential_validator_accept_everything
: unconditionally accepts all values. This validator is used by default for backwards compatibility.rabbit_credential_validator_min_password_length
: validates password lengthrabbit_credential_validator_password_regexp
: validates that password matches a regular expression (with some limitations, see below)
The following example demonstrates how rabbit_credential_validator_min_password_length
is used:
credential_validator.validation_backend = rabbit_credential_validator_min_password_length
credential_validator.min_length = 30
The following example demonstrates how rabbit_credential_validator_password_regexp
is used:
credential_validator.validation_backend = rabbit_credential_validator_password_regexp
credential_validator.regexp = ^[a-bA-Z0-9$]{20,100}
Credential Validator Limitations
Credential validators have limitations that have to do both with the config file grammar and shell interpretation of certain characters when credentials are specified on the command line.
New style configuration format uses #
as the comment character.
This means that validation rules cannot
use #
in regular expression values. Leading and trailing spaces in values will also
be stripped by the config file parser.
Also note that when passwords are used with CLI tools commands that manage users, shell escaping of certain characters must be taken into account.
Custom Credential Validators
Every credential validator is a module that implements a single function behaviour, rabbit_credential_validator. Plugins therefore can provide more implementations.
Credential validators can also validate usernames or apply any other logic (e.g. make sure that provided username and password are not identical).
Passwordless Users
Internal authentication backend allows for users without a password or with a blank one (assuming credential validator also allows it). Such users are only meant to be used with passwordless authentication mechanisms such as authentication using x509 certificates.
In order to create a passwordless user, create one with any password that passes validation and clear
the password using rabbitmqctl's clear_password
command:
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
# ...
Starting with versions 3.6.15
and 3.7.3
, authentication attempts that use a blank password
will be unconditionally rejected by the internal authentication backend with a distinctive error
message in the server log. Connections that authenticate using x509 certificates or use an external service
for authentication (e.g. LDAP) can use blank passwords.
Authentication Using TLS (x509) Certificates
It is possible to authenticate connections using x509 certificates and avoid using passwords entirely. The authentication process then will rely on TLS peer certificate chain validation.
To do so:
- Create a passwordless user (see above)
- Enable the rabbitmq-auth-mechanism-ssl plugin
- Follow the plugin's configuration instructions
- Configure client connections to use TLS and the
EXTERNAL
authentication mechanism - Configure client connections to provide a certificate/key pair and a CA certificate (or chain of certificates). The chain of certificates will be verified by the server and thus at least one certificate in it must be trusted by the target node.
Computing Password Hashes
Sometimes it is necessary to compute a user's password hash for updating via the HTTP API or to generate a definitions file to import.
Hash via rabbitmqctl
rabbitmqctl hash_password foobarbaz
# Output:
# Will hash password foobarbaz
# 27cx5+wEi8R8uwTeTr3hk5azuV3yYxxAtwPPhCyrbdsxVhqq
Hash via HTTP API
curl -4su guest:guest -X GET localhost:15672/api/auth/hash_password/foobarbaz
# Output:
# {"ok":"TBybOvomyVw6BqBU/fHCEpVhDO7fLdQ4kxZDUpt6hagCxV8I"}
This is the algorithm:
- Generate a random 32 bit salt. In this example, we will use
908D C60A
. When RabbitMQ creates or updates a user, a random salt is generated. - Prepend the generated salt with the UTF-8 representation of the desired password.
If the password is
test12
, at this step, the intermediate result would be908D C60A 7465 7374 3132
- Take the hash (this example assumes the default hashing function, SHA-256):
A5B9 24B3 096B 8897 D65A 3B5F 80FA 5DB62 A94 B831 22CD F4F8 FEAD 10D5 15D8 F391
- Prepend the salt again:
908D C60A A5B9 24B3 096B 8897 D65A 3B5F 80FA 5DB62 A94 B831 22CD F4F8 FEAD 10D5 15D8 F391
- Convert the value to base64 encoding:
kI3GCqW5JLMJa4iX1lo7X4D6XbYqlLgxIs30+P6tENUV2POR
- Use the finaly base64-encoded value as the
password_hash
value in HTTP API requests and generated definition files