Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

can't login with LDAPS on AD without LDAP_TLS_INSECURE=true #4075

Open
eoli3n opened this issue Feb 28, 2023 · 18 comments
Open

can't login with LDAPS on AD without LDAP_TLS_INSECURE=true #4075

eoli3n opened this issue Feb 28, 2023 · 18 comments
Labels

Comments

@eoli3n
Copy link

eoli3n commented Feb 28, 2023

Describe the Bug

I configured BookStack to login with LDAPS on Active Directory, with a certificate produced by a self-signed certificate autority.
The certificate autority is available on the host system, but I can't log in, without setting LDAP_TLS_INSECURE=true.

Steps to Reproduce

  1. Configure ldap auth like
AUTH_METHOD=ldap
LDAP_SERVER=ldaps://server.domain.com:636
LDAP_BASE_DN="dc=***,dc=***"
LDAP_DN="cn=bind_dn,cn=users,dc=***,dc=***"
LDAP_PASS="******************************"

LDAP_USER_FILTER=(&(sAMAccountName=${user}))
LDAP_VERSION=3
LDAP_ID_ATTRIBUTE=BIN;objectGUID

LDAP_EMAIL_ATTRIBUTE=mail
LDAP_START_TLS=false
LDAP_TLS_INSECURE=false
  1. Add the certificate autority system wide for Debian 11
cp ca.crt /usr/local/share/ca-certificates/
update-ca-certificates
  1. Validate that the ca is present
    See https://unix.stackexchange.com/questions/97244/list-all-available-ssl-ca-certificates
$ awk -v cmd='openssl x509 -noout -subject' ' /BEGIN/{close(cmd)};{print | cmd}' < /etc/ssl/certs/ca-certificates.crt | grep FSI
subject=emailAddress = *****************, O = ****************, L = *********, C = **, CN = FSI DI Root CA
  1. Try to authenticate : it fails
  2. Change LDAP_TLS_INSECURE to true
  3. Try to authenticate : it succeed

Expected Behaviour

Log in successful with LDAP_TLS_INSECURE=false

Screenshots or Additional Context

APP_DEBUG log

ErrorException
ldap_bind(): Unable to bind to server: Can't contact LDAP server

PHP Version: 8.2.3
BookStack Version: v23.02

#0 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Foundation/Bootstrap/HandleExceptions.php(266): Illuminate\Foundation\Bootstrap\HandleExceptions->handleError()
#1 [internal function]: Illuminate\Foundation\Bootstrap\HandleExceptions->Illuminate\Foundation\Bootstrap\{closure}()
#2 /var/www/bookstack/app/Auth/Access/Ldap.php(107): ldap_bind()
#3 /var/www/bookstack/app/Auth/Access/LdapService.php(186): BookStack\Auth\Access\Ldap->bind()
#4 /var/www/bookstack/app/Auth/Access/LdapService.php(58): BookStack\Auth\Access\LdapService->bindSystemUser()
#5 /var/www/bookstack/app/Auth/Access/LdapService.php(94): BookStack\Auth\Access\LdapService->getUserWithAttributes()
#6 /var/www/bookstack/app/Auth/Access/Guards/LdapSessionGuard.php(72): BookStack\Auth\Access\LdapService->getUserDetails()
#7 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Auth/AuthManager.php(340): BookStack\Auth\Access\Guards\LdapSessionGuard->attempt()
#8 /var/www/bookstack/app/Auth/Access/LoginService.php(157): Illuminate\Auth\AuthManager->__call()
#9 /var/www/bookstack/app/Http/Controllers/Auth/LoginController.php(148): BookStack\Auth\Access\LoginService->attempt()
#10 /var/www/bookstack/app/Http/Controllers/Auth/LoginController.php(82): BookStack\Http\Controllers\Auth\LoginController->attemptLogin()
#11 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Routing/Controller.php(54): BookStack\Http\Controllers\Auth\LoginController->login()
#12 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php(43): Illuminate\Routing\Controller->callAction()
#13 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Routing/Route.php(259): Illuminate\Routing\ControllerDispatcher->dispatch()
#14 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Routing/Route.php(205): Illuminate\Routing\Route->runController()
#15 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Routing/Router.php(798): Illuminate\Routing\Route->run()
#16 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(141): Illuminate\Routing\Router->Illuminate\Routing\{closure}()
#17 /var/www/bookstack/app/Http/Middleware/CheckGuard.php(27): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#18 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): BookStack\Http\Middleware\CheckGuard->handle()
#19 /var/www/bookstack/app/Http/Middleware/RedirectIfAuthenticated.php(31): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#20 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): BookStack\Http\Middleware\RedirectIfAuthenticated->handle()
#21 /var/www/bookstack/app/Http/Middleware/Localization.php(45): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#22 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): BookStack\Http\Middleware\Localization->handle()
#23 /var/www/bookstack/app/Http/Middleware/RunThemeActions.php(26): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#24 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): BookStack\Http\Middleware\RunThemeActions->handle()
#25 /var/www/bookstack/app/Http/Middleware/CheckEmailConfirmed.php(47): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#26 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): BookStack\Http\Middleware\CheckEmailConfirmed->handle()
#27 /var/www/bookstack/app/Http/Middleware/PreventAuthenticatedResponseCaching.php(21): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#28 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): BookStack\Http\Middleware\PreventAuthenticatedResponseCaching->handle()
#29 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/VerifyCsrfToken.php(78): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#30 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Foundation\Http\Middleware\VerifyCsrfToken->handle()
#31 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/View/Middleware/ShareErrorsFromSession.php(49): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#32 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\View\Middleware\ShareErrorsFromSession->handle()
#33 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(121): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#34 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(64): Illuminate\Session\Middleware\StartSession->handleStatefulRequest()
#35 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Session\Middleware\StartSession->handle()
#36 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/AddQueuedCookiesToResponse.php(37): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#37 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse->handle()
#38 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/EncryptCookies.php(67): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#39 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Cookie\Middleware\EncryptCookies->handle()
#40 /var/www/bookstack/app/Http/Middleware/ApplyCspRules.php(33): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#41 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): BookStack\Http\Middleware\ApplyCspRules->handle()
#42 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(116): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#43 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Routing/Router.php(797): Illuminate\Pipeline\Pipeline->then()
#44 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Routing/Router.php(776): Illuminate\Routing\Router->runRouteWithinStack()
#45 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Routing/Router.php(740): Illuminate\Routing\Router->runRoute()
#46 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Routing/Router.php(729): Illuminate\Routing\Router->dispatchToRoute()
#47 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(190): Illuminate\Routing\Router->dispatch()
#48 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(141): Illuminate\Foundation\Http\Kernel->Illuminate\Foundation\Http\{closure}()
#49 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Http/Middleware/TrustProxies.php(39): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#50 /var/www/bookstack/app/Http/Middleware/TrustProxies.php(41): Illuminate\Http\Middleware\TrustProxies->handle()
#51 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): BookStack\Http\Middleware\TrustProxies->handle()
#52 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#53 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php(40): Illuminate\Foundation\Http\Middleware\TransformsRequest->handle()
#54 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Foundation\Http\Middleware\TrimStrings->handle()
#55 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php(27): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#56 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Foundation\Http\Middleware\ValidatePostSize->handle()
#57 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php(86): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#58 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Foundation\Http\Middleware\PreventRequestsDuringMaintenance->handle()
#59 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(116): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#60 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(165): Illuminate\Pipeline\Pipeline->then()
#61 /var/www/bookstack/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(134): Illuminate\Foundation\Http\Kernel->sendRequestThroughRouter()
#62 /var/www/bookstack/public/index.php(52): Illuminate\Foundation\Http\Kernel->handle()
#63 {main}

Browser Details

Firefox on Linux 109.0.1

Exact BookStack Version

v23.01.1

PHP Version

8.2

Hosting Environment

Debian 11 up to date
Mariadb
Nginx with php8.2-fpm

