RADIUS with LDAP: changing LDAP filter based on RADIUS request
Ivan Kalik
tnt at kalik.net
Mon Jun 9 23:50:14 CEST 2008
man unlang - attribute lists.
***
The "<list>:" prefix is optional, and if omitted, is assumed to refer
to the "request" list.
***
Ivan Kalik
Kalik Informatika ISP
Dana 9/6/2008, "Sylvain Robitaille" <syl at alcor.concordia.ca> piše:
>
>Background:
>
> We're using FreeRADIUS-2.0.3 with an OpenLDAP backend, on two separate
>systems for authentication and authorization of users to our wireless
>network and a lesser-used VPN service. I would like to be able to modify
>the LDAP query filter based on (for example) which NAS device sent the
>RADIUS request so that (again, for example) a different filter might be
>used to search for wireless users than for VPN users.
>
>In an effort to be able to setup a "dynamic" LDAP query filter, I have
>tried adding a string-type attribute to our local dictionary file,
>to hold the filter that would be updated on-the-fly:
>
> ATTRIBUTE CU-LDAP-Filter 3000 string
>
>The radiusd.conf file then has ldap module instances (one per LDAP
>server) with the following reference to this attribute:
>
> ldap ldap_host1 {
> server = "ldap_host1"
> identity = "cn=...,ou=...,dc=concordia,dc=ca"
> password = "**SANITIZED**"
> basedn = "ou=people,dc=concordia,dc=ca"
> filter = "%{CU-LDAP-Filter}"
> base_filter = "(objectclass=ConcordiaPerson)"
> ...
> }
>
> ldap ldap_host2 {
> server = "ldap_host2"
> identity = "cn=...,ou=...,dc=concordia,dc=ca"
> password = "**SANITIZED**"
> basedn = "ou=people,dc=concordia,dc=ca"
> filter = "%{CU-LDAP-Filter}"
> base_filter = "(objectclass=ConcordiaPerson)"
> ...
> }
>
>I'm presently testing with the radeapclient client (on localhost), so am
>testing with the following configured into sites-enabled/default:
>
> authorize {
> ...
> switch "%{NAS-IP-Address}" {
> case 192.168.198.20 {
> # test
> update control {
> CU-LDAP-Filter = "(&(cn=%{%{Stripped-User-Name}:-%{User-Name}})(***LDAP QUERY1 TRIMMED FOR BREVITY***))"
> }
> }
> case 127.0.0.1 {
> # test
> update control {
> CU-LDAP-Filter = "(&(cn=%{%{Stripped-User-Name}:-%{User-Name}})(***LDAP QUERY2 TRIMMED FOR BREVITY***))"
> }
> }
> ...
> case {
> # default
> noop
> }
> }
>
> if ("%{CU-LDAP-Filter}" != "") {
> redundant-load-balance {
> ldap_host1
> ldap_host2
> }
> }
> ...
> }
>
>The LDAP query filters, though not included above (these things are quite
>long and site-specific anyway) are known to work, as they're copied from
>our currently in-production configuration that is selecting the ldap
>module instance based on the NAS-IP-Address (ie. if NAS-IP-Address is
>the VPN server we call the ldap_vpn module which is configured with an
>appropriate filter, else we call the ldap_wireless module which is also
>appropriately configured). The present setup works, but based on what
>I'm reading it would give is a much more flexible and fault-tolerant
>(and dare-I-say, more manageable?) setup if I could get the LDAP module
>instances configured into a redundant-load-balance stanza, with a
>dynamically determined LDAP query filter (so that if one LDAP server is
>unavailable, one or more others could be tried instead, instead of
>having a hard-coded query to specific LDAP servers for each service).
>
>I hope I'm making sense so far ...
>
>The following command is issued to test:
>
> radeapclient -x localhost:1815 auth testing123 << END_OF_EAP
> User-Name = "j_doe"
> Cleartext-Password = "**SANITIZED**"
> NAS-IP-Address = 192.168.198.20
> NAS-Port-Type = "Wireless-802.11"
> EAP-Code = Response
> EAP-Id = 210
> EAP-Type-Identity = "j_doe"
> Message-Authenticator = 0x00
> NAS-Port = 0
> END_OF_EAP
>
>Radiusd, running in debug mode shows the following (config-file parsing
>output skipped; it is not showing any errors at all, so although the
>configuration I show above may not be producing the intended result, it
>at least seems syntactically correct):
>
> Listening on authentication address * port 1815
> Listening on accounting address * port 1816
> Listening on proxy address * port 1817
> Ready to process requests.
> User-Name = "j_doe"
> NAS-IP-Address = 192.168.198.20
> NAS-Port-Type = Wireless-802.11
> Message-Authenticator = 0x8499bae7c162d5f0ef2e587fdb9086a0
> NAS-Port = 0
> EAP-Message = 0x02d200080173796c
> +- entering group authorize
> ++[preprocess] returns ok
> ++[chap] returns noop
> ++[mschap] returns noop
> rlm_realm: No '@' in User-Name = "j_doe", looking up realm NULL
> rlm_realm: No such realm "NULL"
> ++[suffix] returns noop
> rlm_eap: EAP packet type response id 210 length 8
> rlm_eap: No EAP Start, assuming it's an on-going EAP conversation
> ++[eap] returns updated
> ++[unix] returns notfound
> ++[files] returns noop
> expand: %{NAS-IP-Address} -> 192.168.198.20
> ++- entering switch %{NAS-IP-Address}
> +++- entering case 192.168.198.20
> expand: %{Stripped-User-Name} ->
> expand: %{User-Name} -> j_doe
> expand: (&(cn=%{%{Stripped-User-Name}:-%{User-Name}})**LDAP QUERY1 FILTER TRIMMED**) -> (&(cn=j_doe)**LDAP QUERY1 FILTER TRIMMED**)
> ++++[control] returns noop
> +++- case 192.168.198.20 returns noop
> ++- switch %{NAS-IP-Address} returns noop
> ++? if ("%{CU-LDAP-Filter}" != "")
> expand: %{CU-LDAP-Filter} ->
> ? Evaluating ("%{CU-LDAP-Filter}" != "") -> FALSE
> ++? if ("%{CU-LDAP-Filter}" != "") -> FALSE
> ++[expiration] returns noop
> ++[logintime] returns noop
> rlm_pap: WARNING! No "known good" password found for the user. Authentication may fail because of this.
> ++[pap] returns noop
> rad_check_password: Found Auth-Type EAP
> auth: type "EAP"
> +- entering group authenticate
> rlm_eap: EAP Identity
> rlm_eap: processing type tls
> rlm_eap_tls: Initiate
> rlm_eap_tls: Start returned 1
> rlm_eap: RT Modif EAP-Type = 21 EAP-LENGTH = 1
> ++[eap] returns handled
> EAP-Message = 0x01d300061520
> Message-Authenticator = 0x00000000000000000000000000000000
> State = 0x1c870d031c541859b55d17dd8af5914a
> Finished request 0.
> Going to the next request
> Waking up in 4.9 seconds.
> Cleaning up request 0 ID 232 with timestamp +4
> Ready to process requests.
>
>
>Note that of the above, I believe the following is relevant to my
>question:
>
> expand: %{NAS-IP-Address} -> 192.168.198.20
> ++- entering switch %{NAS-IP-Address}
> +++- entering case 192.168.198.20
> expand: %{Stripped-User-Name} ->
> expand: %{User-Name} -> j_doe
> expand: (&(cn=%{%{Stripped-User-Name}:-%{User-Name}})**LDAP QUERY1 FILTER TRIMMED**) -> (&(cn=j_doe)**LDAP QUERY1 FILTER TRIMMED**)
> ++++[control] returns noop
> +++- case 192.168.198.20 returns noop
> ++- switch %{NAS-IP-Address} returns noop
> ++? if ("%{CU-LDAP-Filter}" != "")
> expand: %{CU-LDAP-Filter} ->
> ? Evaluating ("%{CU-LDAP-Filter}" != "") -> FALSE
> ++? if ("%{CU-LDAP-Filter}" != "") -> FALSE
>
>This corresponds to the following from the "authorize" section in my
>sites-enabled/default file:
>
> switch "%{NAS-IP-Address}" {
> case 192.168.198.20 {
> # test
> update control {
> CU-LDAP-Filter = "(&(cn=%{%{Stripped-User-Name}:-%{User-Name}})(***LDAP QUERY TRIMMED FOR BREVITY***))"
> }
> }
> }
>
>We see that the line where I intend to assign a value to CU-LDAP-Filter
>is indeed encountered and the variables referred to in that line are
>expanded correctly, but it seems as though the assignment to
>CU-LDAP-Filter isn't done: if ("%{CU-LDAP-Filter}" != "") is evaluated
>as "FALSE".
>
>I suspect that my "update" statement is likely incorrect, since the only
>mention of it in the debug output is:
>
> ++++[control] returns noop
>
>Can anyone help me with this? I've read as much of the relevant
>documentation as I'm aware exists, especially "man unlang" without which
>I certainly wouldn't have gotten even this far, but I'd be very grateful
>if someone could point me to further documentation that would help with
>what I'm trying to do ...
>
>Thanks ...
>
>--
>----------------------------------------------------------------------
>Sylvain Robitaille syl at alcor.concordia.ca
>
>Systems and Network analyst Concordia University
>Instructional & Information Technology Montreal, Quebec, Canada
>----------------------------------------------------------------------
>-
>List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
>
>
More information about the Freeradius-Users
mailing list