diff --git a/docs/content/config/account-management/overview.md b/docs/content/config/account-management/overview.md index 8e8d264e..bdb883ec 100644 --- a/docs/content/config/account-management/overview.md +++ b/docs/content/config/account-management/overview.md @@ -53,7 +53,7 @@ This page provides a technical reference for account management in DMS. ??? warning "Choosing a compatible email address" - An email address should conform to the standard [permitted charset and format](https://stackoverflow.com/questions/2049502/what-characters-are-allowed-in-an-email-address/2049510#2049510) (`local-part@domain-part`). + An email address should conform to the standard [permitted charset and format][email-syntax::valid-charset-format] (`local-part@domain-part`). --- @@ -223,6 +223,7 @@ This page provides a technical reference for account management in DMS. [docs::account-auth::oauth2]: ./supplementary/oauth2.md [docs::account-auth::master-accounts]: ./supplementary/master-accounts.md [docs::examples::auth-lua]: ../../../examples/use-cases/auth-lua.md +[email-syntax::valid-charset-format]: https://stackoverflow.com/questions/2049502/what-characters-are-allowed-in-an-email-address/2049510#2049510 [postfix-docs::virtual-alias]: http://www.postfix.org/VIRTUAL_README.html#virtual_alias [postfix-docs::recipient-delimiter]: http://www.postfix.org/postconf.5.html#recipient_delimiter diff --git a/docs/content/config/account-management/provisioner/file.md b/docs/content/config/account-management/provisioner/file.md index d86b9265..5b74ffcc 100644 --- a/docs/content/config/account-management/provisioner/file.md +++ b/docs/content/config/account-management/provisioner/file.md @@ -51,6 +51,8 @@ The best way to manage DMS accounts and related config files is through our `set ## Config Reference +These config files belong to the [Config Volume][docs::volumes::config]. + ### Accounts !!! info @@ -194,6 +196,7 @@ The best way to manage DMS accounts and related config files is through our `set hello@example.com:5G ``` +[docs::volumes::config]: ../../advanced/optional-config.md#volumes-config [gh-issue::provisioner-file::accounts-extra-fields]: https://github.com/docker-mailserver/docker-mailserver/issues/4117 [gh-issue::feature-request::allow-account-alias-overlap]: https://github.com/docker-mailserver/docker-mailserver/issues/3528 [gh-issue::bugs::account-alias-overlap-problem]: https://github.com/docker-mailserver/docker-mailserver/issues/3350#issuecomment-1550528898 diff --git a/docs/content/config/account-management/supplementary/master-accounts.md b/docs/content/config/account-management/supplementary/master-accounts.md index bcab6cd1..a8665a83 100644 --- a/docs/content/config/account-management/supplementary/master-accounts.md +++ b/docs/content/config/account-management/supplementary/master-accounts.md @@ -1,46 +1,63 @@ --- title: 'Account Management | Master Accounts (Dovecot)' +hide: + - toc # Hide Table of Contents for this page --- -## Introduction - -A master account: - -- Can login as any user (DMS account) and access their mailbox. -- Is not associated to a separate DMS account, nor is it a DMS account itself. - This feature is useful for administrative tasks like hot backups. !!! note - This feature is presently [not supported with LDAP][dms::feature::dovecot-master-accounts::caveat-ldap] account provisioning. + This feature is presently [not supported with `ACCOUNT_PROVISIONER=LDAP`][dms::feature::dovecot-master-accounts::caveat-ldap]. +!!! info + + A _Master Account_: + + - Can login as any user (DMS account) and access their mailbox. + - Is not associated to a separate DMS account, nor is it a DMS account itself. + + --- + + **`setup` CLI support** + + Use the `setup dovecot-master ` commands. These are roughly equivalent to the `setup email` subcommands. + + --- + + **Config file:** `docker-data/dms/config/dovecot-masters.cf` + + The config format is the same as [`postfix-accounts.cf` for `ACCOUNT_PROVISIONER=FILE`][docs::account-management::file::accounts]. + + The only difference is the account field has no `@domain-part` suffix, it is only a username. ??? abstract "Technical Details" - [The _Master Accounts_ feature][dms::feature::dovecot-master-accounts] in DMS configures the [Dovecot Master Users][dovecot-docs::auth::master-users] feature with the Dovecot setting [`auth_master_user_separator`][dovecot-docs::config::auth-master-user-separator] using the upstream default value (`*`). - -## Configuration - -The DMS `setup` CLI can create, update, delete, and list master accounts. Run `setup help` for usage. + [The _Master Accounts_ feature][dms::feature::dovecot-master-accounts] in DMS configures the [Dovecot Master Users][dovecot-docs::auth::master-users] feature with the Dovecot setting [`auth_master_user_separator`][dovecot-docs::config::auth-master-user-separator] (_where the default value is `*`_). ## Login via Master Account -To login as another DMS account (`user@example.com`) with POP3/IMAP, use the following credentials format: +!!! info -- Username: `*` (`user@example.com*admin`) -- Password: `` + To login as another DMS account (`user@example.com`) with POP3 or IMAP, use the following credentials format: + + - Username: `*` (`user@example.com*admin`) + - Password: `` !!! example "Verify login functionality" In the DMS container, you can verify with the `testsaslauthd` command: ```bash - # A regular DMS account to test login through a master account: + # Prerequisites: + # A regular DMS account to test login through a Master Account: setup email add user@example.com secret - # Add a new master account: + # Add a new Master Account: setup dovecot-master add admin top-secret + ``` + ```bash + # Login with credentials format as described earlier: testsaslauthd -u 'user@example.com*admin' -p 'top-secret' ``` @@ -50,3 +67,4 @@ To login as another DMS account (`user@example.com`) with POP3/IMAP, use the fol [dms::feature::dovecot-master-accounts::caveat-ldap]: https://github.com/docker-mailserver/docker-mailserver/pull/2535#issuecomment-1118056745 [dovecot-docs::auth::master-users]: https://doc.dovecot.org/configuration_manual/authentication/master_users/ [dovecot-docs::config::auth-master-user-separator]: https://doc.dovecot.org/settings/core/#core_setting-auth_master_user_separator +[docs::account-management::file::accounts]: ../provisioner/file.md#accounts diff --git a/docs/content/config/account-management/supplementary/oauth2.md b/docs/content/config/account-management/supplementary/oauth2.md index e683e760..fb74aeec 100644 --- a/docs/content/config/account-management/supplementary/oauth2.md +++ b/docs/content/config/account-management/supplementary/oauth2.md @@ -1,21 +1,81 @@ --- title: 'Account Management | OAuth2 Support' +hide: + - toc # Hide Table of Contents for this page --- -## Introduction +# Authentication - OAuth2 / OIDC -!!! warning "This is only a supplement to the existing account provisioners" +This feature enables support for delegating DMS account authentication through to an external _Identity Provider_ (IdP). - Accounts must still be managed via the configured [`ACCOUNT_PROVISIONER`][docs::env::account-provisioner] (`FILE` or `LDAP`). +!!! warning "Receiving mail requires a DMS account to exist" - Reasoning for this can be found in [#3480][gh-pr::oauth2]. Future iterations on this feature may allow it to become a full account provisioner. + If you expect DMS to receive mail, you must provision an account into DMS in advance. Otherwise DMS has no awareness of your externally manmaged users and will reject delivery. -[gh-pr::oauth2]: https://github.com/docker-mailserver/docker-mailserver/pull/3480 -[docs::env::account-provisioner]: ../../environment.md#account_provisioner + There are [plans to implement support to provision users through a SCIM 2.0 API][dms-feature-request::scim-api]. An IdP that can operate as a SCIM Client (eg: Authentik) would then integrate with DMS for user provisioning. Until then you must keep your user accounts in sync manually via your configured [`ACCOUNT_PROVISIONER`][docs::env::account-provisioner]. -The present OAuth2 support provides the capability for 3rd-party applications such as Roundcube to authenticate with DMS (dovecot) by using a token obtained from an OAuth2 provider, instead of passing passwords around. +??? info "How the feature works" -## Example (Authentik with Roundcube) + 1. A **mail client must have support** to acquire an OAuth2 token from your IdP (_however many clients lack generic OAuth2 / OIDC provider support_). + 2. The mail client then provides that token as the user password via the login mechanism `XOAUTH2` or `OAUTHBEARER`. + 3. DMS (Dovecot) will then check the validity of that token against the Authentication Service it was configured with. + 4. If the response returned is valid for the user account, authentication is successful. + + [**XOAUTH2**][google::xoauth2-docs] (_Googles widely adopted implementation_) and **OAUTHBEARER** (_the newer variant standardized by [RFC 7628][rfc::7628] in 2015_) are supported as standards for verifying that a OAuth Bearer Token (_[RFC 6750][rfc::6750] from 2012_) is valid at the identity provider that created the token. The token itself in both cases is expected to be can an opaque _Access Token_, but it is possible to use a JWT _ID Token_ (_which encodes additional information into the token itself_). + + A mail client like Thunderbird has limited OAuth2 / OIDC support. The software maintains a hard-coded list of providers supported. Roundcube is a webmail client that does have support for generic providers, allowing you to integrate with a broader range of IdP services. + + --- + + **Documentation for this feature is WIP** + + See the [initial feature support][dms-feature::oauth2-pr] and [existing issues][dms-feature::oidc-issues] for guidance that has not yet been documented officially. + +??? tip "Verify authentication works" + + If you have a compatible mail client you can verify login through that. + + --- + + ??? example "CLI - Verify with `curl`" + + ```bash + # Shell into your DMS container: + docker exec -it dms bash + + # Adjust these variables for the methods below to use: + export AUTH_METHOD='OAUTHBEARER' USER_ACCOUNT='hello@example.com' ACCESS_TOKEN='DMS_YWNjZXNzX3Rva2Vu' + + # Authenticate via IMAP (Dovecot): + curl --silent --url 'imap://localhost:143' \ + --login-options "AUTH=${AUTH_METHOD}" --user "${USER_ACCOUNT}" --oauth2-bearer "${ACCESS_TOKEN}" \ + --request 'LOGOUT' \ + && grep "dovecot: imap-login: Login: user=<${USER_ACCOUNT}>, method=${AUTH_METHOD}" /var/log/mail/mail.log + + # Authenticate via SMTP (Postfix), sending a mail with the same sender(from) and recipient(to) address: + # NOTE: `curl` seems to require `--upload-file` with some mail content provided to test SMTP auth. + curl --silent --url 'smtp://localhost:587' \ + --login-options "AUTH=${AUTH_METHOD}" --user "${USER_ACCOUNT}" --oauth2-bearer "${ACCESS_TOKEN}" \ + --mail-from "${USER_ACCOUNT}" --mail-rcpt "${USER_ACCOUNT}" --upload-file - <<< 'RFC 5322 content - not important' \ + && grep "postfix/submission/smtpd.*, sasl_method=${AUTH_METHOD}, sasl_username=${USER_ACCOUNT}" /var/log/mail/mail.log + ``` + + --- + + **Troubleshooting:** + + - Add `--verbose` to the curl options. This will output the protocol exchange which includes if authentication was successful or failed. + - The above example chains the `curl` commands with `grep` on DMS logs (_for Dovecot and Postfix services_). When not running `curl` from the DMS container, ensure you check the logs correctly, or inspect the `--verbose` output instead. + + !!! warning "`curl` bug with `XOAUTH2`" + + [Older releases of `curl` have a bug with `XOAUTH2` support][gh-issue::curl::xoauth2-bug] since `7.80.0` (Nov 2021) but fixed from `8.6.0` (Jan 2024). It treats `XOAUTH2` as `OAUTHBEARER`. + + If you use `docker exec` to run `curl` from within DMS, the current DMS v14 release (_Debian 12 with curl `7.88.1`_) is affected by this bug. + +## Config Examples + +### Authentik with Roundcube This example assumes you have already set up: @@ -69,6 +129,16 @@ This example assumes you have already set up: $config['oauth_login_redirect'] = false; ``` +[dms-feature::oauth2-pr]: https://github.com/docker-mailserver/docker-mailserver/pull/3480 +[dms-feature::oidc-issues]: https://github.com/docker-mailserver/docker-mailserver/issues?q=label%3Afeature%2Fauth-oidc +[docs::env::account-provisioner]: ../../environment.md#account_provisioner +[dms-feature-request::scim-api]: https://github.com/docker-mailserver/docker-mailserver/issues/4090 + +[google::xoauth2-docs]: https://developers.google.com/gmail/imap/xoauth2-protocol#the_sasl_xoauth2_mechanism +[rfc::6750]: https://datatracker.ietf.org/doc/html/rfc6750 +[rfc::7628]: https://datatracker.ietf.org/doc/html/rfc7628 +[gh-issue::curl::xoauth2-bug]: https://github.com/curl/curl/issues/10259#issuecomment-1907192556 + [authentik::docs::install]: https://goauthentik.io/docs/installation/ [roundcube::dockerhub-image]: https://hub.docker.com/r/roundcube/roundcubemail [roundcube::docs::install]: https://github.com/roundcube/roundcubemail/wiki/Installation diff --git a/docs/content/config/environment.md b/docs/content/config/environment.md index 9fcabb0b..2ebd092c 100644 --- a/docs/content/config/environment.md +++ b/docs/content/config/environment.md @@ -47,24 +47,12 @@ The Group ID assigned to the static vmail group for `/var/mail` (_Mail storage m ##### ACCOUNT_PROVISIONER -Configures the provisioning source of user accounts (including aliases) for user queries and authentication by services managed by DMS (_Postfix and Dovecot_). +Configures the [provisioning source of user accounts][docs::account-management::overview] (including aliases) for user queries and authentication by services managed by DMS (_Postfix and Dovecot_). -!!! tip "OAuth2 Support" - - Presently DMS supports OAuth2 only as an supplementary authentication method. - - - A third-party service must provide a valid token for the user which Dovecot validates with the authentication service provider. To enable this feature reference the [OAuth2 configuration example guide][docs::auth::oauth2-config-guide]. - - User accounts must be provisioned to receive mail via one of the supported `ACCOUNT_PROVISIONER` providers. - - User provisioning via OIDC is planned for the future, see [this tracking issue](https://github.com/docker-mailserver/docker-mailserver/issues/2713). - -[docs::auth::oauth2-config-guide]: ./account-management/supplementary/oauth2.md - -- **empty** => use FILE +- **FILE** => use local files - LDAP => use LDAP authentication -- OIDC => use OIDC authentication (**not yet implemented**) -- FILE => use local files (this is used as the default) -A second container for the ldap service is necessary (e.g. [`bitnami/openldap`](https://hub.docker.com/r/bitnami/openldap/)). +LDAP requires an external service (e.g. [`bitnami/openldap`](https://hub.docker.com/r/bitnami/openldap/)). ##### PERMIT_DOCKER @@ -1141,6 +1129,7 @@ Provide the credentials to use with `RELAY_HOST` or `DEFAULT_RELAY_HOST`. [docs-tls-manual]: ./security/ssl.md#bring-your-own-certificates [docs-tls-selfsigned]: ./security/ssl.md#self-signed-certificates [docs-accounts-quota]: ./account-management/overview.md#quotas +[docs::account-management::overview]: ./account-management/overview.md [docs::relay-host]: ./advanced/mail-forwarding/relay-hosts.md [docs::dms-volumes-state]: ./advanced/optional-config.md#volumes-state [postfix-config::relayhost]: https://www.postfix.org/postconf.5.html#relayhost diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index 0c0c8e59..d8ece917 100644 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -144,7 +144,7 @@ nav: - 'File Based': config/account-management/provisioner/file.md - 'LDAP Service': config/account-management/provisioner/ldap.md - 'Supplementary': - - 'Dovecot Master Accounts': config/account-management/supplementary/master-accounts.md + - 'Master Accounts': config/account-management/supplementary/master-accounts.md - 'OAuth2 Authentication': config/account-management/supplementary/oauth2.md - 'Best Practices': - 'Auto-discovery': config/best-practices/autodiscover.md