FreeRADIUS with PEAP(MSCHAPv2), MySQL and LDAP?

Phil Mayers p.mayers at imperial.ac.uk
Wed Jan 18 13:34:56 CET 2006


Palmer J.D.F. wrote:
> Hi Phil,
> 
> Many thanks for the reply. I'm sorry the detail was lacking I'll try
> to explain myself a little better now.
> 
> Firstly, what we do already and why I want to use MySQL...
> 
> At the moment we run FR as a RADIUS proxy that proxies requests to a
> number of RADIUS servers based on the username. Presently we use the
> 'users' file to do this, the users file is built from our mail
> tables; amongst other things the users file maps a username to a home
> RADIUS server and a VLAN; basically I want to use MySQL to replace
> the users file; I don't want to actually authenticate against details
> in the MySQL database.
> 
> The reason we use the mail tables is that it contains every user and
> the respective server that their mail goes to, we use the SMTP server
> name to determine which domain a user's RADIUS requests should be
> sent to. We use the Proxy_To_Realm directive in the users file to
> forward a user's request to the correct server.
> 
> The reason I now want to use a database is because it will give us
> the ability to add more user data fields and a database would be more
>  manageable, as the current users file has 38554 entries and is
> growing.
> 

Ok, that bit should be pretty straightforward. Though of course if you
get rid of the IAS servers you don't then need to actually proxy, but do 
then need to choose the LDAP.

> Why I want to use LDAP...
> 
> All of our user data is held in various MS ADS or Novell NDS
> directories,

Ah ha. I should have looked at the From: on your email and recognised a
fellow UK academic and inferred a high probability of devolved and/or
heterogeneous IT infrastructure ;o)

> currently we run an IAS machine on each of our AD domains to handle
> the proxied requests forwarded by the FR server; my thinking was that
> it seems a little pointless to have these IAS boxes if I could use FR
> to set up the PEAP tunnels then verify the user's credentials against
> the appropriate domain's LDAP server.

In principle PEAP can use any inner mechanism. In fact, the stock
Windows XP supplicant can only use MS-CHAPv2, and...

> 
> I ideally want to use PEAP(MSCHAPv2) though, mainly from a support,
> but also from an encryption strength point of view; however it
> appears that unless something clever can be done to verify MSCHAPv2
> against MS or Novell LDAP it looks like I may be stuck with the nasty
> IAS boxes.

You definitely can't do MS-CHAP via LDAP to AD. ADs LDAP server does not
and cannot be made to give you the NT hash or plaintext password from
which you derive it, and that is requires for MS-CHAP.

For AD realms, I think you could use the the "mschap" module and the
ntlm_auth helper, provided the various domains have inter-domain trusts
and the samba+winbind installation on the freeradius server is joined to
one of the domains.

I'm not sure about Novell LDAP - it may be possible with the right
permissions to persuade NDS to give you either the NT hash or even the
plaintext password over LDAP, in which case FreeRadius can do the
MS-CHAP itself.

Assuming that the samba + domain trust things works and that NDS can be
made to expose the NT hash or plaintext password, you'd need something like:

modules {
   # This will handle the non-NDS realms via Samba/Winbind
   # you'll need working samba and domain trusts first
   mschap {
     ntlm_auth = "/usr/bin/ntlm_auth \
--request-nt-key \
--username=%{Stripped-User-Name} \
--domain=%{Realm} \
--challenge=%{mschap:Challenge:-00} \
--nt-response=%{mschap:NT-Response:-00}"
   }

   # These LDAP modules will extract either ntPassword or plaintext
   # userPassword from the various NDS realms and add it to the
   # radius configure items so that FreeRadius can to the MS-CHAP
   # internally
   ldap Ldap1 {
     # various stuff here extracts ntPassword
   }
   ldap Ldap1 {
     # various other stuff here
   }
   mysql {
     # various stuff here
   }
}

authorize {
   preprocess
   mysql
   mschap
   eap

   Autz-Type Ldap1 {
     Ldap1
   }
   Autz-Type Ldap2 {
     Ldap2
   }
}

authenticate {
   Auth-Type MS-CHAP {
     mschap
   }
   eap
}


...and in the mysql check tables I think:

  username |      att              | op |    val
----------+-----------------------+----+-----------
  foo      | Client-IP-Address     | == | 127.0.0.1
  foo      | Autz-Type             | := | Ldap1
  foo      | MS-CHAP-Use-NTLM-Auth | := | 0
  bar      | Client-IP-Address     | == | 127.0.0.1
  bar      | Autz-Type             | := | Ldap2
  bar      | MS-CHAP-Use-NTLM-Auth | := | 0
  baz      | Client-IP-Address     | == | 127.0.0.1
  baz      | Realm                 | := | REALM3

In this case, foo and bar are NDS users on different realms. The 
Autz-Type will be set for them, and the appropriate conditional 
sub-section of authorize run *AFTER* all the unconditional ones, so for 
e.g. user "foo" the request will go:

authorize:

  1. preprocess - Client-IP-Address and NAS-IP-Addresss
  2. mysql - nothing - Client-IP-Address is not 127.0.0.1
  3. mschap - nothing - it's an EAP
  4. eap - Auth-Type set to EAP

