eap-ttls/mschapv2 versus eap-peap/mschapv2 behaviour

Olivier Beytrison olivier at heliosnet.org
Thu Jul 18 11:56:20 CEST 2013

On 18.07.2013 10:53, Phil Mayers wrote:
> On 07/18/2013 07:25 AM, Olivier Beytrison wrote:
>> Hello,
>> We're in the middle of migrating all of our radius server to FR3.
>> This is the opportunity to discuss a the difference of behaviour between
>> EAP-TTLS/MSCHAPv2 and EPA-PEAP/MSCHAPv2 which is bothersome.
>> With EAP-TTLS/MSCHAPv2 we have the following flow
>> With EAP-PEAP/MSCHAPv2 the flow is somewhat different
> FWIW I don't think either of those are complete or accurate.
> For starters, TTLS/MSCHAPv2 and TTLS/EAP-MSCHAPv2 are different, and
> Comparing TTLS/MSCHAP and PEAP/EAP-MSCHAPv2 is comparing two different
> things, and of course they may behave differently.

I agree after writing the mail I went deeper in the analysis and the
flows are quite different. But the difference of behaviour is still there.

>> This mean that with EAP-PEAP/MSCHAPv2, if the ldap/sql/xxx module in
>> authorize{} add attributes to the reply, they will be sent during the
>> last challenge/response in authenticate{}, and will not be present in
>> post-auth or the final access-accept.
> You're not being very precise here. authorize in the inner or outer tunnel?

I'm only talking about the inner tunnel here (sorry for not specifying)

>> On our side, we are doing the policying in the inner-tunnel post-auth
>> section, based on values directly mapped from ldap attributes to our
>> private dictionary through the ldap module called in authz{}
>> With EAP-TTLS we don't need to do anything special to make this work,
>> but for PEAP actually we need to use the rlm_cache to cache and restore
>> the attributes in post-auth.
> Why don't you just set them in post-auth, and skip setting them in
> authorize completely?
> You can do this, remember:
> post-auth {
>   ldap.authorize
>   sql.authorize
>   ...
> }

I know, but I can't and don't want. ldap retrieve the clear-text
password from eDirectory, so this have to be done before authenticate
{}. And I take this opportunity to do a one ldap call for all needs.

>> It would be really nice if eap would cache automatically all attributes
>> present in the reply list if it has to do another round of
>> challenge/response and restore them once the final access-accept (or
>> reject) is reached.
> I'm not sure about that.
> You definitely have to take care with reply attributes, but if you
> always set them in post-auth, you should always be safe.

Well actually the attributes from ldap are all added to the reply list
as we want to see them on wire and they need to be copied to the outer
tunnel. When going to production most of them will move the the control
list, but this issue will remain

> Setting them in authorize is only safe if you set them on *every pass*
> through authorize. You're not doing this, because you have:
> eap {
>   ok = return
> }
> ldap
> sql
> In 3.0, the "ok = return" will match on EAP-identity packets for the
> inner tunnel but *also* EAP-MSCHAPv2 success/failure packets. So, the
> final pass through the tunnel will be skipped.
> This should be logged in the debug with a quite specific/verbose
> message, for exactly this reason:
> https://github.com/FreeRADIUS/freeradius-server/blob/master/src/modules/rlm_eap/eap.c#L852
> Maybe this is the issue you're facing?

I'm well aware of the short-circuit code in eap, and this is a nice
feature. It's meant to save unneeded module calls, but in this situation
it would indeed require a second ldap.authorize call.

>> Now this is a behaviour I always encountered in our configs (based on
>> the default shipped config). Still it's possible that it is due to
>> what've done. For this purpose you'll find the inner-tunnel config below
>> [1].
>>         # that's where we need the attributes added
>>         # by the ldap module in authz{}
>>                  wireless-policy
>>          }
> What does "wireless-policy" do, and where does it get its data from?

It sets the Airspace-Interface-Name attribute based on an attribute
populated from the ldap module. See [1]

The main difference between the two types is that with TTLS, once the
tunnel is established, the request is decoded. So we have in the
inner-tunnel :

authorize {
  eap -> noop
  ldap -> ok + attributes added
authenticate {
  mschap -> ok
post-auth {
  wireless-policy -> ok (it finds the attributes)
Request sent to the outer virtual server

With PEAP it's more like that once the initial tls tunnel is established :

authorize {
  eap -> updated
  ldap -> ok + attributes added
authenticate {
  eap -> mschap [ok] -> handled
Challenge sent to the NAS
Access request comes back
authorize {
  eap -> mschapv2 ok -> short circuit
authenticate {
  eap ->ok
post-auth {
  wireless-policy -> doesn't find the attributes
Request sent to the outer tunnel

Now I like the short-circuit concept as it save quite some uneeded
processing. But I'd like to have a mechanism that remove and stores any
attributes present in the reply (within the inner-tunnel) until the
mschapv2 succeeded.

If you want I have the debug and configuration ready to be posted on a
gist. But I think this is a situation that everyone has already faced.
So I'm also interested in how people actually circumvented this behaviour.

> -
> List info/subscribe/unsubscribe? See
> http://www.freeradius.org/list/devel.html


 Olivier Beytrison
 Network & Security Engineer, HES-SO Fribourg
 Mail: olivier at heliosnet.org

More information about the Freeradius-Devel mailing list