The valkey-ldap
module is a Rust based Valkey module that adds the support for handling user authentication against LDAP based identity providers.
The module works by registering and authentication handler that intercepts the valkey AUTH
command, which validates the the username and password, specified in the AUTH
command, using an LDAP server. Therefore the user must already exist in Valkey before LDAP can be used for authentication.
This module supports two LDAP authentication modes. The bind
mode, and the search+bind
mode.
The bind
mode can be used when the username mostly matches the DN of user entries in the LDAP directory, while the search+bind
mode allows for a much more flexible LDAP directory structure.
In the bind
mode, the module will bind to the distinguished name constructed by prepending a configurable prefix and appending a configurable suffix to the username.
Typically, the prefix parameter is used to specify cn=
, or DOMAIN\
in an Active Directory environment. The suffix is used to specify the remaining part of the DN in a non-Active Directory environment.
In the search+bind
mode, the module first binds to the LDAP directory with a username and password of an account that has permissions to perform search operation in the LDAP directory.
If no username and password is configured for the binding phase, an anonymous bind will be attempted to the directory.
After the binding phase, a search operation is performed over the subtree at a configurable base DN string, and will try to do an exact match of the username specified in the AUTH
command against the value of a configurable entry attribute.
Once the user has been found in this search, the module re-binds to the LDAP directory as this user, using the password specified in the AUTH
command, to verify that the login is correct.
This mode allows for significantly more flexibility in where the user objects are located in the directory, but will cause two additional requests to the LDAP server to be made.
As mentioned before, this module requires that user accounts must exist in Valkey in order to authenticate LDAP users. This restriction is necessary because the ACL rules for each LDAP user are stored in the Valkey user account.
For a user bob
to be successfully authenticated by the LDAP module it must exist in the Valkey ALC database with the same username bob
.
We can create the Valkey user bob
without a password, to prevent someone from trying to log in using bob
account using the password-based authentication method.
To create a user without a password we need to set the resetpass
rule in the ACL rules list. Example:
ACL SET USER bob on resetpass +@hash
After creating the above user bob
in Valkey, it will only be possible to authenticate user bob
with a successful authentication from the LDAP module.
Config Name | Type | Default | Description |
---|---|---|---|
ldap.auth_enabled |
boolean | yes |
Flag to control whether the module should process an authentication request or not. |
ldap.auth_mode |
Enum(bind , search+bind ) |
bind |
The authentication method. Check the Authentication Modes section for more information about the differences. |
ldap.servers |
string | "" |
Comma separated list of LDAP URLs of the form ldap[s]://<domain>:<port> . |
Config Name | Type | Default | Description |
---|---|---|---|
ldap.use_starttls |
boolean | no |
Whether upgrade to a TLS encrypted connection upon connection to a non-ssl LDAP instance. This uses the StartTLS operation per RFC 4513. |
ldap.tls_ca_cert_path |
string | "" |
The filesystem path of the CA certificate for validating the server certificate in a TLS connection. |
ldap.tls_cert_path |
string | "" |
The filesystem path of the client certificate to be used in a TLS connection to the LDAP server. |
ldap.tls_key_path |
string | "" |
The filesystem path of the client certificate key to be used in a TLS connection to the LDAP server. |
Config Name | Type | Default | Description |
---|---|---|---|
ldap.bind_dn_prefix |
string | "cn=" |
The string to prepend to the username passed in the AUTH command when forming the DN that is used in LDAP bind. |
ldap.bind_dn_suffix |
string | "" |
The string to append to the username passed in the AUTH command when forming the DN that is used in LDAP bind. |
Config Name | Type | Default | Description |
---|---|---|---|
ldap.search_bind_dn |
string | "" |
The bind user DN for performing the search. |
ldap.search_bind_passwd |
string | "" |
The bind user password for performing the search. |
ldap.search_base |
string | "" |
The root DN where the search for the user entry begins. |
ldap.search_filter |
string | "objectClass=*" |
The search filter used to filter directory entries. |
ldap.search_attribute |
string | "uid" |
The entry attribute used in search for matching the username specified in the AUTH command. |
ldap.search_scope |
Enum(base , one , sub ) |
sub |
The search scope. |
ldap.search_dn_attribute |
string | "entryDN" |
The attribute that contains the DN of the user entry. |
Config Name | Type | Default | Description |
---|---|---|---|
ldap.connection_pool_size |
number | 2 |
The number of connections available in each LDAP server's connection pool. |
ldap.failure_detector_interval |
number | 1 |
The number of seconds between each iteration of the failure detector. |
ldap.timeout_connection |
number | 10 |
The number of seconds for to wait when connection to an LDAP server before timing out. |
ldap.timeout_ldap_operation |
number | 10 |
The number of seconds for to wait for an LDAP operation before timing out. |
We currently build RPMs for several distributions in the valkey-ldap Copr project.
ValkeyLDAP uses Cargo for building the Valkey module.
cargo build
The project has a collection of scripts to start an LDAP and Valkey server using docker-compose to easily test the module.
To start a Valkey CLI shell to test the module commands, run:
./scripts/run_test_cli.sh
The above command will start the LDAP and Valkey servers, and opens the valkey CLI shell. When the shell closes, it also stops the LDAP and Valkey servers.
If you just want to start the LDAP and Valkey server, run:
./scripts/start_valkey_ldap.sh
You can connect to the LDAP server and Valkey server from the localhost address.
To stop the servers, run:
./scripts/stop_valkey_ldap.sh
The integration tests are written in python 3, and live in the test/integration
directory. To run the tests locally we suggest to create a virtual environment to install the necessary python dependencies.
Assuming you have python 3 installed in your system, to install the python dependencies using a virtual environment do the following:
python3 -m venv venv
source venv/bin/activate
pip install --upgrade pip
pip install -r test/integration/requirements.txt
After setting up the virtual environment, you can run the test using the following command:
./script/run_integration_tests.sh