authenticate:

  1. mschap - nothing does not match (remember it's EAP)
  1. eap run - eap negotiation happens, MS-CHAPv2 chosen as inner 
mechanism, and when FreeRadius has the MS-CHAPv2 request, it generates a 
2nd fake radius request

2nd fake (inner) request:

authorize:

  1. preprocess - Client-IP-Address set to 127.0.0.1 for fakes
  2. mysql - Autz-Type set to Ldap1
  3. mschap - sets Auth-Type to MS-CHAP
  4. eap - nothing
  5. authorize re-run, Ldap1 executed, either ntPassword or plaintext 
userPassword extracted from LDAP and added to configure items

authenticate:

  1. mschap - if User-Password is present, it will derive the 
NT-Password from it. If NT-Password is present, it will leave it 
untouched. Since MS-CHAP-Use-NTLM-Auth is set to "no" freeradius will 
execute the MS-CHAP algorithm internally.



"baz" however is an NT user, and will be handled differently. The first 
request happens are before, and generates a 2nd inner request:

2nd fake (inner) request:

authorize:

  1. preprocess - Client-IP-Address set to 127.0.0.1 for fakes
  2. mysql - Realm set to REALM3
  3. mschap - sets Auth-Type to MS-CHAP
  4. eap - nothing

authenticate:

  1. mschap - ntlm_auth it set, and used. The MS-CHAP request is passed 
to Samba+Winbind and provided domain trusts are working correctly, the 
reply will come back and all will be well.


As you can see, it's not exactly straightforward, but in principle it 
can be made to work provided the AD/windows domain trusts behave as 
expected and NDS can extract either the plaintext or NT password hash.

Let us know how you get on!

> I hope that makes some sense.
> 
> Many thanks, Jezz Palmer.
> 
> 
> 
>> -----Original Message----- From: freeradius-users- 
>> bounces+j.d.f.palmer=swansea.ac.uk at lists.freeradius.org 
>> [mailto:freeradius-users- 
>> bounces+j.d.f.palmer=swansea.ac.uk at lists.freeradius.org] On Behalf
>> Of Phil Mayers Sent: 17 January 2006 21:03 To: FreeRadius users
>> mailing list Subject: Re: FreeRADIUS with PEAP(MSCHAPv2), MySQL and
>> LDAP?
>> 
>> Palmer J.D.F. wrote:
>>> Hi,
>>> 
>>> 
>>> 
>>> I am currently trying to create a new auth system for our WPA
>>> 802.1x WiFi network.
>>> 
>>> Thus far I have the server authenticating using PEAP(MSCHAPv2)
>>> against a users file containing a simple test user/pass pair.
>>> 
>>> What I would now like to do is use MySQL to contain user data
>>> such as the VLAN to be assigned to that user and which LDAP
>>> server their account
>> Assuming you know how to make the VLAN assignment work at all, then
>> this is trivial.
>> 
>> Assigning a completely dynamic LDAP server might be a little more
>> tricky.
>> 
>> If you know what set of LDAP server(s) you want to use in advance,
>> then you could do this:
>> 
>> modules { ldap ldap1 { # config here } ldap ldap2 { # config here }
>>  }
>> 
>> authorize { preprocess mysql mschap eap
>> 
>> Autz-Type Ldap1 { ldap1 } Autz-Type Ldap2 { ldap2 } }
>> 
>> The "mysql" module/tables will need to set Autz-Type on the
>> requests, at which point the authorize stanza will be run *again*
>> executing the conditional sections.
>> 
>> ...however making this work correctly in the presence of
>> eap/ms-chapv2 will not be straightforward, and in any event you
>> have the other issue...
>> 
>>> exists on, then use LDAP to verify the credentials.
>> The only "verification" LDAP can do of credentials is to proxy PAP 
>> requests to LDAP simple binds. You cannot check MS-CHAP "against"
>> an LDAP server.
>> 
>> However using LDAP as a database, as it was intendended, then *if*
>> the LDAP server contains either plaintext password or the NT/LM
>> hashes, the radius server can read them, and the ldap module is
>> configured to get them from LDAP, then FreeRadius can perform the
>> MS-CHAP inside itself.
>> 
>>> The idea being that a PEAP request comes in, tunnel gets built
>>> etc, the user gets looked up in the MySQL database, the
>>> credentials are then authenticated against the correct LDAP (or
>>> RADIUS) server, then on success an access-accept along with the
>>> user's VLAN is passed back to the NAS.
>> This seems extremely hard work. Why would you use both MySQL and
>> LDAP?
>> 
>>> 
>>> 
>>> The question is, is it possible for PEAP(MSCHAPv2) and LDAP with
>>> MySQL to interact in this way?
>> Your question is not precise enough for me to be sure exactly what
>> you want. - List info/subscribe/unsubscribe? See 
>> http://www.freeradius.org/list/users.html
> - List info/subscribe/unsubscribe? See
> http://www.freeradius.org/list/users.html




More information about the Freeradius-Users mailing list