Workshops
Book a 90-minute product workshop led by HashiCorp engineers and product experts during HashiConf Digital Reserve your spot

Vault 1.4 Release Highlights

OpenLDAP Secrets Engine

LDAP is a critical protocol commonly in use with UNIX and Linux applications, with OpenLDAP being the most popular implementation.

The OpenLDAP 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 OpenLDAP and its associated credentials can be summarized as follows.

  • The volume of user entries in an OpenLDAP directory can be difficult to efficiently manage
  • Access to OpenLDAP is required to empower users with credential management capabilities
  • There is a lack of available solutions aimed at automatically rotating OpenLDAP credentials, requiring the use of in house solutions

»Solution

Use the OpenLDAP secrets engine with Vault to provide a variety of authentication methods to users for accessing their own LDAP credentials.

Users can be empowered to manage their own LDAP entries, and their passwords can be configured to be automatically rotated based on a time to live value configured by the administrator.

The following diagram illustrates this credential management workflow.

OpenLDAP Secret Workflow

By making the passwords as short-lived as possible, you reduce the chance that they might be compromised. If an credential is compromised, it can be revoked revoked and rotated rather than changing a global set of credentials.

»Personas

The end-to-end scenario described in this guide involves two personas.

  • admin a Vault administrator with privileged permissions to configure secrets engines
  • alice a user with existing OpenLDAP credential who needs to access a Secure Shell Daemon (sshd) server with this credential password

»Prerequisites

To perform the tasks described in this guide, you need to have the following items.

  • A Vault version 1.4 or later environment; refer to the Getting Started guide to install Vault. Make sure that your Vault server has been initialized and unsealed.

  • 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 provide 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.

»Policy requirements

To perform all tasks demonstrated in this guide, your admin persona policy must include the following capabilities.

# Mount secrets engines
path "sys/mounts/*" {
  capabilities = [ "create", "read", "update", "delete", "list" ]
}

# Configure the openldap secrets engine and create roles
path "openldap/*" {
  capabilities = [ "create", "read", "update", "delete", "list" ]
}

# Write ACL policies
path "sys/policies/acl/*" {
  capabilities = [ "create", "read", "update", "delete", "list" ]
}

# Manage tokens for verification
path "auth/token/create" {
  capabilities = [ "create", "read", "update", "delete", "list", "sudo" ]
}

If you are not familiar with policies, complete the policies guide.

Use a token with these policies attached for all steps performed by the admin persona in this guide.

»Scenario Introduction

In this scenario, you are going to assume two personas, first as admin to configure the OpenLDAP secrets engine, and then as alice to request a new OpenLDAP credential.

  1. Enable the OpenLDAP secrets engine
  2. Configure OpenLDAP secrets engine
  3. Rotate root password
  4. Create a role
  5. Request OpenLDAP credentials

Step 1 through 4 need to be performed by the admin persona. Step 5 describes the commands that the user alice performs to get an OpenLDAP credential from Vault.

»Step 1: Enable the OpenLDAP secrets engine

(Persona: admin)

The first step is to enable an openldap secrets engine at the desired path.

Execute the following command to enable the openldap secrets engine at the path openldap/.

$ vault secrets enable openldap

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 is openldap in this example, its path becomes openldap in absence of any -path parameter.

Successful output:

Success! Enabled the openldap secrets engine at: openldap/

Successful operations against this endpoint are expected to result in no body output. You can confirm that the secrets engine is enabled with a request to the /sys/mounts API.

$ curl \
    --silent \
    --header "X-Vault-Token: $VAULT_TOKEN" \
    $VAULT_ADDR/v1/sys/mounts \
    | jq '.data."openldap/"'

If the secrets engine is enabled, you should observe output like this example.

{
  "accessor": "openldap_18a28534",
  "config": {
    "default_lease_ttl": 0,
    "force_no_cache": false,
    "max_lease_ttl": 0
  },
  "description": "",
  "external_entropy_access": false,
  "local": false,
  "options": null,
  "seal_wrap": false,
  "type": "openldap",
  "uuid": "e3ed93a0-f6ad-c100-03c0-745f0f5b41f4"
}

»Step 2: Configure OpenLDAP secrets engine

