Manage LDAP credentials with Vault
LDAP is a critical protocol commonly in use with UNIX and Linux applications, with OpenLDAP being the most popular implementation.
The LDAP secrets engine provides a centralized workflow for efficiently managing existing LDAP entry passwords, empowering users with access to their own credentials, and the benefits of automatic password rotation.
Challenge
The hardest problems encountered with administration of LDAP and its associated credentials include:
- Volume of user entries in an LDAP directory can be difficult to efficiently manage
- Users require LDAP server access for credential self-management capabilities
- Lack of available solutions aimed at automatically rotating LDAP credentials
Solution
Use the LDAP secrets engine with Vault to offer a variety of authentication methods to users for accessing their own LDAP credentials.
You can empower users to manage their own LDAP entries, and you can configure their passwords to be automatically rotated based on an administrator-specified time to live value.
The following diagram illustrates this credential management workflow.
By making passwords short-lived as possible, you reduce the chance that they become compromised. If a credential becomes compromised, you can revoke and rotate it rather than changing a global set of credentials.
Personas
The end-to-end scenario described in this tutorial involves two personas.
admin
a Vault administrator with privileged permissions to configure secrets enginesalice
a user with existing OpenLDAP credential who needs to access a Secure Shell Daemon (sshd) server with this credential password
Prerequisites
This lab was tested on macOS using an x86_64 based processor. If you are running macOS on an Apple silicon-based processor, click the Start interactive lab button or perform the steps using a x86_64 based Linux virtual machine in your preferred cloud provider.
To perform the tasks described in this tutorial, you need to have the following items.
A Vault or HCP Vault Dedicated instance available.
An OpenLDAP environment you can connect Vault to, or Docker to run an OpenLDAP container.
Local installation of the
ldapadd
binary; if your operating system distribution does not install it by default, you can typically find it in a LDAP utilities package (such as ldap-utils on Debian based Linux) or by installing OpenLDAP locally.Local installation of the curl binary; if you want to follow the HTTP API examples, please be sure to install
curl
.Local installation of the jq binary; this is optional but makes reading JSON output from the HTTP API operations more friendly to humans.
ngrok installed and configure with an auth token (required if using HCP Vault Dedicated)
Launch Terminal
This tutorial includes a free interactive command-line lab that lets you follow along on actual cloud infrastructure.
Policy requirements
Note
You can use the initial root token value to work with Vault in this tutorial lab. It's recommended that you use root tokens just for initial setup or in emergencies in production. As a best practice, use tokens with appropriate set of policies based on your role in the organization.
To perform all tasks demonstrated in this tutorial, your admin persona policy must include the following capabilities.
# Mount secrets enginespath "sys/mounts/*" { capabilities = [ "create", "read", "update", "delete", "list" ]} # Configure the ldap secrets engine and create rolespath "ldap/*" { capabilities = [ "create", "read", "update", "delete", "list" ]} # Write ACL policiespath "sys/policies/acl/*" { capabilities = [ "create", "read", "update", "delete", "list" ]} # Manage tokens for verificationpath "auth/token/create" { capabilities = [ "create", "read", "update", "delete", "list", "sudo" ]}
If you are not familiar with policies, complete the policies tutorial.
Use a token with these policies attached for all steps performed by the admin persona in this tutorial.
Scenario introduction
In this scenario, you are going to assume two personas, first as admin to configure the LDAP secrets engine, and then as alice to request a new OpenLDAP credential.
- Enable the LDAP secrets engine
- Configure LDAP secrets engine
- Rotate root password
- Create a role
- Request OpenLDAP credentials
The admin persona performs steps 1 through 4. The user alice performs the commands in step 5 to get an OpenLDAP credential from Vault.
Lab setup
Start an OpenLDAP server
For this tutorial hands on lab, you will run a community based OpenLDAP Docker image in a container.
Note
If you already have an OpenLDAP server that you can connect to, you can ignore this step and change the examples to match your values.
Run the OpenLDAP container.
$ docker run \ --name vault-openldap \ --env LDAP_ORGANISATION="learn" \ --env LDAP_DOMAIN="learn.example" \ --env LDAP_ADMIN_PASSWORD="2LearnVault" \ -p 389:389 \ -p 636:636 \ --detach \ --rm \ osixia/openldap:1.4.0
The options you use to run the example container are as follows:
- Name the container vault-openldap
- Set LDAP organization value to learn
- Set LDAP domain to learn.example
- Set LDAP administrator password to 2LearnVault
- Listen on default LDAP and LDAPS ports TCP/389 and 636
- Expose these ports to the Docker host
- Detach the container from terminal
- Remove the container when it exits
After starting the container, verify its status.
$ docker ps -f name=vault-openldap --format "table {{.Names}}\t{{.Status}}"NAMES STATUSvault-openldap Up 9 seconds
Configure OpenLDAP with example data
With the OpenLDAP container now available, you can add initial configuration including groups and the example user, alice.
Tip
Use the cat
utility here to write file examples for this tutorial in the present working directory. If you wish to edit and write files another way, then remove the first and last lines of the example in each case to use it verbatim.
Create a configuration file named
learn-vault-example.ldif
.$ cat > learn-vault-example.ldif <<EOFdn: ou=groups,dc=learn,dc=exampleobjectClass: organizationalunitobjectClass: topou: groupsdescription: groups of users dn: ou=users,dc=learn,dc=exampleobjectClass: organizationalunitobjectClass: topou: usersdescription: users dn: cn=dev,ou=groups,dc=learn,dc=exampleobjectClass: groupofnamesobjectClass: topdescription: testing group for devcn: devmember: cn=alice,ou=users,dc=learn,dc=example dn: cn=alice,ou=users,dc=learn,dc=exampleobjectClass: personobjectClass: topcn: learnsn: learnmemberOf: cn=dev,ou=groups,dc=learn,dc=exampleuserPassword: 1LearnedVaultEOF
Use the
ldapadd
utility to add this configuration.$ ldapadd -cxWD "cn=admin,dc=learn,dc=example" -f learn-vault-example.ldif
When prompted for password, enter
2LearnVault
which was the value ofLDAP_ADMIN_PASSWORD
when starting the docker container. If using an existing OpenLDAP, enter the known administrator password.Successful output:
adding new entry "ou=groups,dc=learn,dc=example"adding new entry "ou=users,dc=learn,dc=example"adding new entry "cn=dev,ou=groups,dc=learn,dc=example"adding new entry "cn=alice,ou=users,dc=learn,dc=example"
Start Vault
In a new terminal start a Vault dev server with
root
as the root token.$ vault server -dev -dev-root-token-id root
The Vault dev server defaults to running at
127.0.0.1:8200
. The server is initialized and unsealed.Insecure operation
Do not run a Vault dev server in production. This approach starts a Vault server with an in-memory database and runs in an insecure way.
In a new terminal export an environment variable for the
vault
CLI to address the Vault server.$ export VAULT_ADDR=http://127.0.0.1:8200
Export an environment variable for the
vault
CLI to authenticate with the Vault server.$ export VAULT_TOKEN=root
The Vault server is ready.
Note
For these tasks, you can use Vault's root token. It's recommended that you use root tokens just for initial setup or in emergencies. As a best practice, use an authentication method or token that meets the policy requirements.
Set an environment variable for the OpenLDAP server address.
$ export OPENLDAP_URL=127.0.0.1:389
You are ready to proceed with the lab.
Step 1: Enable the LDAP secrets engine
(Persona: admin)
The first step is to enable an ldap
secrets engine at the desired path.
Execute the following command to enable the
ldap
secrets engine at the pathldap/
.$ vault secrets enable ldap
Note
If you want to enable the secrets engine at a different path, use the
-path
parameter to specify your desired path. Otherwise, the secrets engine gets enabled at a path named after its type. Since the type isldap
in this example, its path becomesldap
in absence of any-path
parameter.Successful output:
Success! Enabled the ldap secrets engine at: ldap/
Step 2: Configure LDAP secrets engine
(Persona: admin)
You need to configure the LDAP secrets engine with valid credentials. It's common to give Vault the superuser credentials and let Vault manage the auditing and lifecycle credentials; it's much better than having one person manage the credentials.
Configures the LDAP secrets engine using the
ldap
plugin to communicate with the Docker based OpenLDAP container.$ vault write ldap/config \ binddn=cn=admin,dc=learn,dc=example \ bindpass=2LearnVault \ url=ldap://$OPENLDAP_URL
Tip
If your OpenLDAP connection URL is different from this example, be sure to replace the example values with correct
binddn
,bindpass
, andurl
values that match your environment. This user should have the necessary privileges to search and change entry passwords in OpenLDAP.Successful output:
Success! Data written to: ldap/config
Note
While the earlier example uses a default OpenLDAP administrator user, it's recommended that you use a dedicated entry management account specifically for Vault in production environments.
Step 3: Rotate the root credential
A best practice when configuring dynamic secrets engines with Vault is to rotate the credential used in the configuration of a secrets engine (known to Vault as the root credential) after configuring the secrets engine.
This helps to reduce credential exposure, ensures that Vault has exclusive control of the rotated root credential, and guarantees the new root credential is not exposed outside of Vault.
- Rotate the root credential.
$ vault write -f ldap/rotate-root Success! Data written to: ldap/rotate-root
Note
Once rotated by Vault, you cannot retrieve the newly generated root credential.
Step 4: Create a role
(Persona: admin)
Now that you have configured the LDAP secrets engine, the next step is to create a role that maps a name in Vault to an entry in OpenLDAP.
- Create a role named
learn
with a rotation period of 24 hours.
$ vault write ldap/static-role/learn \ dn='cn=alice,ou=users,dc=learn,dc=example' \ username='alice' \ rotation_period="24h"
Example output:
Success! Data written to: ldap/static-role/learn
You can now move on to requesting an OpenLDAP credential from the learn role.
Step 5: Request OpenLDAP credentials
(Persona: alice)
The example user alice authenticated to Vault earlier, and her token has a policy attached which provides the capability needed to request a new OpenLDAP credential from the learn role.
# Request OpenLDAP credential from the learn rolepath "ldap/static-cred/learn" { capabilities = [ "read" ]}
Request a new password by reading the
learn
role.$ vault read ldap/static-cred/learn
Successful output:
Key Value--- -----dn cn=alice,ou=users,dc=learn,dc=examplelast_vault_rotation 2020-03-05T17:06:52.345894964Zpassword pIBLIY9kc2yoiqEFbyibMOlyW0cQCPcKoZ3AC3Nzb8l1fS9Yze7eWtLgMKQqyRg6last_password 9qyplZo3cKb7zWI86kiQgYbEq1cCALlMFtLc2iyzOeNS9yKQWI3MBbCg0ReYyfoProtation_period 24httl 23h59m51susername alice
Generate another set of credentials from the
learn
role and save the password to a variable namedLDAP_PASSWORD
.$ LDAP_PASSWORD=$(vault read --format=json ldap/static-cred/learn | jq -r ".data.password")
With the new password saved as a variable, perform an LDAP search with the generated
password
.$ ldapsearch -b "cn=alice,ou=users,dc=learn,dc=example" \ -D 'cn=alice,ou=users,dc=learn,dc=example' \ -w $LDAP_PASSWORD
The results display the password for this user.
You can learn more about credentials, roles, and rotation from the LDAP secrets engine documentation and LDAP Secrets Engine HTTP API.
Next steps
You can explore a deeper dive into the LDAP secrets engine that further extends the example in this tutorial with a full environment based on Docker containers.
Check out the Docker LDAP Secrets Engine with SSH lab to learn more.