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