@eoli3n
Copy link
Author

eoli3n commented Feb 28, 2023

I tried to configure php8.2-fpm as
In /etc/php/8.2/fpm/php.ini

[curl]
; A default value for the CURLOPT_CAINFO option. This is required to be an
; absolute path.
curl.cainfo=/usr/local/share/ca-certificates/ca.crt

[openssl]
; The location of a Certificate Authority (CA) file on the local filesystem
; to use when verifying the identity of SSL/TLS peers. Most users should
; not specify a value for this directive as PHP will attempt to use the
; OS-managed cert stores in its absence. If specified, this value may still
; be overridden on a per-stream basis via the "cafile" SSL stream context
; option.
openssl.cafile=/usr/local/share/ca-certificates/ca.crt

But it changed nothing

@eoli3n
Copy link
Author

eoli3n commented Feb 28, 2023

Reading #1922 didn't help

@eoli3n eoli3n changed the title can't login with LDAPS without LDAP_TLS_INSECURE=true can't login with LDAPS on AD without LDAP_TLS_INSECURE=true Feb 28, 2023
@eoli3n
Copy link
Author

eoli3n commented Feb 28, 2023

It seems that the server certificate miss a SAN, so maybe the issue is not related to BookStack.
I'll update this ASAP.

@ssddanbrown
Copy link
Member

Just something else to consider, are you sure you want to use ldaps? From what I understand, that is very old and somewhat outdated and it's more common to be using LDAP over tls (Over the default 389 port, using LDAP_START_TLS=true in the context of BookStack).

@eoli3n
Copy link
Author

eoli3n commented Feb 28, 2023

We fixed the problem with the missing SAN, other services run with verified LDAPS.
But BookStack still have problem to authenticate with LDAPS.

We are switching to LDAPS, and port 389 will be at some point closed.

@ssddanbrown
Copy link
Member

Just to confirm, have you restarted both nginx and php-fpm since updating the certs? Might also be worth restarting the system to ensure they're fully picked up.

Alternatively, you could try interacting with the /etc/openldap/ldap.conf file directly, in particular the TLS_CACERT and TLS_CACERTDIR options as detailed here: https://www.openldap.org/software//man.cgi?query=ldap.conf&sektion=5&apropos=0&manpath=OpenLDAP+2.4-Release

@eoli3n
Copy link
Author

eoli3n commented Mar 1, 2023

Just to confirm, have you restarted both nginx and php-fpm

Yes, I restarted both at each test.

Alternatively, you could try interacting with the /etc/openldap/ldap.conf file directly

Is bookstack using system wide ldap client ?
I don't have any installed for now, and it works. So I guess that php8.2-ldap use its own way to connect ?

@ssddanbrown
Copy link
Member

From what I can tell, the LDAP extension of PHP uses, and is compiled against, client libraries that handle LDAP abilities. In most cases this is OpenLDAP, and therefore certain configuration can be altered via openldap config.
I have not tested this though.

I did just access one of my ubuntu systems and noticed this config file is actually at /etc/ldap/ldap.conf (My earlier example was from my Fedora system) and this already had a pre-set TLS_CACERT option/location.

@eoli3n
Copy link
Author

eoli3n commented Mar 1, 2023

As I run Debian, I'll check which package holds that file, I don't have it by default.
I keep you updated soon.

@jasonyunliang
Copy link

I have the same issue as yours. i'm using AD LDAPs for other apps as well. it works just fine. until now, don't find any solution yet. it will only work with [LDAP_TLS_INSECURE=true]. was wondering how we can set up TLS since ldaps is old...

@drie-cdts
Copy link

drie-cdts commented Apr 14, 2023

I'm using BookStack v23.02.2 on Debian 11 with PHP 8.2 using the sury.org repo. LDAPS works perfectly fine for me.

My ldap config:

AUTH_METHOD=ldap
LDAP_SERVER="ldaps://dc01.domain.tld:636 ldaps://dc02.domain.tld:636"
LDAP_BASE_DN=ou=domain-user,dc=domain,dc=tld
LDAP_DN=cn=ldapreader,ou=domain-user,dc=domain,dc=tld
LDAP_PASS=***
LDAP_USER_FILTER=(&(objectClass=user)(sAMAccountName=${user})(memberOf:1.2.840.113556.1.4.1941:=CN=bookstack,OU=permissions,OU=domain-groups,DC=domain,DC=tld)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))
LDAP_VERSION=3
LDAP_EMAIL_ATTRIBUTE=mail
LDAP_DISPLAY_NAME_ATTRIBUTE=cn
LDAP_ID_ATTRIBUTE=BIN;objectGUID
LDAP_USER_TO_GROUPS=true
LDAP_GROUP_ATTRIBUTE="memberOf"
LDAP_REMOVE_FROM_GROUPS=true
LDAP_START_TLS=false
LDAP_TLS_INSECURE=false

I activated my internal CA certificates on debian using the command dpkg-reconfigure ca-certificates but I don't know if that makes any difference.
Are you really sure that the domain controller is using the right certificate? AD DS is a bit odd when multiple suitable certificates are present in the cert store. It does not use the newest (latest starting date) cert, it always uses the one with the largest lifetime (expiration date the furthest in future). You don't need to restart anything on the domain controller, the moment a better (longer lifetime) certificate is available it immediately starts using it.

@jasonyunliang
Copy link

i'm using rocky linux with docker-compose to set up bookstack. where should i import the DC CA to ? on the linux host /etc/pki/tls ? let me try that out. and will update later.

@jasonyunliang
Copy link

i didn't import the certificate, but directly change the settings below.

AUTH_METHOD=ldap
LDAP_SERVER=ldap://server.domain.com:389
LDAP_BASE_DN="dc=,dc="
LDAP_DN="cn=bind_dn,cn=users,dc=,dc="
LDAP_PASS="******************************"

LDAP_USER_FILTER=(&(sAMAccountName=${user}))
LDAP_VERSION=3
LDAP_ID_ATTRIBUTE=BIN;objectGUID

LDAP_EMAIL_ATTRIBUTE=mail
LDAP_START_TLS=true
LDAP_TLS_INSECURE=false

But everytime i login to the system , it has to go twice . and the first time showed " An unknown error occured , xxx " . and the second time can successfully sign in. it's very strange. dont know why.

@ssddanbrown
Copy link
Member

@jasonyunliang If you're running bookstack in a docker container, you'll need to be doing any certificate stuff within the container itself, rather than the host.

and the first time showed " An unknown error occured , xxx "

BookStack will log detail upon this error to its error log file as described here:
https://www.bookstackapp.com/docs/admin/debugging/

@jasonyunliang
Copy link

@ssddanbrown thanks for the info. it's really interesting. I removed the container and run the both container again. then tested the settings below

LDAP_SERVER=ldap://server.domain.com:389
LDAP_START_TLS=true
LDAP_TLS_INSECURE=false

it worked just fine...

I used tail -f for the laravel.log

the error i got today
[2023-04-18 01:33:53] production.ERROR: Failed to save user avatar image
[2023-04-18 01:34:39] production.ERROR: Failed to save user avatar image
[2023-04-18 01:42:18] production.ERROR: Failed to save user avatar image

Securing LDAP over SSL Safely [Windows Server 2019]
https://www.youtube.com/watch?v=8rlk2xDkgLw

I followed by the above youtube video to set up the LDAP over SSL on my DC. just for reference . Hope it helps.

@eoli3n
Copy link
Author

eoli3n commented Apr 3, 2024

Now it is not working anymore, even with LDAP_TLS_INSECURE=true, did something changed ?

@ssddanbrown
Copy link
Member

@eoli3n Not that I'm aware of. Any changes made to the wider system recently? What is the current error logged or seen?

@eoli3n
Copy link
Author

eoli3n commented Apr 3, 2024

I just retested to give you logs : it now works and we had a problem on our AD.
Thanks for your answer !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

No branches or pull requests

4 participants