Skip to main content

LDAP Backend

The LDAP backend allows Nauthilus to authenticate users against LDAP directories such as OpenLDAP, Active Directory, or other LDAP-compatible servers.

Structure

The LDAP section has two keywords config and search. The first is used for the backend configuration, the latter for certain protocols.

Configuration Options

ldap::config

The config section defines the main pool settings and one or more LDAP servers. The principal of work is that Nauthilus tries to connect to the first available server. If a server connection fails, Nauthilus tries to reconnect to an LDAP server in the order that was defined.

The following table lists keys and examples to configure LDAP:

KeyRequiredDescriptionExample
number_of_workersnoNumber of LDAP workers to use. If not specified, defaults to 10.10
lookup_pool_sizenoMaximum number of connection that can be opened8
lookup_idle_pool_sizenoMinimum number of connections that must be kept open2
auth_pool_sizenoMaximum number of connection that can be opened8
auth_idle_pool_sizenoMinimum number of connections that must be kept open2
server_uriyesA string containing a LDAP URI or a list of URIsldap://localhost:389/
bind_dnnoThe distinguished name (DN) to use for binding to the LDAP server when using simple bind authenticationcn=admin,dc=example,dc=com
bind_pwnoThe password to use for binding to the LDAP server when using simple bind authenticationsecret
starttlsnoIs STARTTLS used with the LDAP connectiontrue / false
tls_skip_verifynoIf you use self signed certificates, you may to skip TLS verificationtrue / false
sasl_externalnoUse simple bind or SASL/EXTERNALtrue / false
pool_onlynoUse Lua to communicate with LDAPtrue / false
connect_abort_timeoutnoNew in version 1.4.12:
If a pool is exhausted and a new connection can not be established within connect_abort_timeout, the request will temp-fail.
10s (default). Maximum 10m is allowed

ldap::optional_ldap_pools

New in version 1.5.0

This section allows you to define additional LDAP pools with different configurations. This is useful when you need to connect to multiple LDAP servers with different settings.

ldap:
optional_ldap_pools:
pool1:
lookup_pool_size: 5
lookup_idle_pool_size: 1
auth_pool_size: 5
auth_idle_pool_size: 1
server_uri: ldap://ldap1.example.com:389/
starttls: true
tls_skip_verify: false
pool2:
lookup_pool_size: 3
lookup_idle_pool_size: 1
auth_pool_size: 3
auth_idle_pool_size: 1
server_uri: ldap://ldap2.example.com:389/
starttls: true
tls_skip_verify: false

You can then reference these pools in your search configurations using the pool_name parameter:

ldap:
search:
- protocol: imap
cache_name: dovecot
pool_name: pool1
base_dn: ou=people,ou=it,dc=example,dc=com
# ...

SASL/EXTERNAL Configuration

If using SASL/EXTERNAL:

KeyRequiredDescriptionExample
tls_ca_cert(yes) if starttls is enabledCA bundle or CA file in PEM format/path/to/company/ca-file.pem
tls_client_cert(yes)X509 client certificate in PEM format/path/to/client/cert.pem
tls_client_key(yes)X509 client key in PEM format/path/to/client/key.pem

Note:

Make sure to remove a key passphrase from the key.

Pooling

Nauthilus will open as many connections, as the *_idle_pool_size value defines. All other connections are done on demand. A background thread (30 seconds delay) will observe a pool and will close unused connections.

If a new connection is required, Nauthilus first checks, if there is some free connection available and picks it up. If none is free, a new connection is opened. If the pool is exhausted, requests are enqueued until a new connection is free again.

Bind Method

Nauthilus can either do a so-called simple bind, using a bind DN and a bind password, or it can do SASL/EXTERNAL using a X509 client certificate and key. Please check your LDAP configuration to find out, which mode is available for you.

Search Configuration

ldap::search

This section defines blocks that combine protocols and LDAP filters. Here is a table of keys that are known:

Definition of a search list

KeyRequiredDescriptionExample
protocolyesA protocol name or a list of protocols in YAML formatimap
cache_namenoA namespace for the Redis cachedovecot
pool_namenoThe name of the LDAP pool to use for this search. If not specified, the default pool is used.pool1
base_dnyesThe LDAP base DN for the queries
filteryesSection of LDAP filters-
mappingyesQuery result attribute/logic mapping-
attributeyesOne string representing an attribute from the user object or a YAML-list of attributes from an user object. The results are used either in HTTP-response-headers with a X-Nauthilus-Attributename or used to assemble Open ID token claimsuid

Filter Configuration

KeyRequiredDescriptionExample
useryesLDAP filter to retrieve a user DN for a re-bind operationExample see below
list_accountsnoNauthilus may return a list of known account names in an HTTP response, if the GET query string contains mode=list-accountsExample see below
webauthn_credentialsnoLDAP filter to retrieve WebAuthn credentials for a userExample see below

Mapping Configuration

KeyRequiredDescriptionExample
account_fieldyesThis result of this attribute is returned as the user accountuid
totp_secret_fieldnoTell Nauthilus which field is used for the TOTP secret keyrns2FATOTPSecret
totp_recovery_fieldnoTell Nauthilus which field is used for the TOTP recovery codesrns2FATOTPRecoveryCode
display_name_fieldnoTell Nauthilus which field is used for the display namecn
credential_objectnoTell Nauthilus which object class is used for WebAuthn credentialsrns2FAWebAuthn
credential_id_fieldnoTell Nauthilus which field is used for the WebAuthn credential IDrns2FAWebAuthnCredID
public_key_fieldnoTell Nauthilus which field is used for the WebAuthn public keyrns2FAWebAuthnPubKey
unique_user_id_fieldnoTell Nauthilus which field is used for the WebAuthn unique user IDentryUUID
aaguid_fieldnoTell Nauthilus which field is used for the WebAuthn AAGUIDrns2FAWebAuthnAAGUID
sign_count_fieldnoTell Nauthilus which field is used for the WebAuthn sign countrns2FAWebAuthnSignCount

Example Configuration

ldap:
config:
number_of_workers: 10
lookup_pool_size: 8
lookup_idle_pool_size: 2
auth_pool_size: 8
auth_idle_pool_size: 2

server_uri: ldap://some.server:389/
bind_dn: cn=admin,dc=example,dc=com
bind_pw: secret
starttls: true
tls_skip_verify: true
sasl_external: true
tls_ca_cert: /path/to/cacert.pem
tls_client_cert: /path/to/client/cert.pem
tls_client_key: /path/to/client/key.pem

search:
- protocol: http
cache_name: http
base_dn: ou=people,ou=it,dc=example,dc=com
filter:
user: |
(|
(uniqueIdentifier=%L{user})
(rnsMSRecipientAddress=%L{user})
)
mapping:
account_field: rnsMSDovecotUser
attribute: rnsMSDovecotUser

- protocol:
- imap
- pop3
- lmtp
- sieve
- doveadm
- indexer-worker
- default
cache_name: dovecot
base_dn: ou=people,ou=it,dc=example,dc=com
filter:
user: |
(&
(objectClass=rnsMSDovecotAccount)
(|
(uniqueIdentifier=%L{user})
(rnsMSRecipientAddress=%L{user})
)
)
list_accounts: |
(&
(objectClass=rnsMSDovecotAccount)
(rnsMSEnableDovecot=TRUE)
(!
(rnsMSDovecotMaster=TRUE)
)
)
mapping:
account_field: rnsMSDovecotUser
attribute:
- uid
- rnsMSQuota
- rnsMSOverQuota
- rnsMSMailboxHome
- rnsMSMailPath
- rnsMSDovecotFTS
- rnsMSDovecotFTSSolrUrl
- rnsMSACLGroups
- rnsMSDovecotUser

TOTP Schema Example

If you need a schema for the TOTP stuff, you could use the following draft:

objectidentifier RNSRoot     1.3.6.1.4.1.31612
objectidentifier RNSLDAP RNSRoot:1
objectidentifier RNS2FA RNSLDAP:4
objectidentifier RNSLDAPat RNS2FA:1
objectidentifier RNSLDAPoc RNS2FA:2

attributetype ( RNSLDAPat:1
NAME 'rns2FATOTPSecret'
DESC 'TOTP secret'
EQUALITY caseExactMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
SINGLE-VALUE )

attributetype ( RNSLDAPat:2
NAME 'rns2FATOTPRecoveryCode'
DESC 'TOTP backup recovery code'
EQUALITY caseExactMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )

objectclass ( RNSLDAPoc:1
NAME 'rns2FATOTP'
DESC 'Time-based one-time passwords with backup recovery codes'
SUP top AUXILIARY
MAY ( rns2FATOTPSecret $ rns2FATOTPRecoveryCode ) )

It will be enhanced over time to support webauthn as well.