(Persona: admin)

The OpenLDAP secrets engine needs to be configured with valid credentials. It is 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.

»Start an OpenLDAP Server

For the purpose of this tutorial, let's run a community based OpenLDAP Docker image in a container.

Use docker run to run an openldap container; options are detailed after the example.

$ 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:latest

The options we use in the example 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, you can verify that it is running.

$ docker ps -f name=vault-openldap --format "table {{.Names}}\t{{.Status}}"
NAMES               STATUS
vault-openldap      Up 9 seconds

»Configure OpenLDAP with example data

With the OpenLDAP container now available, we can add some initial configuration including groups and the example user, alice.

Example: learn-vault-example.ldif

$ cat > learn-vault-example.ldif <<EOF
dn: ou=groups,dc=learn,dc=example
objectClass: organizationalunit
objectClass: top
ou: groups
description: groups of users

dn: ou=users,dc=learn,dc=example
objectClass: organizationalunit
objectClass: top
ou: users
description: users

dn: cn=dev,ou=groups,dc=learn,dc=example
objectClass: groupofnames
objectClass: top
description: testing group for dev
cn: dev
member: cn=alice,ou=users,dc=learn,dc=example

dn: cn=alice,ou=users,dc=learn,dc=example
objectClass: person
objectClass: top
cn: learn
sn: learn
memberOf: cn=dev,ou=groups,dc=learn,dc=example
userPassword: 1LearnedVault
EOF

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 of LDAP_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"

Now you are ready to configure the OpenLDAP secrets engine in Vault.

The following command configures the OpenLDAP secrets engine using the openldap plugin to communicate with our Docker based OpenLDAP container.

$ vault write openldap/config \
    binddn=cn=admin,dc=learn,dc=example \
    bindpass=2LearnVault \
    url=ldap://127.0.0.1

Successful output:

Success! Data written to: openldap/config

»Step 3: Rotate the root credential

It is a best practice when configuring dynamic secrets engines with Vault to rotate the credential used in the configuration of a secrets engine (known to Vault as the root credential) immediately after configuring the secrets engine.

This helps to minimize exposure of the configured credential, ensures that Vault has exclusive control of the rotated root credential, and guarantees that the new root credential is not exposed outside of Vault.

With that in mind, let's rotate the root credential now so that you can get acquainted with the process.

$ vault write -f openldap/rotate-root

Successful output:

Success! Data written to: openldap/rotate-root

»Step 4: Create a role

(Persona: admin)

Now that you have successfully configured the OpenLDAP secrets engine, the next step is to create a role that maps a name in Vault to an entry in OpenLDAP.

Example:

$ vault write openldap/static-role/learn \
    dn='cn=alice,ou=users,dc=learn,dc=example' \
    username='alice' \
    rotation_period="24h"

Successfully adding the role results in output like this:

Success! Data written to: openldap/static-role/learn

You can now move on to requesting an OpenLDAP credential from the learn role.

»Step 5: Request OpenLDAP credentials

(Persona: alice)

Our example user alice has previously authenticated to Vault 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 role
path "openldap/static-cred/learn" {
  capabilities = [ "read" ]
}

Alice's token id value should be used as the value of VAULT_TOKEN in the following API steps performed as alice.

Finally, using an example application token as previously described, you can use this command to read from the role to request a credential.

$ vault read openldap/static-cred/learn

Successful output:

Key                    Value
---                    -----
dn                     cn=alice,ou=users,dc=learn,dc=example
last_vault_rotation    2020-03-05T17:06:52.345894964Z
password               pIBLIY9kc2yoiqEFbyibMOlyW0cQCPcKoZ3AC3Nzb8l1fS9Yze7eWtLgMKQqyRg6
rotation_period        24h
ttl                    23h59m51s
username               alice

There is more to learn about credentials, roles, and rotation from the OpenLDAP secrets engine documentation and OpenLDAP Secrets Engine HTTP API.

»Next steps

You can explore a deeper dive into the OpenLDAP secrets engine that further extends the example in this guide with a full environment based on Docker containers.

Please check out the Docker OpenLDAP Secrets Engine with SSH Demonstration to learn more.

»Help and reference