# Azure LDAP

Bindplane's LDAP authentication support can be configured to work with [Azure Entra ID](https://learn.microsoft.com/en-us/entra/architecture/auth-ldap).

This guide will walk you through the process of configuring Bindplane to use Azure Entra's LDAP\
functionality as an authentication backend.

### Prerequisites

You must have access to an existing Azure account, with permissions to manage users and [Microsoft Entra Domain Services](https://learn.microsoft.com/en-us/entra/identity/domain-services/overview).

You must create or have access to an existing Domain Service. You can follow [this Microsoft tutorial](https://learn.microsoft.com/en-us/entra/identity/domain-services/tutorial-create-instance).

If running outside of Azure, you must enable "secure LDAP" and "Allow secure LDAP access over the internet". See [the documentation](https://learn.microsoft.com/en-us/entra/identity/domain-services/tutorial-configure-ldaps#enable-secure-ldap-for-microsoft-entra-domain-services) for details.

You must have DNS configured so the Bindplane server can resolve the Azure Entra Domain Services hostname.

### Bindplane Configuration

Bindplane can be configured using the [Initialization Command](#initialization-command) when operating Bindplane on a Linux server. If using Kubernetes, see the [Kubernetes](#kubernetes) configuration section.

#### Initialization Command

On your Bindplane server, execute the `init` command.

```bash
sudo BINDPLANE_CONFIG_HOME=/var/lib/bindplane \
    /usr/local/bin/bindplane init server \
    --config /etc/bindplane/config.yaml
```

Follow the prompts until you reach the authentication questions.

* Select "Active Directory" when prompted for an authentication method.
* Provide your Directory Services IP address.
  * If Bindplane is operating outside of the Azure environment, provide the "Secure LDAP external IP addresses".
* Provide the LDAP port.
  * `389` if operating within the Azure environment, without TLS.
  * `636` if operating with TLS, from within or outside of the Azure environment.

If you want to use TLS, choose yes when prompted. TLS is required when operating outside of the Azure environment. It is recommended that you select "No" when prompted to skip TLS verification and provide a certificate authority in the next prompt.

If using TLS, you must choose yes when prompted for mutual TLS, and private a certificate and private key.

{% hint style="info" %}
**NOTE**

The certificate authority and mutual TLS keypair files must be readable by the `bindplane` Linux user.
{% endhint %}

When prompted to configure the "Base DN", provide your domain services base dn. For example, if your Domain services name is `bindplane-ldap.onmicrosoft.com`, your Base DN will be `dc=bindplane-ldap,dc=onmicrosoft,dc=com`

{% hint style="info" %}
**NOTE**

The Base DN can be extended to include organizational units, using the following syntax:\
`ou=myou,dc=bindplane-ldap,dc=onmicrosoft,dc=com`
{% endhint %}

When prompted for the Use Search Filter, input `(userPrincipalName=%s)`. This will allow users to log in to Bindplane using their Entra ID email address. e.g. `user@myazureaccount.onmicrosoft.com`.

When prompted for the bind username and password, provide the user principal and password for your bind user. This user must have permission to bind to the domain services LDAP server.

**Example Configuration**

Once the configuration is initialized, the `auth` section will look like this:

```yaml
auth:
  type: active-directory
  ldap:
    protocol: ldaps
    server: bindplane-ldap.onmicrosoft.com
    port: "636"
    baseDN: dc=bindplane-ldap,dc=onmicrosoft,dc=com
    bindUser: user@serviceazureaccount.onmicrosoft.com
    bindPassword: mypassword
    searchFilter: (userPrincipalName=%s)
    tls:
      tlsCert: /etc/bindplane/azure_ldap/bindplane.crt
      tlsKey: /etc/bindplane/azure_ldap/bindplane.key
      tlsCa:
        - /etc/bindplane/azure_ldap/ca.crt
```

In this example, the domain services hostname is `bindplane-ldap.onmicrosoft.com` and the certificate is valid for the hostname `bindplane-ldap.onmicrosoft.com`.

The TLS certificates and private key are located at `/etc/bindplane/azure_ldap` with the following\
permissions.

```
-rw-r--r-- 1 bindplane bindplane  737 Apr 23 12:42 bindplane.crt
-rw-r--r-- 1 bindplane bindplane  227 Apr 23 12:42 bindplane.key
-rw-r--r-- 1 bindplane bindplane  619 Apr 23 12:42 ca.crt
```

**High Availability**

If operating Bindplane in high availability, make sure the configuration changes to the `auth` section\
of the configuration file are copied to the other servers.

#### Kubernetes

The [Bindplane Helm Chart](https://github.com/observIQ/bindplane-op-helm) v1.10.0 or newer supports Azure LDAP. See the [Readme](https://github.com/observIQ/bindplane-op-helm/tree/main/charts/bindplane) and the [Initialization](#initialization-command) section on this page for details on each option.

Before you begin, make sure a secret containing the TLS certificates exists in the namespace that Bindplane is deployed to.

```bash
kubectl create secret generic ldap-tls \
  --from-file ca.crt \
  --from-file bindplane.crt \
  --from-file bindplane.key
```

Update your values file with the following options. Make sure to update them to reflect your environment.

```yaml
auth:
  type: active-directory
  ldap:
    protocol: ldaps
    server: bindplane-ldap.onmicrosoft.com
    port: "636"
    baseDN: dc=bindplane-ldap,dc=onmicrosoft,dc=com
    bindUser: user@serviceazureaccount.onmicrosoft.com
    bindPassword: mypassword
    searchFilter: (userPrincipalName=%s)
    tls:
      insecure: false
      ca:
        secret: ldap-tls
        subPath: ca.crt
      clientKeyPair:
        secret: ldap-tls
        crtSubPath: bindplane.crt
        keySubPath: bindplane.key
```

Update your Helm deployment with the new options.

### Troubleshooting

You can use the [ldapsearch](https://docs.ldap.com/ldap-sdk/docs/tool-usages/ldapsearch.html) utility to interface with Azure LDAP. It is useful for validating your certificate, bind user, and base DN.

Example usage:

```bash
export LDAPTLS_CERT="bindplane.crt"
export LDAPTLS_KEY="bindplane.key"
export LDAPTLS_CACERT="ca.crt"

ldapsearch \
    -x \
    -H ldaps://ldap.bindplane-ldap.onmicrosoft.com \
    -D user@account.onmicrosoft.com \
    -w 'password' \
    -b "dc=bindplane-ldap,dc=onmicrosoft,dc=com"
```

Make sure to update the LDAP connection string (`-H`), bind user (`-D`) bind password (`-w`) and\
base dn (`-b`).

### Resources

* [Azure Identity Documentation](https://learn.microsoft.com/en-us/entra/identity/)
* [LDAP authentication with Microsoft Entra ID](https://learn.microsoft.com/en-us/entra/architecture/auth-ldap)
* [What is Microsoft Entra Domain Services?](https://learn.microsoft.com/en-us/entra/identity/domain-services/overview)
* [Tutorial: Create and configure a Microsoft Entra Domain Services managed domain](https://learn.microsoft.com/en-us/entra/identity/domain-services/tutorial-create-instance)
* [Enable secure LDAP for Microsoft Entra Domain Services](https://learn.microsoft.com/en-us/entra/identity/domain-services/tutorial-configure-ldaps#enable-secure-ldap-for-microsoft-entra-domain-services)
* [LDAP Search Utility](https://docs.ldap.com/ldap-sdk/docs/tool-usages/ldapsearch.html)
