wiltonsr / ldapAuth

An open source Traefik Middleware that enables authentication via LDAP in a similar way to Traefik Enterprise
https://plugins.traefik.io/plugins/628c9eb7ffc0cd18356a979c/ldap-auth
Apache License 2.0
111 stars 10 forks source link

allowedGroups sintax #45

Closed plakun closed 1 year ago

plakun commented 1 year ago

Hello, i have a problem with allowedGroups module in plugin. Have config:

http:
  middlewares:
    ldap-auth:
      plugin:
        ldapAuth:
          Attribute: "uid"
          BaseDn: "cn=users,cn=accounts,dc=org,dc=local"
          Enabled: true
          Url: "ldap://freeipa.org.local"
          LogLevel: "DEBUG"
          allowedGroups:
            - cn=test-group,cn=groups,cn=accounts,dc=org,dc=local

I have testuser in test-group. But traefik cant authenticate testuser:

Aug 03 06:59:13 infra-internal-lb traefik[3187004]: DEBUG: ldapAuth: 2023/08/03 06:59:13 restricted.go:52: No session found! Trying to authenticate in LDAP
Aug 03 06:59:13 infra-internal-lb traefik[3187004]: DEBUG: ldapAuth: 2023/08/03 06:59:13 restricted.go:51: Host: freeipa.org.local
Aug 03 06:59:13 infra-internal-lb traefik[3187004]: DEBUG: ldapAuth: 2023/08/03 06:59:13 restricted.go:51: Connect Address: freeipa.org.local:389
Aug 03 06:59:13 infra-internal-lb traefik[3187004]: DEBUG: ldapAuth: 2023/08/03 06:59:13 restricted.go:51: Running in Bind Mode
Aug 03 06:59:13 infra-internal-lb traefik[3187004]: DEBUG: ldapAuth: 2023/08/03 06:59:13 restricted.go:51: Authenticating User: uid=testuser,cn=users,cn=accounts,dc=org,dc=local
Aug 03 06:59:13 infra-internal-lb traefik[3187004]: DEBUG: ldapAuth: 2023/08/03 06:59:13 restricted.go:51: Searching Group: 'cn=test-group,cn=groups,cn=accounts,dc=org,dc=local' with User: 'uid=testuser,cn=users,cn=accounts,dc=org,dc=local'
Aug 03 06:59:13 infra-internal-lb traefik[3187004]: INFO: ldapAuth: 2023/08/03 06:59:13 restricted.go:51: LDAP Result Code 12 "Unavailable Critical Extension": Bad search filter
Aug 03 06:59:13 infra-internal-lb traefik[3187004]: DEBUG: ldapAuth: 2023/08/03 06:59:13 restricted.go:51: User: 'testuser' not found in Group: 'cn=test-group,cn=groups,cn=accounts,dc=org,dc=local'
Aug 03 06:59:13 infra-internal-lb traefik[3187004]: ERROR: ldapAuth: 2023/08/03 06:59:13 restricted.go:51: LDAP Result Code 12 "Unavailable Critical Extension": Bad search filter
Aug 03 06:59:13 infra-internal-lb traefik[3187004]: User 'testuser' does not match any allowed users nor allowed groups.
Aug 03 06:59:13 infra-internal-lb traefik[3187004]: DEBUG: ldapAuth: 2023/08/03 06:59:13 restricted.go:52: [LDAP Result Code 12 "Unavailable Critical Extension": Bad search filter
Aug 03 06:59:13 infra-internal-lb traefik[3187004]: User 'testuser' does not match any allowed users nor allowed groups.]

i made a workaround using searchmode with searchFilter: (&(memberOf=cn=test-group,cn=groups,cn=accounts,dc=org,dc=local)({{.Attribute}}={{.Username}})) and it works, but would be great to understand why normal way doesn't work. Maybe it's because of "memberOf" field? Didnt see this in sources.

wiltonsr commented 1 year ago

Hello, @plakun

Thanks for reporting this issue. I think this problem was added in PR #40.

I can replicate the problem using ldapsearch and FreeIPA demo LDAP server.

Without the member:1.2.840.113556.1.4.1941: filter the search works:

$ ldapsearch -x \
  -b "cn=users,cn=accounts,dc=demo1,dc=freeipa,dc=org" \
  -H ldap://ipa.demo1.freeipa.org \
  -D "uid=manager,cn=users,cn=accounts,dc=demo1,dc=freeipa,dc=org" \
  -w Secret123 \
  "(uid=manager)"
# extended LDIF
#
# LDAPv3
# base <cn=users,cn=accounts,dc=demo1,dc=freeipa,dc=org> with scope subtree
# filter: (uid=manager)
# requesting: ALL
#

