Proxmox & LDAP

eferrandi

New Member
Oct 29, 2024
6
0
1
Hello,

I'm trying to connect my Proxmox server to an LDAP server located internally.
Here is my configuration:

Code:
ldap: ldap-ext
        base_dn ou=company,o=group,c=fr
        server1 ldap.fqdn
        user_attr uid
        bind_dn uid=proxmox,ou=system,ou=company,o=group,c=fr
        default 0
        filter memberof=cn=tests,ou=groups,ou=company,o=group,c=fr
        group_classes groupOfNames
        group_filter (|(cn=IT*)(ou=groups)(ou=company)(o=group)(dc=fr))
        group_name_attr cn
        sync-defaults-options remove-vanished=acl;entry;properties,scope=both
        sync_attributes email=mail
        user_classes inetOrgPerson

When I import the users and groups, I can see the users and the link with the groups, the synchro is good. But when I try to connect, I get a “Login failed. Please try again”.

Looking at the logs, I see the same thing:
Code:
proxmox1 pvedaemon[53456]: authentication failure; rhost=::ffff:192.168.1.1 user=test@ldap-ext msg=Invalid credentials

Users are functional on other tools (grafana, jenkins, gitlab...) connected to LDAP.

Is the LDAP server connection configuration correct?

Thanks for your help
 
Last edited:
Hi eferrandi,

I most certainly can reproduce the error for a failing user login when I type the wrong password for a user.

What confuses me is the log entry -- your config names the ldap 'ldap-ext', but the error comes from user 'test@ldap'. This should say 'test@ldap-ext' if things are right.

Is it possible, that you have some remainders from previous syncs/config attempts? You might consider double-checking what you have in Datacenter->Permissions->Realms and Datacenter->Permissions->Users.

Best,
Daniel
 
Hi Daniel,
Thank you for your reply.
It's a typo in my thread, the realm name is ldap-ext, I've just fixed it.

Is it possible to clean the previous remainders? I've already made several syncs by activating all the “Remove Vanished Options” boxes.
Also, when I change the group for user filter (filter memberof), the users change, so I assume that synchronization works.
 
Last edited:
Hi eferrandi,

If you have an old realm, which is not in use anymore, you might just remove it from Datacenter->Permissions->Realms, and then remove the User entries associated with that realms from Datacenter->Permissions->Users. They will not be autoremoved, but you can sort the list to ease things.

If your sync works, you should actually be able to login with the users visible in Datacenter->Permissions->Users (but by default without any permissions and not being able to see more than the node names). PVE will not store the users' passwords (despite the bind users' one, if you have your LDAP locked down), if I understand correctly.

Have you already tried with another user? Maybe the 'test' user's password has been changed on the LDAP-side?

Best,
Daniel
 
Hi Daniel,
Here are my attempts:
  • Delete Realms and users, groups associated
  • Change bind-dn user and password
None of these actions solved the problem...

I didn't mention it earlier but I have a single user (eferrandi) that works but all imported users can't connect.
I did an action previously by adding it by hand. Does Proxmox keep a cache for authentication?
 
Hi eferrandi,

Help me understand:
  • you have configured an ldap server, and use it to manage credentials for efferandi, username01, username02, etc
  • you have configured the ldap realm 'ldap-ext' in PVE and can the users from the ldap server, Datacenter->Permissions->Users shows:
  • efferandi@ldap-ext
  • username01@ldap-ext
  • username02@ldap-ext
  • etc
  • you deleted all those users from Datacenter->Permissions->Users, did another sync, and they reappeared
  • you have additionally set up efferandi@ldap-ext in Datacenter->Permissions->Users (another user on your ldap-server, just like username01, username02, etc)
  • efferendi, username01, username02 share the same charset in their passwords
-> with efferendi@ldap-ext you can log into the webUI but with neither with username01@ldap-ext nor username02@ldap-ext?

Would you mind sharing which version of PVE you are using, and which version of openldap?

(Here I have PVE 8.3.0 and slapd 2.5.13+dfsg-5 from the TurnKey Openldap 18.1 LXC Container)

Best,
Daniel
 
Last edited:
Hi Daniel,
I found the problem.
My DN database contains users, groups and user aliases.

