Multiple ldap instances - User Group Membership search not done
Hi all, I have a question regarding multiple ldap instances in freeradius and searching users in LDAP-Groups. First of all, what do I try to achieve: Freeradius has to authenticate and authorize our admin users for our customers network devices. It has to perform user authentication with a simple ldap bind authentication and look up the group membership of the user. If the password of the user is correct and the user is member of a specific group, access shall be granted. I have already achieved a working configuration for the tasks above. I recently got a new task to allow also our customers access to their network devices with read-only access. The customer users are already configured in another ldap server. So I would like to configure two named ldap instances in rlm_ldap. If I do so, the authentication part for the admin user still works, but freeradius will not search the LDAP for user membership anymore and reject access. Please find below the config and debug output of the working configuration with only one ldap server And the modified config with two named ldap instances. Any help appreciated. If further debug output is needed, please let me know. Best regards, Florian #################### ## ## Sinlge LDAP Server configuration working ## LDAP search is performed and user is found in the configured group ## #################### Single LDAP Server configured: :/etc/freeradius/3.0# grep -v '#' mods-enabled/ldap | grep -v -e '^$' ldap { server = 'IP' identity = 'CN=freerad,OU=Service-Accounts,OU=User,OU=mycompany,DC=mycompany,DC=de' password = removed base_dn = 'OU=mycompany,DC=mycompany,DC=de' sasl { } update { control:Password-With-Header += 'userPassword' control: += 'radiusControlAttribute' request: += 'radiusRequestAttribute' reply: += 'radiusReplyAttribute' } user { base_dn = "${..base_dn}" filter = "(sAMAccountName=%{%{Stripped-User-Name}:-%{User-Name}})" sasl { } } group { base_dn = "${..base_dn}" filter = '(objectClass=posixGroup)' scope = 'sub' name_attribute = cn membership_filter = "(|(&(objectClass=group)(member=%{control:Ldap-UserDn})))" membership_attribute = 'memberOf' } profile { } client { base_dn = "${..base_dn}" filter = '(objectClass=radiusClient)' template { } attribute { ipaddr = 'radiusClientIdentifier' secret = 'radiusClientSecret' } } accounting { reference = "%{tolower:type.%{Acct-Status-Type}}" type { start { update { description := "Online at %S" } } interim-update { update { description := "Last seen at %S" } } stop { update { description := "Offline at %S" } } } } post-auth { update { description := "Authenticated at %S" } } options { chase_referrals = yes rebind = yes res_timeout = 10 srv_timelimit = 3 net_timeout = 1 idle = 60 probes = 3 interval = 3 ldap_debug = 0x0028 } tls { } pool { start = ${thread[pool].start_servers} min = ${thread[pool].min_spare_servers} max = ${thread[pool].max_servers} spare = ${thread[pool].max_spare_servers} uses = 0 retry_delay = 30 lifetime = 0 idle_timeout = 60 } } :/etc/freeradius/3.0# grep -v '#' sites-enabled/default | grep -v -e '^$' server default { listen { type = auth ipaddr = * port = 0 limit { max_connections = 16 lifetime = 0 idle_timeout = 30 } } listen { ipaddr = * port = 0 type = acct limit { } } listen { type = auth port = 0 limit { max_connections = 16 lifetime = 0 idle_timeout = 30 } } listen { ipv6addr = :: port = 0 type = acct limit { } } authorize { preprocess eap { ok = return } ldap if ((ok || updated) && User-Password) { update { control:Auth-Type := ldap } } } authenticate { digest Auth-Type LDAP { ldap if (LDAP-Group == "mycompany_Technik_Sec"){ if (Huntgroup-Name == "fortigate") { update reply { Fortinet-Group-Name = "mycompany_Operations" Fortinet-Access-Profile = "super_admin" } } } else { reject } } eap } preacct { preprocess acct_unique suffix files } accounting { detail unix -sql exec attr_filter.accounting_response } session { } post-auth { update { &reply: += &session-state: } -sql exec remove_reply_message_if_eap Post-Auth-Type REJECT { -sql attr_filter.access_reject eap remove_reply_message_if_eap } Post-Auth-Type Challenge { } } pre-proxy { } post-proxy { eap } } Debug output of auth request tested via radtest -t pap user.name pw-removed localhost 0 testing123 (0) Received Access-Request Id 178 from 127.0.0.1:52807 to 127.0.0.1:1812 length 81 (0) User-Name = "user.name" (0) User-Password = "pw-removed" (0) NAS-IP-Address = 127.0.1.1 (0) NAS-Port = 0 (0) Message-Authenticator = 0x87ca46d1ef7da1eb772aef641e0d9e02 (0) # Executing section authorize from file /etc/freeradius/3.0/sites-enabled/default (0) authorize { (0) [preprocess] = ok (0) eap: No EAP-Message, not doing EAP (0) [eap] = noop rlm_ldap (ldap): Reserved connection (0) (0) ldap: EXPAND (sAMAccountName=%{%{Stripped-User-Name}:-%{User-Name}}) (0) ldap: --> (sAMAccountName=user.name) (0) ldap: Performing search in "OU=mycompany,DC=mycompany,DC=mycompany,DC=de" with filter "(sAMAccountName=user.name)", scope "sub" (0) ldap: Waiting for search result... (0) ldap: User object found at DN "CN=User Name,OU=Windows 10 User,OU=User,OU=mycompany,DC=mycompany,DC=mycompany,DC=de" (0) ldap: Processing user attributes (0) ldap: WARNING: No "known good" password added. Ensure the admin user has permission to read the password attribute (0) ldap: WARNING: PAP authentication will *NOT* work with Active Directory (if that is what you were trying to configure) rlm_ldap (ldap): Released connection (0) Need 5 more connections to reach 10 spares rlm_ldap (ldap): Opening additional connection (5), 1 of 27 pending slots used rlm_ldap (ldap): Connecting to ldap://IP:389 rlm_ldap (ldap): Waiting for bind result... rlm_ldap (ldap): Bind successful (0) [ldap] = ok (0) if ((ok || updated) && User-Password) { (0) if ((ok || updated) && User-Password) -> TRUE (0) if ((ok || updated) && User-Password) { (0) update { (0) control:Auth-Type := LDAP (0) } # update = noop (0) } # if ((ok || updated) && User-Password) = noop (0) } # authorize = ok (0) Found Auth-Type = LDAP (0) # Executing group from file /etc/freeradius/3.0/sites-enabled/default (0) Auth-Type LDAP { rlm_ldap (ldap): Reserved connection (1) (0) ldap: Login attempt by "user.name" (0) ldap: Using user DN from request "CN=User Name,OU=Windows 10 User,OU=User,OU=mycompany,DC=mycompany,DC=mycompany,DC=de" (0) ldap: Waiting for bind result... (0) ldap: Bind successful (0) ldap: Bind as user "CN=User Name,OU=Windows 10 User,OU=User,OU=mycompany,DC=mycompany,DC=mycompany,DC=de" was successful rlm_ldap (ldap): Released connection (1) (0) [ldap] = ok (0) if (LDAP-Group == "mycompany_Technik_Sec"){ (0) Searching for user in group "mycompany_Technik_Sec" rlm_ldap (ldap): Reserved connection (2) (0) Using user DN from request "CN=User Name,OU=Windows 10 User,OU=User,OU=mycompany,DC=mycompany,DC=mycompany,DC=de" (0) Checking for user in group objects (0) EXPAND (&(cn=mycompany_Technik_Sec)(objectClass=posixGroup)(|(&(objectClass=group)(member=%{control:Ldap-UserDn})))) (0) --> (&(cn=mycompany_Technik_Sec)(objectClass=posixGroup)(|(&(objectClass=group)(member=CN\3dUser Name\2cOU\3dWindows 10 User\2cOU\3dUser\2cOU\3dmycompany\2cDC\3dmycompany\2cDC\3dmycompany\2cDC\3dde)))) (0) Performing search in "OU=mycompany,DC=mycompany,DC=mycompany,DC=de" with filter "(&(cn=mycompany_Technik_Sec)(objectClass=posixGroup)(|(&(objectClass=group)(member=CN\3dUser Name\2cOU\3dWindows 10 User\2cOU\3dUser\2cOU\3dmycompany\2cDC\3dmycompany\2cDC\3dmycompany\2cDC\3dde))))", scope "sub" (0) Waiting for search result... (0) Search returned no results (0) Checking user object's memberOf attributes (0) Performing unfiltered search in "CN=User Name,OU=Windows 10 User,OU=User,OU=mycompany,DC=mycompany,DC=mycompany,DC=de", scope "base" (0) Waiting for search result... ber_get_next failed. ber_get_next failed. (0) Processing memberOf value "CN=mycompany_pdns_operator,OU=PDNS,OU=Sicherheitsgruppen,OU=Gruppen,OU=mycompany,DC=mycompany,DC=mycompany,DC=de" as a DN (0) Resolving group DN "CN=mycompany_pdns_operator,OU=PDNS,OU=Sicherheitsgruppen,OU=Gruppen,OU=mycompany,DC=mycompany,DC=mycompany,DC=de" to group name ... (0) Processing memberOf value "CN=mycompany_Technik_Sec,OU=Sicherheitsgruppen,OU=Gruppen,OU=mycompany,DC=mycompany,DC=mycompany,DC=de" as a DN (0) Resolving group DN "CN=mycompany_Technik_Sec,OU=Sicherheitsgruppen,OU=Gruppen,OU=mycompany,DC=mycompany,DC=mycompany,DC=de" to group name (0) Performing unfiltered search in "CN=mycompany_Technik_Sec,OU=Sicherheitsgruppen,OU=Gruppen,OU=mycompany,DC=mycompany,DC=mycompany,DC=de", scope "base" (0) Waiting for search result... (0) Group DN "CN=mycompany_Technik_Sec,OU=Sicherheitsgruppen,OU=Gruppen,OU=mycompany,DC=mycompany,DC=mycompany,DC=de" resolves to name "mycompany_Technik_Sec" (0) User found in group "mycompany_Technik_Sec". Comparison between membership: name (resolved from DN "CN=mycompany_Technik_Sec,OU=Sicherheitsgruppen,OU=Gruppen,OU=mycompany,DC=mycompany,DC=mycompany,DC=de"), check: name rlm_ldap (ldap): Released connection (2) (0) if (LDAP-Group == "mycompany_Technik_Sec") -> TRUE (0) if (LDAP-Group == "mycompany_Technik_Sec") { (0) if (Huntgroup-Name == "fortigate") { (0) ERROR: Failed retrieving values required to evaluate condition (0) } # if (LDAP-Group == "mycompany_Technik_Sec") = ok (0) ... skipping else: Preceding "if" was taken (0) } # Auth-Type LDAP = ok (0) # Executing section post-auth from file /etc/freeradius/3.0/sites-enabled/default (0) post-auth { (0) update { (0) No attributes updated (0) } # update = noop (0) [exec] = noop (0) policy remove_reply_message_if_eap { (0) if (&reply:EAP-Message && &reply:Reply-Message) { (0) if (&reply:EAP-Message && &reply:Reply-Message) -> FALSE (0) else { (0) [noop] = noop (0) } # else = noop (0) } # policy remove_reply_message_if_eap = noop (0) } # post-auth = noop (0) Sent Access-Accept Id 178 from 127.0.0.1:1812 to 127.0.0.1:52807 length 0 (0) Finished request Waking up in 4.9 seconds. (0) Cleaning up request packet ID 178 with timestamp +15 Ready to process requests #################### ## ## Multiple LDAP Server configuration not working ## Looks like freeradius is not searching the ldap ## #################### :/etc/freeradius/3.0# grep -v '#' mods-enabled/ldap | grep -v -e '^$' ldap mycompany { server = 'IP' identity = 'CN=freerad,OU=Service-Accounts,OU=User,OU=mycompany,DC=mycompany,DC=de' password = removed base_dn = 'OU=mycompany,DC=mycompany,DC=de' sasl { } update { control:Password-With-Header += 'userPassword' control: += 'radiusControlAttribute' request: += 'radiusRequestAttribute' reply: += 'radiusReplyAttribute' } user { base_dn = "${..base_dn}" filter = "(sAMAccountName=%{%{Stripped-User-Name}:-%{User-Name}})" sasl { } } group { base_dn = "${..base_dn}" filter = '(objectClass=posixGroup)' scope = 'sub' name_attribute = cn membership_filter = "(|(&(objectClass=group)(member=%{control:Ldap-UserDn})))" membership_attribute = 'memberOf' } profile { } client { base_dn = "${..base_dn}" filter = '(objectClass=radiusClient)' template { } attribute { ipaddr = 'radiusClientIdentifier' secret = 'radiusClientSecret' } } accounting { reference = "%{tolower:type.%{Acct-Status-Type}}" type { start { update { description := "Online at %S" } } interim-update { update { description := "Last seen at %S" } } stop { update { description := "Offline at %S" } } } } post-auth { update { description := "Authenticated at %S" } } options { chase_referrals = yes rebind = yes res_timeout = 10 srv_timelimit = 3 net_timeout = 1 idle = 60 probes = 3 interval = 3 ldap_debug = 0x0028 } tls { } pool { start = ${thread[pool].start_servers} min = ${thread[pool].min_spare_servers} max = ${thread[pool].max_servers} spare = ${thread[pool].max_spare_servers} uses = 0 retry_delay = 30 lifetime = 0 idle_timeout = 60 } } ldap customers { server = 'IP' identity = 'CN=freerad,OU=Service-Accounts,OU=User,OU=mycompany,DC=mycompany,DC=de' password = removed base_dn = 'OU=mycompany,DC=mycompany,DC=mycompany,DC=de' sasl { } update { control:Password-With-Header += 'userPassword' control: += 'radiusControlAttribute' request: += 'radiusRequestAttribute' reply: += 'radiusReplyAttribute' } user { base_dn = "${..base_dn}" filter = "(sAMAccountName=%{%{Stripped-User-Name}:-%{User-Name}})" sasl { } } group { base_dn = "${..base_dn}" filter = '(objectClass=posixGroup)' scope = 'sub' name_attribute = cn membership_filter = "(|(&(objectClass=group)(member=%{control:Ldap-UserDn})))" membership_attribute = 'memberOf' } profile { } client { base_dn = "${..base_dn}" filter = '(objectClass=radiusClient)' template { } attribute { ipaddr = 'radiusClientIdentifier' secret = 'radiusClientSecret' } } accounting { reference = "%{tolower:type.%{Acct-Status-Type}}" type { start { update { description := "Online at %S" } } interim-update { update { description := "Last seen at %S" } } stop { update { description := "Offline at %S" } } } } post-auth { update { description := "Authenticated at %S" } } options { chase_referrals = yes rebind = yes res_timeout = 10 srv_timelimit = 3 net_timeout = 1 idle = 60 probes = 3 interval = 3 ldap_debug = 0x0028 } tls { } pool { start = ${thread[pool].start_servers} min = ${thread[pool].min_spare_servers} max = ${thread[pool].max_servers} spare = ${thread[pool].max_spare_servers} uses = 0 retry_delay = 30 lifetime = 0 idle_timeout = 60 } } :/etc/freeradius/3.0# grep -v '#' sites-enabled/default | grep -v -e '^$' server default { listen { type = auth ipaddr = * port = 0 limit { max_connections = 16 lifetime = 0 idle_timeout = 30 } } listen { ipaddr = * port = 0 type = acct limit { } } listen { type = auth port = 0 limit { max_connections = 16 lifetime = 0 idle_timeout = 30 } } listen { ipv6addr = :: port = 0 type = acct limit { } } authorize { filter_username preprocess eap { ok = return } mycompany if ((ok || updated) && User-Password) { update { control:Auth-Type := ldap } } customers if ((ok || updated) && User-Password) { update { control:Auth-Type := ldap } } } authenticate { digest Auth-Type LDAP { mycompany if (mycompany-LDAP-Group == "mycompany_Technik_Sec"){ if (Huntgroup-Name == "fortigate") { update reply { Fortinet-Group-Name = "mycompany_Operations" Fortinet-Access-Profile = "super_admin" } } } else { reject } customers } eap } preacct { preprocess acct_unique suffix files } accounting { detail unix -sql exec attr_filter.accounting_response } session { } post-auth { update { &reply: += &session-state: } -sql exec remove_reply_message_if_eap Post-Auth-Type REJECT { -sql attr_filter.access_reject eap remove_reply_message_if_eap } Post-Auth-Type Challenge { } } pre-proxy { } post-proxy { eap } } Debug output of auth request tested via radtest -t pap user.name pw-removed localhost 0 testing123 (0) Received Access-Request Id 85 from 127.0.0.1:42556 to 127.0.0.1:1812 length 81 (0) User-Name = "user.name" (0) User-Password = "pw-removed" (0) NAS-IP-Address = 127.0.1.1 (0) NAS-Port = 0 (0) Message-Authenticator = 0xd04d42343938af1eb2a54bbed931ccd6 (0) # Executing section authorize from file /etc/freeradius/3.0/sites-enabled/default (0) authorize { (0) policy filter_username { (0) if (&User-Name) { (0) if (&User-Name) -> TRUE (0) if (&User-Name) { (0) if (&User-Name =~ / /) { (0) if (&User-Name =~ / /) -> FALSE (0) if (&User-Name =~ /@[^@]*@/ ) { (0) if (&User-Name =~ /@[^@]*@/ ) -> FALSE (0) if (&User-Name =~ /\.\./ ) { (0) if (&User-Name =~ /\.\./ ) -> FALSE (0) if ((&User-Name =~ /@/) && (&User-Name !~ /@(.+)\.(.+)$/)) { (0) if ((&User-Name =~ /@/) && (&User-Name !~ /@(.+)\.(.+)$/)) -> FALSE (0) if (&User-Name =~ /\.$/) { (0) if (&User-Name =~ /\.$/) -> FALSE (0) if (&User-Name =~ /@\./) { (0) if (&User-Name =~ /@\./) -> FALSE (0) } # if (&User-Name) = notfound (0) } # policy filter_username = notfound (0) [preprocess] = ok (0) eap: No EAP-Message, not doing EAP (0) [eap] = noop rlm_ldap (mycompany): Reserved connection (0) (0) mycompany: EXPAND (sAMAccountName=%{%{Stripped-User-Name}:-%{User-Name}}) (0) mycompany: --> (sAMAccountName=user.name) (0) mycompany: Performing search in "OU=mycompany,DC=mycompany,DC=mycompany,DC=de" with filter "(sAMAccountName=user.name)", scope "sub" (0) mycompany: Waiting for search result... (0) mycompany: User object found at DN "CN=User Name,OU=Windows 10 User,OU=User,OU=mycompany,DC=mycompany,DC=mycompany,DC=de" (0) mycompany: Processing user attributes (0) mycompany: WARNING: No "known good" password added. Ensure the admin user has permission to read the password attribute (0) mycompany: WARNING: PAP authentication will *NOT* work with Active Directory (if that is what you were trying to configure) rlm_ldap (mycompany): Released connection (0) Need 5 more connections to reach 10 spares rlm_ldap (mycompany): Opening additional connection (5), 1 of 27 pending slots used rlm_ldap (mycompany): Connecting to ldap://IP:389 rlm_ldap (mycompany): Waiting for bind result... rlm_ldap (mycompany): Bind successful (0) [mycompany] = ok (0) if ((ok || updated) && User-Password) { (0) if ((ok || updated) && User-Password) -> TRUE (0) if ((ok || updated) && User-Password) { (0) update { (0) control:Auth-Type := LDAP (0) } # update = noop (0) } # if ((ok || updated) && User-Password) = noop rlm_ldap (customers): Reserved connection (0) (0) customers: EXPAND (sAMAccountName=%{%{Stripped-User-Name}:-%{User-Name}}) (0) customers: --> (sAMAccountName=user.name) (0) customers: Performing search in "OU=mycompany,DC=mycompany,DC=mycompany,DC=de" with filter "(sAMAccountName=user.name)", scope "sub" (0) customers: Waiting for search result... (0) customers: User object found at DN "CN=User Name,OU=Windows 10 User,OU=User,OU=mycompany,DC=mycompany,DC=mycompany,DC=de" (0) customers: Processing user attributes (0) customers: WARNING: No "known good" password added. Ensure the admin user has permission to read the password attribute (0) customers: WARNING: PAP authentication will *NOT* work with Active Directory (if that is what you were trying to configure) rlm_ldap (customers): Released connection (0) Need 5 more connections to reach 10 spares rlm_ldap (customers): Opening additional connection (5), 1 of 27 pending slots used rlm_ldap (customers): Connecting to ldap://IP:389 rlm_ldap (customers): Waiting for bind result... rlm_ldap (customers): Bind successful (0) [customers] = ok (0) if ((ok || updated) && User-Password) { (0) if ((ok || updated) && User-Password) -> TRUE (0) if ((ok || updated) && User-Password) { (0) update { (0) control:Auth-Type := LDAP (0) } # update = noop (0) } # if ((ok || updated) && User-Password) = noop (0) } # authorize = ok (0) Found Auth-Type = LDAP (0) # Executing group from file /etc/freeradius/3.0/sites-enabled/default (0) Auth-Type LDAP { rlm_ldap (mycompany): Reserved connection (1) (0) mycompany: Login attempt by "user.name" (0) mycompany: Using user DN from request "CN=User Name,OU=Windows 10 User,OU=User,OU=mycompany,DC=mycompany,DC=mycompany,DC=de" (0) mycompany: Waiting for bind result... (0) mycompany: Bind successful (0) mycompany: Bind as user "CN=User Name,OU=Windows 10 User,OU=User,OU=mycompany,DC=mycompany,DC=mycompany,DC=de" was successful rlm_ldap (mycompany): Released connection (1) (0) [mycompany] = ok (0) if (mycompany-LDAP-Group == "mycompany_Technik_Sec"){ (0) if (mycompany-LDAP-Group == "mycompany_Technik_Sec") -> FALSE (0) else { (0) [reject] = reject (0) } # else = reject (0) } # Auth-Type LDAP = reject (0) Failed to authenticate the user (0) Using Post-Auth-Type Reject (0) # Executing group from file /etc/freeradius/3.0/sites-enabled/default (0) Post-Auth-Type REJECT { (0) attr_filter.access_reject: EXPAND %{User-Name} (0) attr_filter.access_reject: --> user.name (0) attr_filter.access_reject: Matched entry DEFAULT at line 11 (0) [attr_filter.access_reject] = updated (0) [eap] = noop (0) policy remove_reply_message_if_eap { (0) if (&reply:EAP-Message && &reply:Reply-Message) { (0) if (&reply:EAP-Message && &reply:Reply-Message) -> FALSE (0) else { (0) [noop] = noop (0) } # else = noop (0) } # policy remove_reply_message_if_eap = noop (0) } # Post-Auth-Type REJECT = updated (0) Delaying response for 1.000000 seconds Waking up in 0.3 seconds. Waking up in 0.6 seconds. (0) Sending delayed response (0) Sent Access-Reject Id 85 from 127.0.0.1:1812 to 127.0.0.1:42556 length 20 Waking up in 3.9 seconds.
On Feb 27, 2019, at 5:05 AM, Florian Sus | indevis GmbH <florian.sus@indevis.de> wrote:
I have a question regarding multiple ldap instances in freeradius and searching users in LDAP-Groups.
First of all, what do I try to achieve: Freeradius has to authenticate and authorize our admin users for our customers network devices. It has to perform user authentication with a simple ldap bind authentication and look up the group membership of the user. If the password of the user is correct and the user is member of a specific group, access shall be granted. I have already achieved a working configuration for the tasks above.
That's good.
I recently got a new task to allow also our customers access to their network devices with read-only access. The customer users are already configured in another ldap server. So I would like to configure two named ldap instances in rlm_ldap.
No, you should add a *different* named instance of the LDAP module. Don't break things that work. Don't rename the existing (and working) LDAP module. And how do you tell the difference between the two groups of users? This is a key question which you've left unresolved. What happens if *both* LDAP servers have a user named "bob"? Which one gets access?
If I do so, the authentication part for the admin user still works, but freeradius will not search the LDAP for user membership anymore and reject access. Please find below the config and debug output of the working configuration with only one ldap server And the modified config with two named ldap instances.
Don't post config files to the list. When you join the list, you get an email saying this. Your message is typical of a complex process: "I'm not sure what I"m doing, so I did a huge amount of work, and sent a huge description of what I've done". Most of that effort is unproductive. Go back to the *working* configuration. Then, add a *new* LDAP module: ldap ldap2 { ... } Just adding a new LDAP module won't break anything. Then, figure out how to tell the difference between the two sets of users. This is really the key question that will drive the solution. Without that answer, it's impossible to advise on a good solution. Are the names different? Do the users log into two different sets of devices? i.e. how does it work, and what do you want it to do? Alan DeKok.
Hi Alan, thanks a lot for your fast reply! Regarding the difference between admin users and customer read-only users I would like to do the following. Admin user will authenticate with "firstname.lastname" Customer RO users will authenticate with their e-mail address. So for admins the realm and delimiter is not given and if I have read correctly I could use realm NULL and authenticate the realm NULL users against first ldap server. All other users will have a realm which is unknown and should use the DEFAULT realm which I would like to have authenticated against the second ldap server. I am very new to freeradius so I decided to have a step-by-step approach to the final configuration. As my next step I would like to have configured two ldap servers (second ldap server can be dummy config for now) to see how I need to handle the configuration (eg. using <instancename>-LDAP-Group in unlang). I guess to have the final working config I need to use an additional virtual server (one for admin users for realm NULL and the other one for customers realm DEFAULT) and proxy.conf, but that will be in the later steps. To clarify: By "Then, add a *new* LDAP module" you mean to *append* the config for second ldap server to the file .../mods-available/ldap in the form ldap ldpa2 { ... } And I leave the existing config in the very same file for the first ldap server as it is. For checking group membership of users from the first ldap server I need to use if (LDAP-Group == "Groupname") { ... } And for checking group memebership of users from second ldap server I need to use If (ldap2-LDAP-Group == "other-Groupname") { ... } Do you need to have one ldap server instance unnamed and the other ones as named ldap servers? Thanks again and best regards, Florian -----Ursprüngliche Nachricht----- Von: Freeradius-Users [mailto:freeradius-users-bounces+florian.sus=indevis.de@lists.freeradius.org] Im Auftrag von Alan DeKok Gesendet: Mittwoch, 27. Februar 2019 13:49 An: FreeRadius users mailing list <freeradius-users@lists.freeradius.org> Betreff: Re: Multiple ldap instances - User Group Membership search not done On Feb 27, 2019, at 5:05 AM, Florian Sus | indevis GmbH <florian.sus@indevis.de> wrote:
I have a question regarding multiple ldap instances in freeradius and searching users in LDAP-Groups.
First of all, what do I try to achieve: Freeradius has to authenticate and authorize our admin users for our customers network devices. It has to perform user authentication with a simple ldap bind authentication and look up the group membership of the user. If the password of the user is correct and the user is member of a specific group, access shall be granted. I have already achieved a working configuration for the tasks above.
That's good.
I recently got a new task to allow also our customers access to their network devices with read-only access. The customer users are already configured in another ldap server. So I would like to configure two named ldap instances in rlm_ldap.
No, you should add a *different* named instance of the LDAP module. Don't break things that work. Don't rename the existing (and working) LDAP module. And how do you tell the difference between the two groups of users? This is a key question which you've left unresolved. What happens if *both* LDAP servers have a user named "bob"? Which one gets access?
If I do so, the authentication part for the admin user still works, but freeradius will not search the LDAP for user membership anymore and reject access. Please find below the config and debug output of the working configuration with only one ldap server And the modified config with two named ldap instances.
Don't post config files to the list. When you join the list, you get an email saying this. Your message is typical of a complex process: "I'm not sure what I"m doing, so I did a huge amount of work, and sent a huge description of what I've done". Most of that effort is unproductive. Go back to the *working* configuration. Then, add a *new* LDAP module: ldap ldap2 { ... } Just adding a new LDAP module won't break anything. Then, figure out how to tell the difference between the two sets of users. This is really the key question that will drive the solution. Without that answer, it's impossible to advise on a good solution. Are the names different? Do the users log into two different sets of devices? i.e. how does it work, and what do you want it to do? Alan DeKok. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
On Feb 27, 2019, at 9:35 AM, Florian Sus | indevis GmbH <florian.sus@indevis.de> wrote:
Regarding the difference between admin users and customer read-only users I would like to do the following.
That makes it a lot easier.
Admin user will authenticate with "firstname.lastname" Customer RO users will authenticate with their e-mail address.
So for admins the realm and delimiter is not given and if I have read correctly I could use realm NULL and authenticate the realm NULL users against first ldap server. All other users will have a realm which is unknown and should use the DEFAULT realm which I would like to have authenticated against the second ldap server.
I would suggest using realm names where possible. Use the domain name for users who authenticate with email addresses. Use the default realm for all other users. authorize { ... suffix ... if (Realm == "realm-A") { ldap_realmA } else { ldap } ... } That will authenticate each set of users from the correct LDAP server. If you want to add group checks, just do that inside the relevant if / else blocks above.
I am very new to freeradius so I decided to have a step-by-step approach to the final configuration.
That's good.
As my next step I would like to have configured two ldap servers (second ldap server can be dummy config for now) to see how I need to handle the configuration (eg. using <instancename>-LDAP-Group in unlang). I guess to have the final working config I need to use an additional virtual server (one for admin users for realm NULL and the other one for customers realm DEFAULT) and proxy.conf, but that will be in the later steps.
No, you don't need to do that. You can just use one virtual server.
To clarify: By "Then, add a *new* LDAP module" you mean to *append* the config for second ldap server to the file .../mods-available/ldap in the form
ldap ldpa2 { ... }
You can append it or put it into a different file. It's just text.
And I leave the existing config in the very same file for the first ldap server as it is. For checking group membership of users from the first ldap server I need to use
if (LDAP-Group == "Groupname") { ... }
And for checking group memebership of users from second ldap server I need to use
If (ldap2-LDAP-Group == "other-Groupname") { ... }
Yes.
Do you need to have one ldap server instance unnamed and the other ones as named ldap servers?
You don't *need* to do it that way. But it's the simplest. Alan DeKok/
Hi Alan, thanks again for your time and your suggestions. I could just finish the first part successfully for authentication our admin users. Now I will have a closer look into how to differentiate between admin and customer users. Your suggestions were already very helpful to know in which direction I need to go :) For everyone having the same problem regarding the LDAP group membership search not working with <instance-name>-LDAP Group == ... I have found the solution to make that work: http://lists.freeradius.org/pipermail/freeradius-users/2016-August/084503.ht... You need to prepend a "&": ... if (&<instance-name>-LDAP-Group == "GroupName") { ... } Best regards, Florian
participants (2)
-
Alan DeKok -
Florian Sus | indevis GmbH