Slow/failing Nextcloud OpenLDAP logins

Nextcloud version: Various 19, 20, 21, 22, 23, now 24.0.4
Operating system and version: Ubuntu 20.04, Ubuntu 22.04
Apache or nginx version: nginx 1.22.0
PHP version: previously on 7.4, now 8.0

The issue you are facing:

LDAP logins take an inordinately long time, and have been trending towards longer and longer with each Nextcloud upgrade. Currently taking over 3 and a half minutes for a login to complete. LDAP requests by other systems (Dovecot, phpLDAPAdmin, Linux PAM, Dokuwiki) do not exhibit similar delays.

Is this the first time you’ve seen this error? : N

Steps to replicate it:

  1. Configure LDAP authentication
  2. Attempt to login using an LDAP account
  3. Wait over three minutes for login or 2FA selection, depending on user settings.

The output of your Nextcloud log in Admin > Logging:

  Debug    user_ldap          Ready for a paged search                                                                                                      2022-09-10T21:05:56+00:00 

  Debug    user_ldap          initializing paged search for filter uid=MY-UID, base ou=MY-ACCOUNTS-OU,dc=MY-DOMAIN, attr                                  2022-09-10T21:05:56+00:00 
                              ["entryuuid","nsuniqueid","objectguid","guid","ipauniqueid","dn","uid","samaccountname","memberof","mail","displayname","jpegphoto","thumbnailphoto"],                           
                              limit 500, offset 0                                                                                                                                     

  Debug    no app in context  OC\AppFramework\Middleware\Security\Exceptions\NotLoggedInException: Current user is not logged in at                         2022-09-10T21:07:45+00:00 
                              .../Middleware/Security/SecurityMiddleware.php line 153                                                                                                 
                                                                                                                                                                                      
                              0. .../Middleware/MiddlewareDispatcher.php line 97                                                                                                      
                                 OC\AppFramework\Middleware\Security\SecurityMiddleware->beforeController(                                                                            
                                                                                                                                                                                      
                                 )                                                                                                                                                    
                              1. .../private/AppFramework/Http/Dispatcher.php line 125                                                                                                
                                 OC\AppFramework\Middleware\MiddlewareDispatcher->beforeController(                                                                                   
                                                                                                                                                                                      
                                 )                                                                                                                                                    
                              2. lib/private/AppFramework/App.php line 172                                                                                                            
                                 OC\AppFramework\Http\Dispatcher->dispatch(                                                                                                           
                                                                                                                                                                                      
                                 )                                                                                                                                                    
                              3. lib/private/Route/Router.php line 298                                                                                                                
                                 OC\AppFramework\App::main(                                                                                                                           
                                                                                                                                                                                      
                                 )                                                                                                                                                    
                              4. lib/base.php line 1023                                                                                                                               
                                 OC\Route\Router->match(                                                                                                                              
                                                                                                                                                                                      
                                 )                                                                                                                                                    
                              5. index.php line 36                                                                                                                                    
                                 OC::handleRequest(                                                                                                                                   
                                                                                                                                                                                      
                                 ) 

This keeps repeating.

The output of your config.php file in /path/to/nextcloud (make sure you remove any identifiable information!):

<?php
$CONFIG = array (
  'passwordsalt' => 'REMOVED',
  'secret' => 'REMOVED',
  'trusted_domains' => 
  array (
    0 => 'localhost',
    1 => 'MY-DOMAIN-NAME',
    2 => 'INTERNAL-IP',
    3 => 'INTERNAL-HOST-NAME',
  ),
  'datadirectory' => '/REMOVED',
  'dbtype' => 'mysql',
  'version' => '24.0.4.1',
  'overwrite.cli.url' => 'REMOVED',
  'overwritehost' => 'REMOVED',
  'overwriteprotocol' => 'https',
  'dbname' => 'nextcloud',
  'dbhost' => 'localhost',
  'dbport' => '',
  'dbtableprefix' => 'oc_',
  'mysql.utf8mb4' => true,
  'dbuser' => 'REMOVED',
  'dbpassword' => 'REMOVED',
  'installed' => true,
  'instanceid' => 'REMOVED',
  'ldapIgnoreNamingRules' => false,
  'ldapProviderFactory' => 'OCA\\User_LDAP\\LDAPProviderFactory',
  'mail_smtpmode' => 'smtp',
  'mail_sendmailmode' => 'pipe',
  'mail_from_address' => 'REMOVED',
  'mail_domain' => 'REMOVED',
  'memcache.local' => '\\OC\\Memcache\\APCu',
  'memcache.distributed' => '\\OC\\Memcache\\Redis',
  'redis' => 
  array (
    'host' => '127.0.0.1',
    'port' => 6379,
  ),
  'mail_smtpsecure' => 'tls',
  'mail_smtpauthtype' => 'LOGIN',
  'mail_smtpauth' => 1,
  'mail_smtphost' => 'REMOVED',
  'mail_smtpport' => '25',
  'mail_smtpname' => 'REMOVED',
  'mail_smtppassword' => 'REMOVED',
  'maintenance' => false,
  'theme' => '',
  'loglevel' => 0,
  'data-fingerprint' => 'REMOVED',
  'default_phone_region' => 'AU',
  'app_install_overwrite' => 
  array (
    0 => 'ocsms',
    1 => 'deck',
    2 => 'previewgenerator',
    3 => 'end_to_end_encryption',
    4 => 'flow_notifications',
    5 => 'ldap_write_support',
  ),
  'twofactor_enforced' => 'false',
  'twofactor_enforced_groups' => 
  array (
  ),
  'twofactor_enforced_excluded_groups' => 
  array (
  ),
);

The output of your Apache/nginx/system log in /var/log/____:

Nothing unusual.

In my LDAP/AD integration settings, on the Server tab, I have my server base dn entered, and clicking “Test Base DN” returns:

44 entries available within the provided Base DN

so as you can see, I don’t have a large directory!

Under the Users tab, I have selected inetOrgPerson in the “Only these object classes” field, giving an LDAP Filter of:

(|(objectclass=inetOrgPerson))

“Only from these groups:” is disabled, as my LDAP server does not have MemberOfGroup enabled.

Clicking “Verify settings and count users” returns:

2 users found

On the Login Attributes tab, I have followed the example of this post and set my LDAP Query to simply:

uid=%uid

Putting in my userid and clicking “Verify Settings” returns:

User found and settings verified.

But then I see this in my logs during login attempts:

No DN found for MY-UID on MY-DOMAIN

The LDAP entry for my account has a dn of uid=MY-UID,ou=MY-ACCOUNT_OU,dc=MY-DOMAIN.

What the heck is going on?

I’ve tried various different options with the LDAP filters: using the filters as generated, editing the LDAP filters manually, setting different options to relevant settings, none of which seems to make any difference, and now in trying those things, my logins have blown out to almost 4 minutes.

Also strange is that it returns a “bad username or password” result immediately, so it seems it gets the answer from the ldap server straight away, which my openldap logs supports, but then spends a few minutes doing something in the background. Something that over time, takes longer and longer to happen.

Ok, on further investigation, it seems those recurring log entries about paged searches are probably related to logged in mobile apps checking in.

I have disabled/removed a bunch of apps that we weren’t using, including LDAP Write Support, and login times are back down to just over a minute, which is still crazy slow, but bearable. Really, I would expect a slow login process to take ten to twenty seconds.