Librenms issue
# troubleshooting
n
Here's a brand new thread for you! Please keep the discussion for this problem in this thread.
j
first answer, the user is lnms
it correctly authenticates so i know the user lookup etc is working
n
For context, the situation so far: I'm trying to get an app called LibreNMS to auth to lldap and can't seem to make it work. Any tips to debug? I've turned on debugging and its gives some clues but not any that have helped me
Copy code
librenms:/opt/librenms# ./scripts/auth_test.php -u lnms
Authentication Method: ldap
Password:
Authenticate user lnms:
AUTH SUCCESS

User (lnms):
  username =>
  realname =>
  user_id => 0
  email =>
  level => 0
Groups: ; cn=admin,ou=groups,dc=example,dc=com
Copy code
lldap_1  | 2023-08-02T08:55:42.156833926+00:00  WARN     β”‚  ┝━ 🚧 [warn]: Invalid dn filter on user:
lldap_1  | 2023-08-02T08:55:42.157817843+00:00  WARN     β”‚  ┕━ 🚧 [warn]: Invalid dn filter on group:
lldap_1  | 2023-08-02T08:55:42.159634093+00:00  INFO     ┝━ LDAP request [ 237Β΅s | 0.16% ]
lldap_1  | 2023-08-02T08:55:42.159652426+00:00  WARN     β”‚  ┕━ 🚧 [warn]: Invalid dn filter on user: cn=admin,ou=groups,dc=example,dc=com
With the LLDAP verbose logs, I could see what the requests/responses are and help you debug (don't paste just the warnings, but the full tree for each relevant request, or everything)
j
"auth_ldap_attr": { "auth_ldap_cache_ttl": 300, "auth_ldap_debug": false, "auth_ldap_emailattr": "mail", "auth_ldap_group": "", "auth_ldap_groupbase": "ou=groups,dc=example,dc=com", "auth_ldap_groupmemberattr": "member", "auth_ldap_groups": { "auth_ldap_port": 3890, "auth_ldap_prefix": "uid=", "auth_ldap_server": "host.docker.internal", "auth_ldap_require_groupmembership": false, "auth_ldap_starttls": "disabled", "auth_ldap_suffix": ",ou=people,dc=example,dc=com", "auth_ldap_timeout": 5, "auth_ldap_uid_attribute": "uid", "auth_ldap_userdn": true, "auth_ldap_wildcard_ou": false, "auth_ldap_version": 3, "auth_mechanism": "ldap", "auth_ldap_binduser": "lnms", "auth_ldap_binddn": "cn=lnms,ou=people,dc=example,dc=com", "auth_ldap_bindpassword": "password", "auth_ldap_groupmembertype": "username",
sorry was just trying to figure out how to extract the config
ok turning on debug and capturing a test auth
n
There's something weird going on. The configured DC for lldap seems to be the default one (dc=example,dc=com), which is fine, but then in the last request you have this weird filter:
filter: And([Equality("cn", "admin"), Equality("member", "uid=,ou=people,dc=9,dc=nz")])
, where you're looking for the admin group, but only if it contains the user "" (empty) in the
dc=9,dc=nz
and I have no idea where that comes from πŸ˜„
j
oh sorry i was trying to filter out my real dn πŸ™‚
i'm just substituting dc=example,dc=com for posting here
n
oh, then you missed one πŸ˜„
still, the uid is empty
j
looks like i missed one doh
n
which is weird
j
do you see any likely candidates in the librenms for me to try and change?
i can do some extreme logging on the librenms side and post that?
n
from what I can tell, this is just the ldap prefix and the ldap suffix, with nothing in between
n
but all the previous ldap queries look fine
it is weird that it's binding 3 times (I would expect twice at most) but not completely unexpected
l
I've played with this few days ago, without any sucess - https://community.librenms.org/t/trying-auth-mechanism-ldap-against-lldap/21919
j
haha i'm watching that thread to see if there are any responses
l
so I am not the onlyone trying to ditch OpenLDAP πŸ™‚
I've went and read the source and it seems as that $username variable is not passed to other LDAP queries correctly ..
j
i was on a plane a couple of days ago trying to figure out how to avoid a complicated ldap solution and was very happy to discover this
n
btw, @lowk3y , there's a quote missing in your post that messes up the formatting, after bindusr.
l
it's funny because I would assume this would be no brainer and should work out-of-the-box.
@nitnelave is there?
n
That's right, it should work out-of-the-box πŸ™‚ ... in an ideal world
j
oh so it auths but doesn't pass the $username in a later query?
n
In theory, there's no difference between theory and practice. In practice...
l
@nitnelave it's missing only in my post .. in the configuration there is one, otherwise PHP would complain
@jacobw9_81247 i was having an idea to added verbose logging to librenms (so additional, just to figure out how ldap queries are put together), because I am assuming there is something missing and or it doesn't fatch things right
@nitnelave LLDAP at the current point doesn't support
starttls
just LDAPS on different port right? Because I couldn't convince LibreNMS to use LDAPS
n
No, it doesn't support starttls
j
my next step was to relearn php to work it from that side πŸ™‚
l
@jacobw9_81247 hehe ..
Got it. Still I see couple of apps basically does
starttls
when saying enable TLS πŸ™‚
@jacobw9_81247 if you are planning to debug this further let me know ..
j
will do
@nitnelave any more thoughts or is this up to me?
n
The
$username
variable seems like the culprit indeed, the logs look good on the LLDAP side, we're just missing the username from the last filter, AFAICT
j
@lowk3y where did you spot the missing $username?
l
@jacobw9_81247 it's my wild guess .. if you look at my debug output of
auth-test.php
you could spot put filter queries ..
Copy code
put_filter: "(&(|(cn=nms-admin)(cn=nms-operator)(cn=nms))(member=uid=,ou=people,dc=example,dc=com))"
put_filter: AND
put_filter_list "(|(cn=nms-admin)(cn=nms-operator)(cn=nms))(member=uid=,ou=people,dc=example,dc=com)"
put_filter: "(|(cn=nms-admin)(cn=nms-operator)(cn=nms))"
put_filter: OR
put_filter_list "(cn=nms-admin)(cn=nms-operator)(cn=nms)"
and it seems as
(member=uid=<missing usernema>
as from previous ldap query it never got back
uid
right back .. or something
j
Cool, will look in to this tomorrow
l
@jacobw9_81247 you managed to played with it yet?
j
yeah think i found the problem
in librenms/LibreNMS/Authentication /LdapAuthorizer.php
line 234 looks like it has an issue
foreach ($entries as $entry) {
$entry should be an array but its just an integer
adding this above line 240 fixes it
$user = $this->ldapToUser($entries[0]);
l
hmm ..
j
not an actual fix, but fixes the output to populate the array properly
l
have you made a PR on LibreNMS for this fix? is this breaking other LDAP impementations
j
librenms:/opt/librenms/scripts# ./auth_test2.php -u lnms Authentication Method: ldap Password: Authenticate user lnms: User (lnms): username => lnms realname => lnmsdisplay user_id => 0 email => lnms@example.com level => 10 Groups: ; cn=admin,ou=groups,dc=example,dc=com
only just figued it out a few minutes ago
not a proper fix, not sure what the actual issue is
l
but it strange, because
Copy code
php
foreach ($entries as $entry) {
         $user = $this->ldapToUser($entry);
should do just that for each entries. With
Copy code
php
$user = $this->ldapToUser($entries[0]);
you're taking just the first one
j
but it should be enough for someone to figure it out quickly
yeah, i'm not sure why that doesn't work, looks correct
did a lot of debugging to get to that
l
it would make sense to pass this finding also to LibreNMS community
j
doing that right now
as im totally keen for them to fix it πŸ˜„
im off to bed, haven't had time to see if this fixes actual auth
will try tmrw
l
./auth-test.php
seem to "work", but once getting logged into web GUI it seems groups mapping doesn't work. No matter that
auth-test.php
report
level=10
I still have no permissions inside web interface 😦
so it's more complex issues
but yes, at least I can log into LibreNMS
n
If you have an OpenLDAP handy, I'd be curious to compare the request/responses between LLDAP and OpenLDAP
(or any other LDAP server with which it works)
l
I do have another setup with OpenLDAP, but 2 years older libreNMS which works just fine
I see if I can enable debug mode on OpenLDAP to see the queries it performs
n
Or you can also use tcpdump to capture the traffic between the two
l
TLS is enabled 😦
but yes, maybe I can force it go without
j
FYI the uid=, happens after the issue that I found so I don’t think that’s related to this issue
Also librenms expects uid to be an int at one point. Is that usual or unusual?
n
That seems unusual
j
Is it perhaps what a few vendors do so librenms just expects it?
n
I'm reading about the LDAP encoding to see if I missed anything
Alright, I had a quick look at the code, and it seems like librenms is expecting a uid number field (which we don't have). That's how it's "casting" a user to a user_id, and how it matches users
So maybe it's just that that's missing
The "uidnumber" config attribute
j
got it
is that something that's usually there and you;d consider implementing?
(i've tweaked my config so much i'm just rebulding my test environment0
n
I think we could make it work, yeah
The DB already has a row ID, we can reuse that. I'll have to see what openLdap usually returns
Another possibility is hashing the user id for "random" IDs
j
ok great
I've cleaned up my build if you want any cleaner logs
i've taken out a few variables too, possibly creating new issues but i think i have it working as well as it will with the uid number field issue
which i assume is the posix one
librenms:/opt/librenms# ./scripts/auth_test.php -u admin Authentication Method: ldap Password: Authenticate user admin: AUTH SUCCESS User (): username => admin realname => Administrator user_id => 0 email => level => 10 Groups: cn=nms_admin,ou=groups,dc=example,dc=com
you need to set this to get the level to work
auth_ldap_groupmemberattr: member
as the default is memberUid
so you can log in to the main librenms with this setup, but the level 10 above which is admin does not translate to the user having admin rights
another issue that was fixed by my workaround was the missing uid:
ldap_search_ext put_filter: "(&(cn=nms_admin)(member=uid=admin,ou=people,dc=example,dc=com))" put_filter: AND put_filter_list "(cn=nms_admin)(member=uid=admin,ou=people,dc=example,dc=com)" put_filter: "(cn=nms_admin)" put_filter: simple put_simple_filter: "cn=nms_admin" put_filter: "(member=uid=admin,ou=people,dc=example,dc=com)" put_filter: simple put_simple_filter: "member=uid=admin,ou=people,dc=example,dc=com" ldap_build_search_req ATTRS: * ldap_send_initial_request
that last request is from this chain of code...
ldapToUser($entry)
'level' => $this->getUserlevel($entry['uid'][0]),
which goes though a few options for constructing the ldap flter, but i don't think they are the probem as the user level in auth_test.php is returned correctly
so i'll leave this here while the thread on the librenms github issue gets discussed, but let me know if there's any more testing you'd like
l
πŸ€”
j
or hopefully the uid number get added and that just fixes it πŸ™‚
n
FYI, I don't know when I can get to it, don't hold your breath
Could you open an issue on GitHub for me?
j
sure
Let me know if i can help. I've been keen to learn rust at some point but this doesn't look like a good intro project πŸ™‚
n
Yeah, getting a valid user ID is more problematic than I thought... Since I don't have a numeric autoincrement primary key for the table, the foreign keys are on the username (the primary key). So I can't introduce a new primary integer autoincrement key. I'm gonna have to make do with a random hash, letting the DB handle the collisions
but since they can be used for linux users, I'll limit them to between 2k and 60k (for various legacy reasons)
Once someone creates >30k users in LLDAP, new user creation will start taking longer and longer... until it fails when approaching 58k users
But that's not exactly the kind of scales that LLDAP is built for πŸ˜„
j
Yeah sounds reasonable. Is it something you might look to sort properly in the longer term? I imagine there might be quite a few use cases that expect the posix attributes.
n
I mean, that's fairly proper, you don't have to have sequential user IDs
that'll populate the posix attribute, and if you don't like the value you can always set it yourself or modify it
(as long as it's unique)
j
I forgot to test replacing the cast with the actual uid (I forgot the attribute would be empty) will try that in a bit
I have 2 more apps (netbox and oxidised) to try and integrate with lldap so be interesting to see if that expect it too
Netbox is a django app so not sure if someone has done that already
PR submitted
which should fix it
Thanks @nitnelave
And yeah, no need for the change I'd say.
Also I didn’t realise the variable to check was configurable
So changed uidNumber to uid
Will document this properly once fixed
l
@jacobw9_81247 the patch you wrote on LibreNMS works for you? I can login, but my user that is
admin
group is still not getting right permissions ..
j
yep
i need to write up the rest of the settings
this is important
auth_ldap_attr: '{"uid": "uid"}'
auth_ldap_groupmemberattr: member
auth_ldap_require_groupmembership: false
have you set those already?
you should be able to test with scripts/auth_test.php and make sure its populating the user_id and level fields correctly