snipe / snipe-it

A free open source IT asset/license management system
https://snipeitapp.com
GNU Affero General Public License v3.0
10.89k stars 3.14k forks source link

LDAPS certificate is not properly validated #13129

Closed qay21 closed 1 year ago

qay21 commented 1 year ago

Debug mode

Describe the bug

When using a valid certificate for a remote LDAPS server, SnipeIT seems to fail to validate it and therefore does not bind to LDAP server, blocking syncs and auth processes.

Reproduction steps

  1. Configure SnipeIT to use a remote LDAP server using LDAPS connection
  2. Try to log in : an error message is displayed stating that authentication failed
  3. Add $LDAPTLS_REQCERT=allow to env variables and restart
  4. Retry login : successful

Expected behavior

As verified from inside the container, with openssl s_client -showcerts -connect myldap.server:636, the provided certificate is valid and all needed CA are already installed inside the container. SnipeIT shouldn't fail to validate this certificate.

Screenshots

No response

Snipe-IT Version

Version v6.1.1-pre - build 10727 (master)

Operating System

Official Docker image

Web Server

Official Docker image

PHP Version

Official Docker image

Operating System

No response

Browser

No response

Version

No response

Device

No response

Operating System

No response

Browser

No response

Version

No response

Error messages

No response

Additional context

No response

uberbrady commented 1 year ago

Generally, if the certs are in the right place, the validation should work.

I would try php artisan ldap:troubleshoot and php artisan ldap:troubleshoot --ldap-search and see if you see anything glaring.

The first command does very low-level PHP connecting to LDAP servers, and the second command will help assemble command-line arguments to run the ldapsearch command, and one of them might lead us to what could be going wrong here…

qay21 commented 1 year ago

This is very interesting, thank you ! The second command, with --ldap-search, outputs a completely fine command, properly using all of my in-app configured LDAP settings, that is good. However the output of the first command is more interesting, and is as follow :

STAGE 1: Checking settings
Determined LDAP hostname to be: myldap.server
Performing DNS lookup of: myldap.server
STAGE 2: Checking basic network connectivity
Attempting to connect to port: 389 - may take up to 30 seconds
Success!
Attempting to connect to port: 636 - may take up to 30 seconds
Success!
STAGE 3: Determine encryption algorithm, if any
Trying TLS first for port 389
gonna try to bind now, this can take a while if we mess it up
WARNING: Exception caught during bind - ldap_bind(): Unable to bind to server: Can't contact LDAP server
WARNING: Failed to bind to ldaps://myldap.server:389 - trying without certificate checks.
gonna try to bind now, this can take a while if we mess it up
WARNING: Exception caught during bind - ldap_bind(): Unable to bind to server: Can't contact LDAP server
WARNING: Failed to bind to ldaps://myldap.server:389 with certificate checks disabled. Trying unencrypted with STARTTLS
WARNING: Exception caught during bind - ldap_start_tls(): Unable to start TLS: Connect error
WARNING: Failed to bind to ldap://myldap.server:389 with STARTTLS enabled. Trying without STARTTLS
gonna try to bind now, this can take a while if we mess it up
Bind results are: 1 which translate into boolean: 1
Plain connection to ldap://myldap.server:389 succesful!
Trying TLS first for port 636
gonna try to bind now, this can take a while if we mess it up
WARNING: Exception caught during bind - ldap_bind(): Unable to bind to server: Can't contact LDAP server
WARNING: Failed to bind to ldaps://myldap.server:636 - trying without certificate checks.
gonna try to bind now, this can take a while if we mess it up
WARNING: Exception caught during bind - ldap_bind(): Unable to bind to server: Can't contact LDAP server
WARNING: Failed to bind to ldaps://myldap.server:636 with certificate checks disabled. Trying unencrypted with STARTTLS
WARNING: Exception caught during bind - ldap_start_tls(): Unable to start TLS: Can't contact LDAP server
WARNING: Failed to bind to ldap://myldap.server:636 with STARTTLS enabled. Trying without STARTTLS
gonna try to bind now, this can take a while if we mess it up
WARNING: Exception caught during bind - ldap_bind(): Unable to bind to server: Can't contact LDAP server
WARNING: Failed to bind to ldap://myldap.server:636. Giving up on port 636
Found working LDAP URL's: 
LDAP URL: ldap://myldap.server:389

I left it unedited except the server's hostname.

The expected successful way (and the way everything in our infrastructure works) is contacting ldaps://myldap.server:636. We don't use StartTLS. LDAPS certificate is a Let's Encrypt standard certbot generated certificate, which is by all other tools and analysis considered valid.

Otherwise, I see here that :

Installing and trying ldapsearch from inside the container seems to lead to the same error :

ldap_sasl_bind(SIMPLE): Can't contact LDAP server (-1)

I think there is something to dig from here. Thanks for these commands, and if this ring any bell I'm open to suggestions. I'll keep digging on this !

qay21 commented 1 year ago

So, apparently, Can't contact LDAP server (-1) does not mean anything else than "something failed", whether the problem is on the network, the LDAP server's response, the client toolsuite or the client recognized certificate authorities. So, not much of a useful error.

I also tried these, from inside the container :

Any ldapsearch I try MUST be preceded by LDAPTLS_REQCERT=allow or LDAPTLS_REQCERT=never for it to succeed. I'm a bit lost here. It looks like ldapsearch inside the container is failing to validate a perfectly good certificate, whereas everything else succeed. Is there a twist somewhere, about ldapsearch not using ca-certificates or something ?

qay21 commented 1 year ago

SOLVED !

I had one of my senior colleagues have a look, they found something : /etc/ldap/ldap.conf seem to be missing in the container, despite ldap-utils being installed the standard way (as a reminder, I installed apt install ldap-utils in order to try ldapsearch commands directly inside the container).

This file is supposed to define TLS_CACERT /etc/ssl/certs/ca-certificates.crt, so that ldap* commands are aware of the list of valid CA certificates. Since this was missing, ldapsearch was not able to validate certificates. This file is provided by a specific package, installed using apt-get install libldap-common. No idea why this does not come as a dependency for ldap-utils, but anyway.

This fixed ldapsearch calls from ldap-utils, but at first the LDAP login was stil failing. However, my colleague noticed that ldd /usr/lib/php/20210902/ldap.so is supposed to load libldap-2.5.so.0, so they suggested service apache2 restart. This worked !

It seems, @uberbrady, that libldap-common is missing from the official image. Adding it would properly provided LDAPS support.

rasari03 commented 10 months ago

3. $LDAPTLS_REQCERT=allow

On server 2019, where is the location for the LDAPS certificate ?

rasari03 commented 10 months ago

SOLVED !

I had one of my senior colleagues have a look, they found something : /etc/ldap/ldap.conf seem to be missing in the container, despite ldap-utils being installed the standard way (as a reminder, I installed apt install ldap-utils in order to try ldapsearch commands directly inside the container).

This file is supposed to define TLS_CACERT /etc/ssl/certs/ca-certificates.crt, so that ldap* commands are aware of the list of valid CA certificates. Since this was missing, ldapsearch was not able to validate certificates. This file is provided by a specific package, installed using apt-get install libldap-common. No idea why this does not come as a dependency for ldap-utils, but anyway.

This fixed ldapsearch calls from ldap-utils, but at first the LDAP login was stil failing. However, my colleague noticed that ldd /usr/lib/php/20210902/ldap.so is supposed to load libldap-2.5.so.0, so they suggested service apache2 restart. This worked !

It seems, @uberbrady, that libldap-common is missing from the official image. Adding it would properly provided LDAPS support.

I am having a hard time getting LDAPS to work from SNIPE-IT to Server 2019 (AD LDAPS)