PEAP and MAC-auth checking with SQL

Alan DeKok aland at
Mon Mar 31 22:16:12 CEST 2014

Christopher Kuhn wrote:
> I'm currently running a FreeRADIUS server which is working just fine
> authenticating users with PEAP-MSCHAP. I now need to add some
> functionality which basically amounts to mac authentication. However,
> due to the way our switch stacks handle it, all requests still come in
> as some kind of EAP request which includes a username.

  That's pretty normal.

> Requests will be one of two things. Either:
> 1) Our current, real authentication scheme where we want to use
> PEAP-MSCHAP for 'DOMAIN\user' (or 'user at domain'). These users need to go
> through the whole AAA process.
> OR
> 2) A request where User-Name = Calling-Station-Id; the switch sends an
> EAP request with the supplicant's MAC as the username. As long as the
> MAC is on my whitelist, it can be approved.

  That seems straightforward.

> In either case, I need to check the Calling-Station-Id against a
> whitelist. If it isn't on the list, it is rejected. If it is there, it
> either continues through the PEAP-MSCHAP authentication (request type
> 1), or is approved more-or-less immediately (request type 2). Although I
> realize the authed_macs function can already do this, I have been told
> to use SQL for both scalability and to use features like user-group
> mapping (so we have more information in the accounting database).

  Yes.  The general rule is that complex if / else conditions go into
the configuration files, as "unlang" policies.  Lookups of one of 1000's
of things in a fixed table should be done via a database.

> Here are my problems/questions:
> 1) Can I use the SQL module to check an attribute (e.g.,
> Calling-Station-Id) irrespective of User-Name during Authorization and
> still have the User-Name logged during Accounting? If so, can you point
> me at any particular configuration sections, modules, or attributes I
> should be working with? 

  Yes.  Just use a SELECT statement.  You'll have to create a new table
of allowed MAC addresses.  Then, just SELECT the MAC address from the table.

authorize {

	if (Calling-Station-Id != "%{sql: SELECT ... %{Calling-Station-Id}") {

  Put the SELECT statement into the string "%{sql:...}"  And put
%{Calling-Station-Id} into the SELECT statement where the MAC address is
supposed to be.

  The above policy will reject all requests which don't have
Calling-Station in the new table you added.

> 2) Is it appropriate to create different realms for the two different
> cases?

  That's probably overkill.  I don't see why you'd do that.

  Alan DeKok.

More information about the Freeradius-Users mailing list