Here is the LDAP search command:
Code:
SRCH base=“ou=company,o=group,c=en” scope=2 deref=2 filter="(uid=testefe)”
And here's the result:
Code:
BIND dn="uid=testefe,ou=users,ou=appli,ou=apps,ou=company,o=group,c=fr”
And I want :
Code:
dn="uid=testefe,ou=users,ou=company,o=group,c=fr”

Do you know what the variables scope and deref mean in the search query?

To answer your questions, I'm using Proxmox version 8.3.0 and OpenLDAP version 2.6.
I can confirm that the eferrandi account is working correctly and that the users username01@ldap-ext & username02@ldap-ext are unable to connect.

Thanks a lot for your help !
 
Last edited:
Hi efferandi,

how did you isolate the LDAP search command? Do you have an idea, how the 'c=en' (as well as scope=2 and deref=2) gets into this discussion, have you changed your ldap-realm settings on the PVE-side? If so, would you mind sharing the updated configuration that you are actually using?

Best,
Daniel
 
Would you mind sharing the output of the Task-Window, when you click 'sync'?
 
Hi efferandi,

as it is very easy to get confused with LDAP trees -- here I have a minimal working example:


complete subtree export of the ldap server at 10.10.10.22 (2 groups, three users, just one user in the group that should be synced into PVE [and thus completely unpriviledged be allowed to log in]):


Code:
version: 1

# Entry 1: dc=host,dc=example,dc=invalid
dn: dc=host,dc=example,dc=invalid
dc: host
o: host.example.invalid
objectclass: top
objectclass: dcObject
objectclass: organization

# Entry 2: ou=Aliases,dc=host,dc=example,dc=invalid
dn: ou=Aliases,dc=host,dc=example,dc=invalid
objectclass: organizationalUnit
objectclass: top
ou: Aliases

# Entry 3: ou=Groups,dc=host,dc=example,dc=invalid
dn: ou=Groups,dc=host,dc=example,dc=invalid
objectclass: organizationalUnit
objectclass: top
ou: Groups

# Entry 4: cn=pve_users,ou=Groups,dc=host,dc=example,dc=invalid
dn: cn=pve_users,ou=Groups,dc=host,dc=example,dc=invalid
cn: pve_users
gidnumber: 2001
memberuid: fbor
objectclass: posixGroup
objectclass: top

# Entry 5: cn=users,ou=Groups,dc=host,dc=example,dc=invalid
dn: cn=users,ou=Groups,dc=host,dc=example,dc=invalid
cn: users
gidnumber: 100
objectclass: posixGroup
objectclass: top

# Entry 6: ou=Users,dc=host,dc=example,dc=invalid
dn: ou=Users,dc=host,dc=example,dc=invalid
objectclass: organizationalUnit
objectclass: top
ou: Users

# Entry 7: cn=Fee Bor,ou=Users,dc=host,dc=example,dc=invalid
dn: cn=Fee Bor,ou=Users,dc=host,dc=example,dc=invalid
cn: Fee Bor
gidnumber: 2001
givenname: Fee
homedirectory: /home/users/fbor
objectclass: inetOrgPerson
objectclass: posixAccount
objectclass: top
sn: Bor
uid: fbor
uidnumber: 2001
userpassword: {MD5}Qpf0SxOVUjUkWySXOZ16kw==

# Entry 8: cn=Fefe Boo,ou=Users,dc=host,dc=example,dc=invalid
dn: cn=Fefe Boo,ou=Users,dc=host,dc=example,dc=invalid
cn: Fefe Boo
gidnumber: 100
givenname: Fefe
homedirectory: /home/users/fboo
objectclass: inetOrgPerson
objectclass: posixAccount
objectclass: top
sn: Boo
uid: fboo
uidnumber: 2003
userpassword: {MD5}i5mrJYdVD0cdIvzfJvhlgQ==

# Entry 9: cn=Foo Bar,ou=Users,dc=host,dc=example,dc=invalid
dn: cn=Foo Bar,ou=Users,dc=host,dc=example,dc=invalid
cn: Foo Bar
gidnumber: 100
givenname: Foo
homedirectory: /home/users/fbar
objectclass: inetOrgPerson
objectclass: posixAccount
objectclass: top
sn: Bar
uid: fbar
uidnumber: 2002
userpassword: {MD5}Qpf0SxOVUjUkWySXOZ16kw==

