L
LLDAPโ€ข10mo ago
Trick789

Trick789 - Hi ๐Ÿ™‚ I'm running homeassistant (HA)...

Hi ๐Ÿ™‚ I'm running homeassistant (HA), lldap and the cisco duo authentication proxy (DUO) on k8s. I can't use the example config as I'm using HA > LDAP > DUO > LDAP > LLDAP. It's working beautifully using a a custom auth provider for HA (python script using ldap3 library: https://gist.github.com/yumenohikari/8440144023cf33ab3ef0d68084a1b42f) , but the only thing I can't get right is the filter so that only members of a group cn=ha_rw,ou=groups,dc=example,dc=com can authenticate. I've tried a bunch of flavors for the filter, but the lldap log continues to throw [warn]: Ignoring unknown group attribute ""memberof"" in filter messages. I thought memberof was a person attribute so I loaded up an LDAP browser (Apache DS) but can't find the attribute on either groups or people. But it must work because DUO is also pulling a memberof query to allow certain LLDAP users through and that's not generating a log entry on the LLDAP server. This is the original filter in the script (basically for AD):
FILTER = """ (& (objectClass=person) (| (sAMAccountName={}) (userPrincipalName={}) ) (memberOf=CN=Home Assistant,OU=Security Groups,OU=Accounts,DC=ad,DC=example,DC=com) )"""
and that's what I've attempted to change it to..
FILTER = """ (& (objectClass=person) (| (uid={}) (mail={}) ) (memberOf=CN=ha_hw,ou=groups,dc=example,dc=com) )"""
Any idea what the filter should look like? (running lldap 0.5.1-alpha). Thank you.
Solution:
@nitnelave - hey, just wanted to let you know that with the right filter in place I got it to work.. filter in ldap-auth.py
safe_username = escape_filter_chars(os.environ['username']) FILTER = f"(&(uid={safe_username})(memberOf=cn=ha_rw,ou=groups,dc=example,dc=com))"...
Jump to solution
64 Replies
nitnelave
nitnelaveโ€ข10mo ago
You're right that memberOf is a person attribute. It's also not technically an attribute, which is why the LDAP browser didn't show it (it's also possible that the browser doesn't work well with LLDAP). The reverse direction, for groups, is "member".
Trick789
Trick789โ€ข10mo ago
@nitnelave - thanks for the excellent work. love the project! Enabled verbosity and am seeing the following entries..
[debug]: | request.base: "DC=example,DC=com" | scope: Global get_user_list [ 607ยตs | 0.03% / 0.34% ] [debug]: | filters: And([And([]), MemberOf("ha_rw")])
so I take it the filter is working and I can just ignore those warnings
nitnelave
nitnelaveโ€ข10mo ago
The warning might be a false alarm: since your query probably has a base DN of just the DC (without the OU), LLDAP searches both groups and users (although it's not going to find any group with the object class condition)
Trick789
Trick789โ€ข10mo ago
oh right, I could finetune the base DN in the script to avoid that.
nitnelave
nitnelaveโ€ข10mo ago
If you can configure the base DN of the request, adding "ou=people" at the beginning should make the warnings go away
Trick789
Trick789โ€ข10mo ago
just noticed, after having added a couple of users to the group, that no matter which user I enter in HA, it's trying to login with the first user (alphabetically) in the group. Bummer but that has nothing to do with LLDAP I suppose ๐Ÿ™‚
nitnelave
nitnelaveโ€ข10mo ago
Look at the query sent to LLDAP and make sure it has the login name (you can see it in the verbose logs) When I see:
get_user_list [ 607ยตs | 0.03% / 0.34% ] [debug]: | filters: And([And([]), MemberOf("ha_rw")])
It seems that there's no login name in there
Trick789
Trick789โ€ข10mo ago
oh yeh I'm monitoring the logs of all 3 apps while trying to sign in.. HA: authentication failed for user B (the one I'm trying to login with). DUO: passes user A (first user of group hw_rw) on to LLDAP. LLDAP: errors out on user A.
nitnelave
nitnelaveโ€ข10mo ago
I don't see the whole "or" block from your filter The second "And([])" is just "true", that's the object class= person filter, it's always true for users I guess the issue is in the duo configuration
Trick789
Trick789โ€ข10mo ago
This is what I'm seeing when DUO checks if a user is allowed to use the service (DUO)
[debug]: | filters: And([And([Or([MemberOf("duo_access")]), Or([And([Not(And([])), Not(And([]))]), And([]), Not(And([]))])]), UserId(UserId("userB"))])
I didn't define the filter, that's all DUO.
nitnelave
nitnelaveโ€ข10mo ago
It's getting hard to read ๐Ÿ˜… can you post the LDAP just above? It has the LDAP filter before processing
Trick789
Trick789โ€ข10mo ago
[debug]: | filters: And([And([]), MemberOf("ha_rw")]) list_users [ 509ยตs | 0.26% ] filters: Some(And([And([]), MemberOf("ha_rw")])) | _get_groups: false [debug]: | return: [UserAndGroups { user: User { user_id: UserId("userB"), ..
nitnelave
nitnelaveโ€ข10mo ago
No, I mean a couple of lines above the filter, for the same query, you have the full request And the filter looks different
Trick789
Trick789โ€ข10mo ago
gotcha
[debug]: | msg: LdapMsg { msgid: 183, op: SearchRequest(LdapSearchRequest { base: "CN=duo_access,OU=groups,DC=example,DC=com", scope: Base, aliases: Never, sizelimit: 1, timelimit: 0, typesonly: false, filter: Present("objectClass"), attrs: ["objectsid"] }), ctrl: [] }
followed by
[debug]: | request.base: "CN=duo_access,OU=groups,DC=example,DC=com" | scope: Group(Equality("cn", "duo_access"))
nitnelave
nitnelaveโ€ข10mo ago
That's the request for the duo_access group (no idea about the objectsid attribute though) (maybe it's important?)
Want results from more Discord servers?
Add your server