dynamic VLAN assignment w/ mschapv2 against AD and LDAP

Alexander Clouter alex at digriz.org.uk
Fri Jan 21 09:49:55 CET 2011


schilling <schilling2006 at gmail.com> wrote:
>
> Where should I put the perl script? I already have a perl module for
> another virtual server to use radscript.
> 
> I also tried unlang in post-auth, like
> if ( %{User-Name} =~ /\@/ && fooEmployeeStatus =~ /active/i ) {
>                update outer.reply {
>                                Service-Type = "Framed-User"
>                                Tunnel-Type = "VLAN"
>                                Tunnel-Medium-Type = "IEEE-802"
>                                Tunnel-Private-Group-Id = "facstaff"
>                }
>        }
>
I cannot recommend more *not* to do your authorisation in the inner 
tunnel, and instead to pass it back on out.  There are a number of 
reasons, clarity including, but especially you then can make use of the 
reject path...

Incase it helps, this is what we (a small-medium university in the 
UK) do.  In our eap block we set (we use TTLS, however it should be the 
same for PEAP):
----
eap {
	...

	ttls {
		...
		copy_request_to_tunnel = no
                use_tunneled_reply = yes
                virtual_server = "auth"
	}

	...
}

Then we have a 'auth' virtual server:
----
server auth {
        authorize {
                if ((outer.request:EAP-Message)) {
                        update outer.request {
                                User-Name := "%{request:User-Name}"
                        }
                        update reply {
                                User-Name := "%{request:User-Name}"
                        }
                }

                validate_username

                suffix

                if ((outer.request:EAP-Message) && Realm != "%{config:local.MY.realm}") {
                        update outer.reply {
                                Reply-Message := "Realm is '%{Realm}' on Inside"
                        }
                        reject
                }

                # if the password is passed to us use it, otherwise yank it from LDAP
                if ((outer.request:Cleartext-Password)) {
                        update control {
                                Cleartext-Password := "%{outer.request:Cleartext-Password}"
                        }
                }
                else {
                        ldap-login

                        # some accounts are glitched and do not have a UP :(
                        if (ok && !(control:Cleartext-Password)) {
                                update outer.reply {
                                        Reply-Message := "No eDirectory UP"
                                }
                                reject
                        }
                }

                pap
                chap
                mschap

                update reply {
                        Auth-Type := "%{control:Auth-Type}"
                }
        }

        authenticate {
                Auth-Type PAP {
                        pap
                }
                Auth-Type CHAP {
                        chap
                }
                Auth-Type MSCHAP {
                        mschap
                }
        }
}
----

We are 'blessed' with Novhell, so 'ldap-login' populated 
Cleartext-Password from eDirectory if present, your approach would be 
different (the interesting bit is if you set 
'request:Cleartext-Password' in your outer layer before calling 'eap', 
which is a handy hook for a NAGIOS RADIUS hook (letting you test 
authentication with eapol_test[1] and remove the AD component from the 
equation.

Once the 'auth' virtual server finishes, you will find in the outer 
layer for *successful* authentications, 'reply:User-Name' is the inner 
username whilst for *failure* authentications you want to use 
'request:User-Name'.

> I did map something to fooEmployeeStatus in ldap.attrmaps
> Bare %{...} is invalid in condition at: %{User-Name} =~ /\@/ &&
> fooEmployeeStatus =~ /active/i )
> /home/sding/opt/etc/raddb/sites-enabled/inner-tunnel[276]: Errors
> parsing post-auth section.
> 
> How can I reference User-Name in post-auth section of inner-tunnel?
> 
In your outer post-auth section then I would recommend the following 
unlang (prime the defaults, and use the attributes to fixup what you 
want the final result to be):
----
post-auth {
	...

	# defaults
	update reply {
		Tunnel-Type := VLAN
		Tunnel-Medium-Type := IEEE-802
		Tunnel-Private-Group-Id := "unauthorised"

		Termination-Action := RADIUS-Request

		# Cisco only support a max of 65535
		Session-Timeout := 64800

		Acct-Interim-Interval := 3600
	}

	if ( User-Name =~ /@/ && (fooEmployeeStatus) ) {
		update reply {
			Tunnel-Private-Group-Id := "facstaff"
		}
	}

	...
}
----

If you want to lower the load (and authentication latency) on your AD 
servers then you might want to look at the following too:

http://www.mail-archive.com/freeradius-users@lists.freeradius.org/msg65781.html

Cheers

[1] http://deployingradius.com/scripts/eapol_test/

-- 
Alexander Clouter
.sigmonster says: Never ask the barber if you need a haircut.




More information about the Freeradius-Users mailing list