Configuration of ldap realm in PVE from /etc/pve/domains.cfg (but created via GUI, no editing done on the file directly):


Code:
ldap: openldap
        base_dn dc=host,dc=example,dc=invalid
        server1 10.10.10.22
        user_attr uid
        default 0
        filter gidnumber=2001
        group_classes posixGroup
        group_filter cn=pve_users
        group_name_attr cn
        sync-defaults-options remove-vanished=acl;entry;properties,scope=both

When syncing, this just imports the group pve_users (labelled in PVE as pve_users-openldap) and just the the user fbor. On the LDAP side this user is put into the group pve_users, by giving it the relevant gidnumber (2001), which is assigned to the group pve_users.

If the password for user 'fbor' is changed on the LDAP-side, this takes immediate effect on the PVE-side, so no, passwords despite the bind user's one (if needed) is not cached to my experience.

I know this is a much simpler example than your architecture, but I hope it helps anyway,

Best,
Daniel
 
After deleting both fbor and pve_users-openldap from PVE and clicking onto 'sync' with the realm 'openldap' selected, this shows the following in the Task Window:


Code:
starting sync for realm openldap
got data from server, updating users and groups
syncing users (remove-vanished opts: acl;entry;properties)
deleting outdated existing users first
adding user 'fbor@openldap'
syncing groups (remove-vanished opts: acl;entry;properties)
deleting outdated existing groups first
adding group 'pve_users-openldap'
successfully updated users and groups configuration
TASK OK
 
Answer for Reply #8
I retrieved this LDAP search command from the OpenLDAP logs.
'c=en' is a typo (again...) but scope and deref are in search request recovered inside openldap log.

Here is the output when I use the DN ou=users,ou=company,o=group,c=fr when I click 'sync' :
Code:
Header
Proxmox
Virtual Environment 8.3.0
Datacenter
Logs
(dry test run) starting sync for realm ldap-ext
got data from server, updating users
syncing users (remove-vanished opts: acl;entry;properties)
deleting outdated existing users first
overwriting user 'eferrandi@ldap-ext'
overwriting user 'user1@ldap-ext'
overwriting user 'user2@ldap-ext'

NOTE: Dry test run, changes were NOT written to the configuration.
TASK OK

And with this DN : ou=company,o=group,c=fr
Code:
(dry test run) starting sync for realm ldap-ext
got data from server, updating users and groups
syncing users (remove-vanished opts: acl;entry;properties)
deleting outdated existing users first
overwriting user 'eferrandi@ldap-ext'
overwriting user 'user1@ldap-ext'
overwriting user 'user2@ldap-ext'
syncing groups (remove-vanished opts: acl;entry;properties)
deleting outdated existing groups first
overwriting group 'Group1'
overwriting group 'Group2'

NOTE: Dry test run, changes were NOT written to the configuration.
TASK OK

Answer for Reply #10
In your example, you don't have a user alias. In fact, when I only target this DN: ou=users,ou=cls,o=clsgroup,c=en, I don't have any aliases and all my users are able to connect.
 
Hi!

