Issue with LDAP

I’ve setup LDAPS but am having issues with the bind account. Everything works if I enable anonymous binding, however, if I disable it, I get an error message:

Remote LDAP server returned response that credentials are invalid.

Yes, the password is correct. My suspicion is the bind account DN. My LDAP schema uses uid for the user naming attribute. By choosing “RFC 2307” in TrueNAS, I suspect that the lookup is doing something like member=CN=bind_account and simply not finding the user.

Saying that I’m mediocre with LDAP would be a compliment, so any help here is appreciated!

You need to use full DN for the binddn field. E.g: "uid=testuser,ou=Users,o=<something>,dc=jumpcloud,dc=com"

Update: I think that the issue may be related to certs.

I was looking at access logs on my LDAP server and saw the following entry:

[03/Sep/2024:20:14:00.131544749 -0600] conn=8633 fd=238 slot=238 SSL connection from 192.168.1.10 to 192.168.1.5
[03/Sep/2024:20:14:00.142146218 -0600] conn=8633 TLS1.3 128-bit AES-GCM; client CN=nas.contoso.com,O=CONTOSO.COM; issuer CN=Certificate Authority,O=CONTOSO.COM
[03/Sep/2024:20:14:00.145234679 -0600] conn=8633 TLS1.3 failed to map client certificate to LDAP DN (No such object)
[03/Sep/2024:20:14:00.145301269 -0600] conn=8633 op=0 BIND dn="uid=bindaccount,cn=users,cn=accounts,dc=contoso,dc=com" method=sasl version=3 mech=EXTERNAL
[03/Sep/2024:20:14:00.145427866 -0600] conn=8633 op=0 RESULT err=49 tag=97 nentries=0 wtime=0.013713078 optime=0.000130589 etime=0.013843010 - Client certificate mapping failed
[03/Sep/2024:20:14:00.145817517 -0600] conn=8633 op=1 UNBIND
[03/Sep/2024:20:14:00.145827144 -0600] conn=8633 op=1 fd=238 Disconnect - Cleanly Closed Connection - U1

TrueNAS should only need the root CA’s public certificate for LDAPS. However, I’m a little confused with TrueNAS’s certificate interface.

I did create a client cert for the TrueNAS server (for HTTPS), which I added to “Certificates” in the GUI. I also uploaded the CA chain (sub + root) to “Certificate Authorities” in the GUI. However, I’m starting to think that the “Certificate Authorities” section is only for certs to make TrueNAS a CA, rather than establish trust with external CAs.

When I configure LDAPS, it requires that I pick a cert to perform the lookup with, however, it only allows me to select certs from the “Certificates” category rather than “Certificate Authorities”.

Current configs are as follows:


You add CAs through our UI for adding CAs to TrueNAS. Certificates in LDAP page are for cert-based authentication (e.g. mutual TLS).

That said, what are the goals here? If this is AD then you must use the AD plugin, not the LDAP plugin in TrueNAS.

The goal is to setup LDAPS and kerberos for centralized identity management rather than having local accounts scattered about my network. I’m not using AD, but rather RHEL’s IdM services.

I did manage to get LDAPS working properly, so thank you for clarifying the GUI certificate manager. I removed the initial CA cert chain that I had imported and re-uploaded it. Not sure what went wrong in the first place.

Anyways, that was the easy part, unfortunately. Now the kerberos part. I wish that I was using AD because it makes things so much easier. AD is one of the few products that Microsoft actually did well…

If the IDM solution is based on FreeIPA you can test out the Electric Eel BETA. We have added support for proper IPA join there. Just need to configure DNS correctly first, use hostname of IPA server for LDAP bind, and we will automatically create kerberos configuration, keytabs, etc.

Yup, IDM uses FreeIPA on the backend. The full support for FreeIPA is very exciting! Since I unfortunately already have this NAS up and running with data on it, I may hold off on beta testing in the short term, but I will definitely follow along! I may even hold off on kerberos implementation until a stable version of Electric Eel comes out. Thanks for that info!

Hello, again!

I’ve updated to Electric Eel. My LDAPS configurations are working properly and showing healthy. However, the kerberos configurations don’t seem to automatically generate. Is there something that I can/need to do to kick this off?

Edit to add:

I tried disabling LDAP and then re-enabling (the “enable” checkbox). When re-enabling it, it throws an error (below). I’ve tried deleting the hostname and re-adding it, as well as tinkering around with it in general, but I keep getting the same error and am unable to re-enable it.

  File "/usr/lib/python3/dist-packages/middlewared/plugins/ldap.py", line 843, in ipa_config
    raise CallError('Hostname should be changed from default value prior to joining IPA domain')
middlewared.service_exception.CallError: [EFAULT] Hostname should be changed from default value prior to joining IPA domain

EDIT #2:

I stumbled on the truenas github and found that it’s in reference to truenas’s hostname. There’s a hardcoded check disallowing truenas as the hostname when joining ipa domain. I’m curious why that’s there, but it seems like I need to change TrueNAS’s hostname. I’ll play around with that…

        if hostname == 'truenas':
            raise CallError('Hostname should be changed from default value prior to joining IPA domain')

Ok, still having issues. It seems that TrueNAS is looking for permissions to manage its kerberos principal. I’d prefer to not allow that. Is there any way to proceed without granting such permissions?

Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/middlewared/plugins/ldap.py", line 912, in __start
    dom_join_resp = await job.wrap(await self.middleware.call(
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/middlewared/job.py", line 692, in wrap
    return await subjob.wait(raise_error=True)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/middlewared/job.py", line 436, in wait
    raise self.exc_info[1]
  File "/usr/lib/python3/dist-packages/middlewared/job.py", line 488, in run
    await self.future
  File "/usr/lib/python3/dist-packages/middlewared/job.py", line 535, in __run_body
    rv = await self.middleware.run_in_thread(self.method, *args)
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/middlewared/main.py", line 1364, in run_in_thread
    return await self.run_in_executor(io_thread_pool_executor, method, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/middlewared/main.py", line 1361, in run_in_executor
    return await loop.run_in_executor(pool, functools.partial(method, *args, **kwargs))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/concurrent/futures/thread.py", line 58, in run
    result = self.fn(*self.args, **self.kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/middlewared/utils/directoryservices/krb5.py", line 331, in check_ticket
    return fn(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/middlewared/plugins/directoryservices_/join.py", line 244, in join_domain
    do_join_fn(job, ds_type, domain)
  File "/usr/lib/python3/dist-packages/middlewared/utils/directoryservices/krb5.py", line 331, in check_ticket
    return fn(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/middlewared/plugins/directoryservices_/ipa_join_mixin.py", line 430, in _ipa_join
    resp = self._ipa_join_impl(
           ^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/middlewared/plugins/directoryservices_/ipa_join_mixin.py", line 406, in _ipa_join_impl
    raise e
  File "/usr/lib/python3/dist-packages/middlewared/plugins/directoryservices_/ipa_join_mixin.py", line 395, in _ipa_join_impl
    resp = _parse_ipa_response(join)
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/middlewared/plugins/directoryservices_/ipa_join_mixin.py", line 39, in _parse_ipa_response
    raise CallError(err, extra=err_decoded)
middlewared.service_exception.CallError: [EFAULT] {"result": null, "error": {"code": 2100, "message": "Insufficient access: Insufficient 'write' privilege to the 'krbLastPwdChange' attribute of entry 'fqdn=nas.contoso.com,cn=computers,cn=accounts,dc=contoso,dc=com'.", "data": {"info": "Insufficient 'write' privilege to the 'krbLastPwdChange' attribute of entry 'fqdn=nas.contoso.com,cn=computers,cn=accounts,dc=contoso,dc=com'."}, "name": "ACIError"}, "id": null, "principal": "serviceaccount@contoso.com", "version": "4.11.0"}

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/middlewared/job.py", line 488, in run
    await self.future
  File "/usr/lib/python3/dist-packages/middlewared/job.py", line 533, in __run_body
    rv = await self.method(*args)
         ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/middlewared/schema/processor.py", line 49, in nf
    res = await f(*args, **kwargs)
          ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/middlewared/schema/processor.py", line 179, in nf
    return await func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/middlewared/plugins/ldap.py", line 681, in do_update
    await self.__start(job, ds_type)
  File "/usr/lib/python3/dist-packages/middlewared/plugins/ldap.py", line 932, in __start
    if not err.err_msg.startswith('[KRB5_REALM_UNKNOWN]'):
           ^^^^^^^^^^^
AttributeError: 'CallError' object has no attribute 'err_msg'

That’s fixed for 24.10.1 (in review). It’s related to case where we’re unable to use existing credentials to do a proper IPA join.

1 Like

Is it possible to test 24.10.1 somehow?