Closed kduthoy closed 1 day ago
You should share your compose.yaml
like the bug report asks, did you customize any other ENV?
@thechubbypanda may have some insight here as they contributed the XOAUTH2 support and docs for Roundcube support. I think ports 465 and 587 should support XOAUTH2 since Postfix delegates SASL auth to Dovecot by default, but perhaps something is missing there?
Our test suite shows coverage for SMTP with port 587, so this should definitely be supported:
Must be a misconfiguration somewhere?
Here is my compose file
services:
mail:
image: ghcr.io/docker-mailserver/docker-mailserver:latest
container_name: mail
hostname: <FQDN>
networks:
lan:
ipv4_address: <internal IP address>
env_file: mail.env
ports:
- "25:25" # SMTP (explicit TLS => STARTTLS, Authentication is DISABLED => use port 465/587 instead)
- "143:143" # IMAP4 (explicit TLS => STARTTLS)
- "465:465" # ESMTP (implicit TLS)
- "587:587" # ESMTP (explicit TLS => STARTTLS)
- "993:993" # IMAP4 (implicit TLS)
volumes:
- ./data/mail/mail/:/var/mail/
- ./data/mail/mail-state/:/var/mail-state/
- ./data/mail/log/:/var/log/mail/
- ./appdata/mail/config/:/tmp/docker-mailserver/
- /etc/localtime:/etc/localtime:ro
- ./appdata/proxy/letsencrypt/:/etc/letsencrypt/:ro
restart: always
stop_grace_period: 1m
# Uncomment if using `ENABLE_FAIL2BAN=1`:
cap_add:
- NET_ADMIN
healthcheck:
test: "ss --listening --tcp | grep -P 'LISTEN.+:smtp' || exit 1"
timeout: 3s
retries: 0
depends_on:
- ldap
and the env-file:
I've tested a bit more and I get a different error when I change mail.env to the following
ENABLE_OAUTH2=1
OAUTH2_INTROSPECTION_URL=https://authelia.example.com/api/oidc/userinfo
Error in the logfile when I try to login in roundcube is. So now I don't even can't login with OAUTH2
dovecot: auth: oauth2(user,IP,<*******>): oauth2 failed: Introspection failed: Username 'user' did not match 'user@example.com'
Thank you for the help!
That looks like an email as username issue. Essentially you need to tell one side or the other to use email as username. I think the docs mention it vaguely but if not, there's a dovecot setting in the Auth config somewhere you'll need to tweak. I'm not at my PC at the moment so I can't link things for you.
dovecot: auth: oauth2(user,IP,<*******>): oauth2 failed: Introspection failed: Username 'user' did not match 'user@example.com'
Like @thechubbypanda pointed out, you just need those two to match, so either login with user@example.com
or configure the username_attribute
to username
instead of email
(default) like you had configured earlier 👍
That looks like an email as username issue
Yes, when Dovecot receives the access token, it will provide it to the configured endpoint for OAUTH2_INTROSPECTION_URL
and if the token is valid it receives a JSON response with information about the user. email
is default field in the response to compare to the login username (credentials to go with the login password token), these need to match IIRC.
The field can be changed, but the support via ENV is not yet added in DMS, it will be for v15 release. For now you would need to directly mount the OAuth2 Dovecot config instead of using ENV.
I think the docs mention it vaguely
I know it's been discussed, it may be documented in our tests or scripts, but I don't think we raised awareness in the docs. I never got around to fleshing out the OAuth2 docs page as I wanted to get the improved config management support in first. I now have time to push ahead with the LDAP rework, and OAuth2 will leverage that same approach, so it'll be handled for v15 👍
OAUTH2_USERNAME_ATTRIBUTE=username
OAUTH2_INTROSPECTION_MODE=post
OAUTH2_FORCE_INTROSPECTION=yes
So @kduthoy you seem to be aware of the config you need - but as mentioned above, the ENV support you're trying to use here isn't available yet.
EDIT: Actually it should work for those settings (_except force_introspection
_):
This is the current feature support:
It's the same as the current LDAP, if the file is missing a line for the ENV to match, it will not work. If you need to modify the file to add a new setting, there is not much benefit from trying to use ENV.
Instead you can still keep the change in compose.yaml
without a separate config file if you like via the configs
feature (this requires any Docker Compose release from 2024):
services:
mail:
configs:
- source: oauth2-config
target: /etc/dovecot/dovecot-oauth2.conf.ext
configs:
oauth2-config:
content: |
introspection_url = https://auth.example.com/admin/oauth2/introspect
introspection_mode = post
username_attribute = username
You can probably just use the /userinfo
endpoint instead of /introspect
, just bring back your username_attribute = username
ENV setting and you shouldn't need the custom config override like shown above?
Hi @polarathene @thechubbypanda
thank you for your feedback.
Unfortunately it doesn't work. If I use
OAUTH2_INTROSPECTION_URL=https://auth.example.com/api/oidc/userinfo
OAUTH2_USERNAME_ATTRIBUTE=username
I get this error in the logs:
dovecot: auth: Error: oauth2(user, IP,<*******>): oauth2 failed: Introspection failed: No username returned
and I can't login to IMAP with roundcube.
If I add
OAUTH2_INTROSPECTION_URL=https://clientid:secret@authelia.example.com/api/oidc/introspection
OAUTH2_USERNAME_ATTRIBUTE=username
OAUTH2_INTROSPECTION_MODE=post
I can login to IMAP with roundcube but I get the following error when I send an e-mail with SMTP on port 465 and 587:
postfix/submissions/smtpd[1653]: warning: SASL authentication failure: Couldn't find mech XOAUTH2
postfix/submissions/smtpd[1653]: warning: hostname[ip-adres]: SASL XOAUTH2 authentication failed: no mechanism available, sasl_username=(unavailable)
Thank you for your help! Kristof
Check that dovecote is requesting 3 scopes: openid, profile, and email.
Ensure that the username attribute is being returned along with the email. If the username is under sub
you might have to change the attribute to that.
Try logging in with your email address instead and setting the attribute to email.
Seems like /userinfo
doesn't return the username
field, while your /introspection
endpoint does.
Not sure why that isn't compatible with XOAUTH2 on Postfix, it should be delegating to Dovecot 🤔
I don't have time to investigate a reproduction. Potentially next month, I have to tackle other tasks before I can spare more time towards OAuth2 support.
I have recently rewritten docs related to this, you might want to give that a look? It's not merged yet, but you can view the preview for the OAuth2 page here, notably it might be worth trying my verification advice:
The curl
example shows OAUTHBEARER
, you could try with XOAUTH2
but pay attention to the notes that state the curl
example won't work in the DMS container curl
due to XOAUTH2
bug.
- Check that dovecote is requesting 3 scopes: openid, profile, and email.
Checked and this is correct. Requesting openid, profie and email in the roundcube config
$config['oauth_scope'] = 'email openid profile';
- Ensure that the username attribute is being returned along with the email. If the username is under
sub
you might have to change the attribute to that.
I found out that the attribute in the userinfo endpoint of Authelia for username is preferred_username
. Changed the configuration to
OAUTH2_INTROSPECTION_URL=https://authelia.example.be/api/oidc/userinfo
OAUTH2_USERNAME_ATTRIBUTE=preferred_username
And I can login again with roundcube to my mailbox. Sending e-mails remains the same. It is correct that in the introspection endpoint the username attribute is username
.
Sending e-mails remains a problem.
postfix/submission/smtpd[1526]: connect from roundcube[IP]
postfix/submission/smtpd[1526]: Anonymous TLS connection established from roundcube[IP]: TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384
postfix/submission/smtpd[1526]: warning: SASL authentication failure: Couldn't find mech XOAUTH2
postfix/submission/smtpd[1526]: warning: roundcube[IP]: SASL XOAUTH2 authentication failed: no mechanism available, sasl_username=(unavailable)
I finally got around to setting up Roundcube with an auth service (rauthy). It has no issues with sending mail from a user I logged in to roundcube with via OAuth2.
I used the /userinfo
endpoint instead of the /introspect
endpoint, but I have documented insights regarding concerns for /introspect
here: https://github.com/docker-mailserver/docker-mailserver/issues/2713#issuecomment-2268187285
Thus your issue is not a bug in DMS from what I can tell, everything is ok on our end. I would need to know what you're doing differently to reproduce.
I have setup via Authelia too and got this to work fine. I had a user john
configured with email john.doe@authelia.test
and tried with the /userinfo
endpoint.
username_attribute = preferred_username
:
mail dovecot: auth: oauth2(john.doe@authelia.test,172.16.42.6,<8Plc1fgenKesECoG>): oauth2 failed: Introspection failed: Username 'john.doe@authelia.test' did not match 'john'
When leaving it with the default username_attribute = email
this does work and if you haven't configured postfix-accounts.cf
/ LDAP in DMS for Dovecot to know of the user, it'll fail with:
roundcube-1 | errors: <f8bddfeb> IMAP Error: Login failed for john.doe@authelia.test against mail.example.test from 172.16.42.11 (X-Forwarded-For: 172.16.42.1). AUTHENTICATE XOAUTH2: A0001 NO [UNAVAILABLE] Internal error occurred. Refer to server log for more information. in /var/www/html/program/lib/Roundcube/rcube_imap.php on line 211 (GET /index.php/login/oauth?code=authelia_ac_UY9A8II1doCGPczbyUm5u3po2HuDS-KnzW4oDf4P85o.SIJOQ0lqEVBQLItSr-DoFlMu22nU_OaokmfM0uPNJhY&iss=https%3A%2F%2Fauth.example.localhost&scope=email+openid+profile&state=ejOw84Evfs4L)
dms-1 | 2024-08-06T00:06:09.986793+00:00 mail dovecot: auth: passwd-file(john.doe@authelia.test,172.16.42.6,<F0eWj/geiLasECoG>): unknown user (SHA1 of given password: 564053)
dms-1 | 2024-08-06T00:06:09.986824+00:00 mail dovecot: auth: Error: passwd-file(john.doe@authelia.test,172.16.42.6,<F0eWj/geiLasECoG>): user not found from userdb
dms-1 | 2024-08-06T00:06:09.986892+00:00 mail dovecot: imap(789): Error: auth-master: login: request [1902379009]: Login auth request failed: Authenticated user not found from userdb, auth lookup id=1902379009 (auth connected 0 msecs ago, request took 0 msecs, client-pid=786 client-id=1)
dms-1 | 2024-08-06T00:06:09.987189+00:00 mail dovecot: imap-login: Disconnected: Internal login failure (pid=786 id=1): user=<john.doe@authelia.test>, method=XOAUTH2, rip=172.16.42.6, lip=172.16.42.5, mpid=789, session=<F0eWj/geiLasECoG>
For /introspect
endpoint, you could query this with curl
and the access token (it's visible in the above log output as the value of code
)
# This is only here to minimize noise from the endpoint URL that follows.
# It's the client ID + client Secret with `:` between the values
export CLIENT_CREDENTIALS=roundcube:JKGW34FcEJTF2MH9MqMMCELyaqIqoeJPIYpBwikbZUufTwKEpqeYpd6suuqwEUGQ
curl --request POST \
--url "https://${CLIENT_CREDENTIALS}@auth.example.localhost/api/oidc/introspect" \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data token=authelia_ac_UY9A8II1doCGPczbyUm5u3po2HuDS-KnzW4oDf4P85o.SIJOQ0lqEVBQLItSr-DoFlMu22nU_OaokmfM0uPNJhY
{
"active": true,
"client_id": "roundcube",
"exp": 1722906685,
"iat": 1722903084,
"scope": "email openid profile",
"sub": "c09c699f-4f25-4a34-9103-46f6e23e762c",
"username": "john"
}
Likewise with the /userinfo
:
# This endpoint is protected via client credentials, just provide the access token via `Authorization: Bearer ...` header:
curl --request GET \
--url http://auth.example.localhost/api/oidc/userinfo \
--header 'Authorization: Bearer authelia_ac_UY9A8II1doCGPczbyUm5u3po2HuDS-KnzW4oDf4P85o.SIJOQ0lqEVBQLItSr-DoFlMu22nU_OaokmfM0uPNJhY
{
"amr": [
"pwd"
],
"aud": [
"roundcube"
],
"auth_time": 1722901191,
"azp": "roundcube",
"client_id": "roundcube",
"email": "john.doe@authelia.test",
"email_verified": true,
"iat": 1722901927,
"iss": "https://auth.example.localhost",
"name": "John Doe",
"preferred_username": "john",
"sub": "c09c699f-4f25-4a34-9103-46f6e23e762c"
}
So you can see the difference between the two endpoint responses there and what you can map with Dovecots username_attribute
setting.
Roundcube seems to provide the IMAP login username from the email
associated to the Authelia user as shown above, so you need to match that.
In this case preferred_username
(/userinfo
) and username
(/introspect
) JSON fields are john
so choosing those won't match successfully. It can potentially match successfully by using the Dovecot OAuth2 config setting username_format
(_default is %Lu
, lowercase the IMAP login username john.doe@authelia.test
and expect to match as the full email address to username_attribute
_).
If we changed that default to %Ln
, this would only compare the local-part of the IMAP login username, thus john.doe
against john
... which would still fail in this case, but you can see how if the email local-part or username in Authelia were actually equivalent this would then work too.
Anyway, just use the /userinfo
endpoint and the default email
. Then DMS should also have in postfix-accounts.cf
or LDAP a user with that same email address and you should have successful login on IMAP, as well as SMTP submission?
This issue has become stale because it has been open for 20 days without activity. This issue will be closed in 10 days automatically unless:
meta/stale
label or adds the stale-bot/ignore
labelThis issue was closed due to inactivity.
📝 Preliminary Checks
👀 What Happened?
I use roundcube to connect to IMAP with OAUTH2 and everything works correct. I can login to the mailbox and read the mails.
When I try to send an e-mail, I get the following error in the docker mailserver logs:
👟 Reproduction Steps
Authenticate with OAUTH2 and try to send and e-mail
🐋 DMS Version
v14.0.0
💻 Operating System and Architecture
Ubuntu 22.04
⚙️ Container configuration files
No response
📜 Relevant log output