OK -- this looks good to me (you're just previewing, right?).
For interest -- how are you using the aliases on the LDAP-side?

Best,
Daniel
 
Hi!
Here's how our aliases are declared:
Code:
objectClass: alias(structural)
objectClass: extensibleObject(auxiliary)
objectClass: top(abstract)
aliasedObjectName: uid:test-efe...
I can confirm that aliases are not tracked at Proxmox level, only real users are taken into account.

Also, in numerous tests, I discovered that users assigned to a posixGroup were not synchronized in Proxmox groups. They must be assigned to groupOfNames groups. I obviously changed the groupClasses to run my tests.
 
Hi!

mhm, I just set up a gitlab testinstance, and when I try to log in using an alias I get:

Code:
Could not authenticate you from Ldapmain because "Invalid credentials for elfbor".

where 'elfbor' is an alias to 'fbor' (which can log in to gitlab without any problems). So at least to me this does not seem to be PVE-specific.

Here's my tree with aliases:
Code:
# LDIF Export for cn=config|dc=host,dc=example,dc=invalid
# Server: TurnKey OpenLDAP (127.0.0.1)
# Search Scope: sub
# Search Filter: (objectClass=*)
# Total Entries: 10
#
# Generated by phpLDAPadmin (http://phpldapadmin.sourceforge.net) on December 6, 2024 10:34 am
# Version: 1.2.6.3

version: 1

# Entry 1: dc=host,dc=example,dc=invalid
dn: dc=host,dc=example,dc=invalid
dc: host
o: host.example.invalid
objectclass: top
objectclass: dcObject
objectclass: organization

# Entry 2: ou=Aliases,dc=host,dc=example,dc=invalid
dn: ou=Aliases,dc=host,dc=example,dc=invalid
objectclass: organizationalUnit
objectclass: top
ou: Aliases

# Entry 3: uid=elfbor,ou=Aliases,dc=host,dc=example,dc=invalid
dn: uid=elfbor,ou=Aliases,dc=host,dc=example,dc=invalid
aliasedobjectname: uid=fbor,ou=Users,dc=host,dc=example,dc=invalid
objectclass: alias
objectclass: extensibleObject
objectclass: top
uid: elfbor

# Entry 4: ou=Groups,dc=host,dc=example,dc=invalid
dn: ou=Groups,dc=host,dc=example,dc=invalid
objectclass: organizationalUnit
objectclass: top
ou: Groups

# Entry 5: cn=pve_users,ou=Groups,dc=host,dc=example,dc=invalid
dn: cn=pve_users,ou=Groups,dc=host,dc=example,dc=invalid
cn: pve_users
gidnumber: 2001
memberuid: fbor
objectclass: posixGroup
objectclass: top

# Entry 6: cn=users,ou=Groups,dc=host,dc=example,dc=invalid
dn: cn=users,ou=Groups,dc=host,dc=example,dc=invalid
cn: users
gidnumber: 100
objectclass: posixGroup
objectclass: top

# Entry 7: ou=Users,dc=host,dc=example,dc=invalid
dn: ou=Users,dc=host,dc=example,dc=invalid
objectclass: organizationalUnit
objectclass: top
ou: Users

# Entry 8: cn=Fee Bor,ou=Users,dc=host,dc=example,dc=invalid
dn: cn=Fee Bor,ou=Users,dc=host,dc=example,dc=invalid
cn: Fee Bor
gidnumber: 2001
givenname: Fee
homedirectory: /home/users/fbor
mail: me@example.invalid
objectclass: inetOrgPerson
objectclass: posixAccount
objectclass: top
sn: Bor
uid: fbor
uidnumber: 2001
userpassword: {MD5}Qpf0SxOVUjUkWySXOZ16kw==

# Entry 9: cn=Fefe Boo,ou=Users,dc=host,dc=example,dc=invalid
dn: cn=Fefe Boo,ou=Users,dc=host,dc=example,dc=invalid
cn: Fefe Boo
gidnumber: 100
givenname: Fefe
homedirectory: /home/users/fboo
objectclass: inetOrgPerson
objectclass: posixAccount
objectclass: top
sn: Boo
uid: fboo
uidnumber: 2003
userpassword: {MD5}i5mrJYdVD0cdIvzfJvhlgQ==

# Entry 10: cn=Foo Bar,ou=Users,dc=host,dc=example,dc=invalid
dn: cn=Foo Bar,ou=Users,dc=host,dc=example,dc=invalid
cn: Foo Bar
gidnumber: 100
givenname: Foo
homedirectory: /home/users/fbar
objectclass: inetOrgPerson
objectclass: posixAccount
objectclass: top
sn: Bar
uid: fbar
uidnumber: 2002
userpassword: {MD5}Qpf0SxOVUjUkWySXOZ16kw==

Can you elaborate on 'users assigned to a posixGroup were not synchronized in Proxmox groups'?

Best,
Daniel

PS: in gitlab's gitlab.rb I'm using 'base: dc=host,dc=example,dc=invalid' in the ldap section.
 
Last edited: