1
1
mirror of https://github.com/docker-mailserver/docker-mailserver synced 2024-12-18 23:14:11 +01:00
docker-mailserver/docs/content/config/account-management/provisioner/ldap.md
Brennan Kinney 0698ad9370
docs: Refactor pages for Account Management (#4122)
* docs: Relocate account / auth pages into a common section

* docs: Update references to relocated pages

* docs: Add account management overview page

Updates remaining links to account sections on this page instead (_for `accounts`, `aliases`, `quotas`_).

This page will cover the features and defer to separate pages for more specific content where relevant.

* docs: Correct relocated pages titles and links

* docs: Accounts (Dovecot Master) - Minor revisions

* docs: Fix highlighting roundcube PHP snippet in OAuth2 page

* docs: Accounts (File) - Refactor

- Manual method not necessary to document.
- Condense `setup` example guidance.
- Quotas / Aliases content migrated to Overview when not specific about file provisioner.

Some of the content is this commit is not a complete revision.

* chore: Temporary commit

* docs(refactor): Sub-addressing section

Much better docs on the sub-addressing feature supported by Postfix and Dovecot, along with the guidance with usage in Sieve.

* docs:  Revise accounts section

Add some context regarding DMS accounts and their distinction/overlap from the email address functionality, and it's relevant context for receiving/sending.

File provisioner, minor revisions to referencing associated config files and account management.

* docs: Minor adjustments

* docs: Refactor the quota section

Better documented with links and coverage over the workaround details we've implemented.

* docs: Revise the quota section

Minor revisions with phrasing, admonitions for structure and better explanation of the feature functionality/purpose.

* docs: Alias section refactor

Extensively covers known issues and technical details that have been discussed often enough.

The improvements should benefit both users and maintainers.

* docs: Refactor master accounts page

This rewrite should more clearly document the feature, along with a better example and additional links for reference.

* docs: OAuth2 revision

Minor update to this page:
- Links extracted to bottom of page as per convention.
- ENV file example converted to preferred `compose.yaml` ENV settings.

* docs: Sieve minor revisions

- Correct link to subaddressing section
- Make the config file example snippets intended filename less ambiguous.
- Minor rephrasng.

* docs: Revise accounts overview section

Revised the account section and added additional clarity for common confusion with relation to sender address and multi-domain support.

Top of the page now clarifies it's a technical reference and directs users to the related pages for configuration / caveats.

Technical Overview links to Dovecot docs were missing.

* docs: Another revision pass

File based provisioner docs:
- Sections indent with info admonitions.
- Accounts section expanded with config format and example.
- Quotas section expanded and shifted to bottom (alphabetical sort).
- Split into `setup` CLI and config reference groups.

Overview page:
- Sections indent with info admonitions.
- Revised content.

* docs(chore): Shift sub-addressing section

This is related to accounts and aliases, but not provisioners, thus extract out of the accounts parent section.

* docs: Document `postfix-accounts.cf` third column

This lacked documentation but was community contributed feature to allow further customization of a Dovecot Account.

It has caveats as DMS does not take these into consideration anywhere in scripts. Documenting officially for better awareness.

* docs: Revise and expand supplementary pages

Better outline the OAuth2 login process, the two supported login mechanisms and their docs/rfcs, along with documenting caveat with mail client compatibility.

Add a verification tip for the OAuth2 support, showing how `curl` can be used, along with caveat presently affecting the `curl` in DMS v14.

Additionally note the feature still isn't documented fully, providing the user with additional references for more information.

`ACCOUNT_PROVISIONER` ENV docs minimized. No `OIDC` provisioner plans, the OAuth2 docs page now mentions SCIM 2.0 API as the next step towards resolving that concern. The tip admonition was removed as it no longer provides value, instead we link to the Account Management overview page.

Dovecot Master Accounts docs page now lightly document the `setup` CLI and config format for the feature.

* docs: Fix broken anchor links

Some anchor links to different parts of our docs have gone stale. This branch also broke a few itself that I missed.

The build now only reports issues with anchor links to Content Tabs, which it must not be aware of during the build (_MKDocs Material specific feature?_)

* docs(lint): Fix indentation level

* chore: Add entry to `CHANGELOG.md` + corrections
2024-07-22 10:00:53 +12:00

16 KiB

title
Account Management | Provisioner (LDAP)

Introduction

Getting started with ldap and DMS we need to take 3 parts in account:

  • postfix for incoming & outgoing email
  • dovecot for accessing mailboxes
  • saslauthd for SMTP authentication (this can also be delegated to dovecot)

Variables to Control Provisioning by the Container

Have a look at the ENV page for information on the default values.

LDAP_QUERY_FILTER_*

Those variables contain the LDAP lookup filters for postfix, using %s as the placeholder for the domain or email address in question. This means that...

  • ...for incoming email, the domain must return an entry for the DOMAIN filter (see virtual_alias_domains).
  • ...for incoming email, the inboxes which receive the email are chosen by the USER, ALIAS and GROUP filters.
    • The USER filter specifies personal mailboxes, for which only one should exist per address, for example (mail=%s) (also see virtual_mailbox_maps)
    • The ALIAS filter specifies aliases for mailboxes, using virtual_alias_maps, for example (mailAlias=%s)
    • The GROUP filter specifies the personal mailboxes in a group (for emails that multiple people shall receive), using virtual_alias_maps, for example (mailGroupMember=%s).
    • Technically, there is no difference between ALIAS and GROUP, but ideally you should use ALIAS for personal aliases for a singular person (like ceo@example.org) and GROUP for multiple people (like hr@example.org).
  • ...for outgoing email, the sender address is put through the SENDERS filter, and only if the authenticated user is one of the returned entries, the email can be sent.
    • This only applies if SPOOF_PROTECTION=1.
    • If the SENDERS filter is missing, the USER, ALIAS and GROUP filters will be used in a disjunction (OR).
    • To for example allow users from the admin group to spoof any sender email address, and to force everyone else to only use their personal mailbox address for outgoing email, you can use something like this: (|(memberOf=cn=admin,*)(mail=%s))

???+ example

A really simple `LDAP_QUERY_FILTER` configuration, using only the _user filter_ and allowing only `admin@*` to spoof any sender addresses.

```yaml
- LDAP_START_TLS=yes
- ACCOUNT_PROVISIONER=LDAP
- LDAP_SERVER_HOST=ldap.example.org
- LDAP_SEARCH_BASE=dc=example,dc=org"
- LDAP_BIND_DN=cn=admin,dc=example,dc=org
- LDAP_BIND_PW=mypassword
- SPOOF_PROTECTION=1

- LDAP_QUERY_FILTER_DOMAIN=(mail=*@%s)
- LDAP_QUERY_FILTER_USER=(mail=%s)
- LDAP_QUERY_FILTER_ALIAS=(|) # doesn't match anything
- LDAP_QUERY_FILTER_GROUP=(|) # doesn't match anything
- LDAP_QUERY_FILTER_SENDERS=(|(mail=%s)(mail=admin@*))
```

DOVECOT_*_FILTER & DOVECOT_*_ATTRS

These variables specify the LDAP filters that dovecot uses to determine if a user can log in to their IMAP account, and which mailbox is responsible to receive email for a specific postfix user.

This is split into the following two lookups, both using %u as the placeholder for the full login name (see dovecot documentation for a full list of placeholders). Usually you only need to set DOVECOT_USER_FILTER, in which case it will be used for both filters.

  • DOVECOT_USER_FILTER is used to get the account details (uid, gid, home directory, quota, ...) of a user.
  • DOVECOT_PASS_FILTER is used to get the password information of the user, and is in pretty much all cases identical to DOVECOT_USER_FILTER (which is the default behavior if left away).

If your directory doesn't have the postfix-book schema installed, then you must change the internal attribute handling for dovecot. For this you have to change the pass_attr and the user_attr mapping, as shown in the example below:

- DOVECOT_PASS_ATTRS=<YOUR_USER_IDENTIFIER_ATTRIBUTE>=user,<YOUR_USER_PASSWORD_ATTRIBUTE>=password
- DOVECOT_USER_ATTRS=<YOUR_USER_HOME_DIRECTORY_ATTRIBUTE>=home,<YOUR_USER_MAILSTORE_ATTRIBUTE>=mail,<YOUR_USER_MAIL_UID_ATTRIBUTE>=uid,<YOUR_USER_MAIL_GID_ATTRIBUTE>=gid

!!! note

For `DOVECOT_*_ATTRS`, you can replace `ldapAttr=dovecotAttr` with `=dovecotAttr=%{ldap:ldapAttr}` for more flexibility, like for example `=home=/var/mail/%{ldap:uid}` or just `=uid=5000`.

A list of dovecot attributes can be found [in the dovecot documentation](https://doc.dovecot.org/configuration_manual/authentication/user_databases_userdb/#authentication-user-database).

???+ example "Defaults"

```yaml
- DOVECOT_USER_ATTRS=mailHomeDirectory=home,mailUidNumber=uid,mailGidNumber=gid,mailStorageDirectory=mail
- DOVECOT_PASS_ATTRS=uniqueIdentifier=user,userPassword=password
- DOVECOT_USER_FILTER=(&(objectClass=PostfixBookMailAccount)(uniqueIdentifier=%n))
```

???+ example

Setup for a directory that has the [qmail-schema](https://github.com/amery/qmail/blob/master/qmail.schema) installed and uses `uid`:

```yaml
- DOVECOT_PASS_ATTRS=uid=user,userPassword=password
- DOVECOT_USER_ATTRS=homeDirectory=home,qmailUID=uid,qmailGID=gid,mailMessageStore=mail
- DOVECOT_USER_FILTER=(&(objectClass=qmailUser)(uid=%u)(accountStatus=active))
```

The LDAP server configuration for dovecot will be taken mostly from postfix, other options can be found in the environment section in the docs.

DOVECOT_AUTH_BIND

Set this to yes to enable authentication binds (more details in the dovecot documentation). Currently, only DN lookup is supported without further changes to the configuration files, so this is only useful when you want to bind as a readonly user without the permission to read passwords.

SASLAUTHD_LDAP_FILTER

This filter is used for saslauthd, which is called by postfix when someone is authenticating through SMTP (assuming that SASLAUTHD_MECHANISMS=ldap is being used). Note that you'll need to set up the LDAP server for saslauthd separately from postfix.

The filter variables are explained in detail in the LDAP_SASLAUTHD file, but unfortunately, this method doesn't really support domains right now - that means that %U is the only token that makes sense in this variable.

!!! note "When to use this and how to avoid it"

Using a separate filter for SMTP authentication allows you to for example allow `noreply@example.org` to send email, but not log in to IMAP or receive email: `(&(mail=%U@example.org)(|(memberOf=cn=email,*)(mail=noreply@example.org)))`

If you don't want to use a separate filter for SMTP authentication, you can set `SASLAUTHD_MECHANISMS=rimap` and `SASLAUTHD_MECH_OPTIONS=127.0.0.1` to authenticate against dovecot instead - this means that the `DOVECOT_USER_FILTER` and `DOVECOT_PASS_FILTER` will be used for SMTP authentication as well.

???+ example "Configure LDAP with saslauthd"

```yaml
- ENABLE_SASLAUTHD=1
- SASLAUTHD_MECHANISMS=ldap
- SASLAUTHD_LDAP_FILTER=(mail=%U@example.org)
```

Secure Connection with LDAPS or StartTLS

To enable LDAPS, all you need to do is to add the protocol to LDAP_SERVER_HOST, for example ldaps://example.org:636.

To enable LDAP over StartTLS (on port 389), you need to set the following environment variables instead (the protocol must not be ldaps:// in this case!):

- LDAP_START_TLS=yes
- DOVECOT_TLS=yes
- SASLAUTHD_LDAP_START_TLS=yes

Active Directory Configurations (Tested with Samba4 AD Implementation)

In addition to LDAP explanation above, when Docker Mailserver is intended to be used with Active Directory (or the equivalent implementations like Samba4 AD DC) the following points should be taken into consideration:

  • Samba4 Active Directory requires a secure connection to the domain controller (DC), either via SSL/TLS (LDAPS) or via StartTLS.
  • The username equivalent in Active Directory is: sAMAccountName.
  • proxyAddresses can be used to store email aliases of single users. The convention is to prefix the email aliases with smtp: (e.g: smtp:some.name@example.com).
  • Active Directory is used typically not only as LDAP Directory storage, but also as a domain controller, i.e., it will do many things including authenticating users. Mixing Linux and Windows clients requires the usage of RFC2307 attributes, namely uidNumber, gidNumber instead of the typical uid. Assigning different owner to email folders can also be done in this approach, nevertheless there is a bug at the moment in Docker Mailserver that overwrites all permissions when starting the container. Either a manual fix is necessary now, or a temporary workaround to use a hard-coded ldap:uidNumber that equals to 5000 until this issue is fixed.
  • To deliver the emails to different members of Active Directory Security Group or Distribution Group (similar to mailing lists), use a user-patches.sh script to modify ldap-groups.cf so that it includes leaf_result_attribute = mail and special_result_attribute = member. This can be achieved simply by:

The configuration shown to get the Group to work is from here and here.

# user-patches.sh

...
grep -q '^leaf_result_attribute = mail$' /etc/postfix/ldap-groups.cf || echo "leaf_result_attribute = mail" >> /etc/postfix/ldap-groups.cf
grep -q '^special_result_attribute = member$' /etc/postfix/ldap-groups.cf || echo "special_result_attribute = member" >> /etc/postfix/ldap-groups.cf
...
  • In /etc/ldap/ldap.conf, if the TLS_REQCERT is demand / hard (default), the CA certificate used to verify the LDAP server certificate must be recognized as a trusted CA. This can be done by volume mounting the ca.crt file and updating the trust store via a user-patches.sh script:
# user-patches.sh

...
cp /MOUNTED_FOLDER/ca.crt /usr/local/share/ca-certificates/
update-ca-certificates
...

The changes on the configurations necessary to work with Active Directory (only changes are listed, the rest of the LDAP configuration can be taken from the other examples shown in this documentation):

# If StartTLS is the chosen method to establish a secure connection with Active Directory.
- LDAP_START_TLS=yes
- SASLAUTHD_LDAP_START_TLS=yes
- DOVECOT_TLS=yes

- LDAP_QUERY_FILTER_USER=(&(objectclass=person)(mail=%s))
- LDAP_QUERY_FILTER_ALIAS=(&(objectclass=person)(proxyAddresses=smtp:%s))
# Filters Active Directory groups (mail lists). Additional changes on ldap-groups.cf are also required as shown above.
- LDAP_QUERY_FILTER_GROUP=(&(objectClass=group)(mail=%s))
- LDAP_QUERY_FILTER_DOMAIN=(mail=*@%s)
# Allows only Domain admins to send any sender email address, otherwise the sender address must match the LDAP attribute `mail`.
- SPOOF_PROTECTION=1
- LDAP_QUERY_FILTER_SENDERS=(|(mail=%s)(proxyAddresses=smtp:%s)(memberOf=cn=Domain Admins,cn=Users,dc=*))

- DOVECOT_USER_FILTER=(&(objectclass=person)(sAMAccountName=%n))
# At the moment to be able to use %{ldap:uidNumber}, a manual bug fix as described above must be used. Otherwise %{ldap:uidNumber} %{ldap:uidNumber} must be replaced by the hard-coded value 5000.
- DOVECOT_USER_ATTRS==uid=%{ldap:uidNumber},=gid=5000,=home=/var/mail/%Ln,=mail=maildir:~/Maildir
- DOVECOT_PASS_ATTRS=sAMAccountName=user,userPassword=password
- SASLAUTHD_LDAP_FILTER=(&(sAMAccountName=%U)(objectClass=person))

LDAP Setup Examples

???+ example "Basic Setup"

```yaml
services:
  mailserver:
    image: ghcr.io/docker-mailserver/docker-mailserver:latest
    container_name: mailserver
    hostname: mail.example.com

    ports:
      - "25:25"
      - "143:143"
      - "587:587"
      - "993:993"

    volumes:
      - ./docker-data/dms/mail-data/:/var/mail/
      - ./docker-data/dms/mail-state/:/var/mail-state/
      - ./docker-data/dms/mail-logs/:/var/log/mail/
      - ./docker-data/dms/config/:/tmp/docker-mailserver/
      - /etc/localtime:/etc/localtime:ro

    environment:
      - ENABLE_SPAMASSASSIN=1
      - ENABLE_CLAMAV=1
      - ENABLE_FAIL2BAN=1
      - ENABLE_POSTGREY=1

      # >>> Postfix LDAP Integration
      - ACCOUNT_PROVISIONER=LDAP
      - LDAP_SERVER_HOST=ldap.example.org
      - LDAP_BIND_DN=cn=admin,ou=users,dc=example,dc=org
      - LDAP_BIND_PW=mypassword
      - LDAP_SEARCH_BASE=dc=example,dc=org
      - LDAP_QUERY_FILTER_DOMAIN=(|(mail=*@%s)(mailAlias=*@%s)(mailGroupMember=*@%s))
      - LDAP_QUERY_FILTER_USER=(&(objectClass=inetOrgPerson)(mail=%s))
      - LDAP_QUERY_FILTER_ALIAS=(&(objectClass=inetOrgPerson)(mailAlias=%s))
      - LDAP_QUERY_FILTER_GROUP=(&(objectClass=inetOrgPerson)(mailGroupMember=%s))
      - LDAP_QUERY_FILTER_SENDERS=(&(objectClass=inetOrgPerson)(|(mail=%s)(mailAlias=%s)(mailGroupMember=%s)))
      - SPOOF_PROTECTION=1
      # <<< Postfix LDAP Integration

      # >>> Dovecot LDAP Integration
      - DOVECOT_USER_FILTER=(&(objectClass=inetOrgPerson)(mail=%u))
      - DOVECOT_PASS_ATTRS=uid=user,userPassword=password
      - DOVECOT_USER_ATTRS==home=/var/mail/%{ldap:uid},=mail=maildir:~/Maildir,uidNumber=uid,gidNumber=gid
      # <<< Dovecot LDAP Integration

      # >>> SASL LDAP Authentication
      - ENABLE_SASLAUTHD=1
      - SASLAUTHD_MECHANISMS=ldap
      - SASLAUTHD_LDAP_FILTER=(&(mail=%U@example.org)(objectClass=inetOrgPerson))
      # <<< SASL LDAP Authentication

      - SSL_TYPE=letsencrypt
      - PERMIT_DOCKER=host

    cap_add:
      - NET_ADMIN
```

??? example "Kopano / Zarafa"

```yaml
services:
  mailserver:
    image: ghcr.io/docker-mailserver/docker-mailserver:latest
    container_name: mailserver
    hostname: mail.example.com

    ports:
      - "25:25"
      - "143:143"
      - "587:587"
      - "993:993"

    volumes:
      - ./docker-data/dms/mail-data/:/var/mail/
      - ./docker-data/dms/mail-state/:/var/mail-state/
      - ./docker-data/dms/config/:/tmp/docker-mailserver/

    environment:
      # We are not using dovecot here
      - SMTP_ONLY=1
      - ENABLE_SPAMASSASSIN=1
      - ENABLE_CLAMAV=1
      - ENABLE_FAIL2BAN=1
      - ENABLE_POSTGREY=1
      - SASLAUTHD_PASSWD=

      # >>> SASL Authentication
      - ENABLE_SASLAUTHD=1
      - SASLAUTHD_LDAP_FILTER=(&(sAMAccountName=%U)(objectClass=person))
      - SASLAUTHD_MECHANISMS=ldap
      # <<< SASL Authentication

      # >>> Postfix Ldap Integration
      - ACCOUNT_PROVISIONER=LDAP
      - LDAP_SERVER_HOST=<yourLdapContainer/yourLdapServer>
      - LDAP_SEARCH_BASE=dc=mydomain,dc=loc
      - LDAP_BIND_DN=cn=Administrator,cn=Users,dc=mydomain,dc=loc
      - LDAP_BIND_PW=mypassword
      - LDAP_QUERY_FILTER_USER=(&(objectClass=user)(mail=%s))
      - LDAP_QUERY_FILTER_GROUP=(&(objectclass=group)(mail=%s))
      - LDAP_QUERY_FILTER_ALIAS=(&(objectClass=user)(otherMailbox=%s))
      - LDAP_QUERY_FILTER_DOMAIN=(&(|(mail=*@%s)(mailalias=*@%s)(mailGroupMember=*@%s))(mailEnabled=TRUE))
      # <<< Postfix Ldap Integration

      # >>> Kopano Integration
      - POSTFIX_DAGENT=lmtp:kopano:2003
      # <<< Kopano Integration

      - SSL_TYPE=letsencrypt
      - PERMIT_DOCKER=host

    cap_add:
      - NET_ADMIN
```