# manager, users, accounts, demo1.freeipa.org
dn: uid=manager,cn=users,cn=accounts,dc=demo1,dc=freeipa,dc=org
givenName: Test
sn: Manager
uid: manager
cn: Test Manager
displayName: Test Manager
initials: TM
gecos: Test Manager
krbPrincipalName: manager@DEMO1.FREEIPA.ORG
objectClass: top
objectClass: person
objectClass: organizationalperson
objectClass: inetorgperson
objectClass: inetuser
objectClass: posixaccount
objectClass: krbprincipalaux
objectClass: krbticketpolicyaux
objectClass: ipaobject
objectClass: ipasshuser
objectClass: ipaSshGroupOfPubKeys
objectClass: mepOriginEntry
objectClass: ipantuserattrs
loginShell: /bin/sh
homeDirectory: /home/manager
mail: manager@demo1.freeipa.org
krbCanonicalName: manager@DEMO1.FREEIPA.ORG
ipaUniqueID: 33a91070-df83-11ed-919b-0674ebdae396
uidNumber: 1142400003
gidNumber: 1142400003
krbLastPwdChange: 20230420135652Z
ipaNTSecurityIdentifier: S-1-5-21-562557311-290852036-180187086-1003
memberOf: cn=ipausers,cn=groups,cn=accounts,dc=demo1,dc=freeipa,dc=org
memberOf: cn=employees,cn=groups,cn=accounts,dc=demo1,dc=freeipa,dc=org
memberOf: ipaUniqueID=d73ae6ae-df7f-11ed-8ae9-0674ebdae396,cn=hbac,dc=demo1,dc
 =freeipa,dc=org
memberOf: cn=managers,cn=groups,cn=accounts,dc=demo1,dc=freeipa,dc=org
krbPasswordExpiration: 20230719135652Z

# search result
search: 2
result: 0 Success

# numResponses: 2
# numEntries: 1

But using AD nested groups:

$ ldapsearch -x \
  -b "cn=users,cn=accounts,dc=demo1,dc=freeipa,dc=org" \
  -H ldap://ipa.demo1.freeipa.org \
  -D "uid=manager,cn=users,cn=accounts,dc=demo1,dc=freeipa,dc=org" \
  -w Secret123 \
  "(|(uid=manager)(member:1.2.840.113556.1.4.1941:=uid=manager))"
# extended LDIF
#
# LDAPv3
# base <cn=users,cn=accounts,dc=demo1,dc=freeipa,dc=org> with scope subtree
# filter: (|(uid=manager)(member:1.2.840.113556.1.4.1941:=uid=manager))
# requesting: ALL
#

# search result
search: 2
result: 12 Critical extension is unavailable
text: Bad search filter

# numResponses: 1

When you use a custom searchFilter and don't add allowedGroups, then no authorization is performed

https://github.com/wiltonsr/ldapAuth/blob/c6f6066dfd95b1cb019b25b71f9cf6a587462a31/ldapauth.go#L268-L271

And this piece of code that adds the AD nested groups filter doesn't run

https://github.com/wiltonsr/ldapAuth/blob/c6f6066dfd95b1cb019b25b71f9cf6a587462a31/ldapauth.go#L326-L331

You can make a test using v0.0.22 and report here if everything works as expected. This specific version doesn't have the AD nested groups feature.

If we confirm this is the problem, I will submit a fix with a param to explicitly enable the AD nested groups feature.

wiltonsr commented 1 year ago

@fcinqmars fyi

fcinqmars commented 1 year ago

@wiltonsr I think you indeed found the culprit. I can confirm that PR#40 introduced this bug by using ipa.demo1.freeipa.org as it works with 0.0.22 but not with any further versions.

That being said, I would be curious to know what the difference is with that LDAP server. I tested against the one you usually use (forumsys.com) as well as with AD and they both work. ldap.forumsys.com and ipa.demo1.freeipa.org are both using the same LDAP version (LDAPv3).

ldapsearch -x   \
-b "dc=example,dc=com" \
-H ldap://ldap.forumsys.com  \
-D "cn=read-only-admin,dc=example,dc=com" \
-w password \
"(|(uid=euclid)(member:1.2.840.113556.1.4.1941:=uid=euclid))"

# extended LDIF
#
# LDAPv3
# base <dc=example,dc=com> with scope subtree
# filter: (|(uid=euclid)(member:1.2.840.113556.1.4.1941:=uid=euclid))
# requesting: ALL
#

# euclid, example.com
dn: uid=euclid,dc=example,dc=com
uid: euclid
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: person
objectClass: top
cn: Euclid
sn: Euclid
mail: euclid@ldap.forumsys.com

# search result
search: 2
result: 0 Success

# numResponses: 2
# numEntries: 1
wiltonsr commented 1 year ago

That being said, I would be curious to know what the difference is with that LDAP server.

Looks like a specific server feature to be enabled/configured.

Anyway, I think that the PR #46 will fix the problem.