rewrite User-Name in received Access-Request - tough question :)

Alan DeKok aland at
Sun Oct 28 10:28:36 CET 2012

Bojan Pogacar wrote:
> This is my first post on this mailing list. I hope someone can give me
> an advice over my problem that I am solving over a month. I even bought
> a book about freeradius and after reading it twice there is not an
> answer to my problem.

  Yes.  Most complicated problems involve putting pieces together.
Finding a pre-packaged solution is rare.

> Then they wanted me to change login procedure. All users would get free
> access for 30 minutes per day and they don't have to login through
> captive portal. After 30 minutes, captive portal would open and user
> would have to login with some coupone to connect to the internet.

  Write this down as workflow for what you want to happen.  When you do
that, the solution is usually simple.

  But I do see issues here.  You said some users are authenticated via
MAC address, and others are not.  If you want to let those others in
without authenticating to the captive portal, how do you know who they
are?  How do you track them?

  That is a big problem.  You WON'T get a user name, because they're not
using the captive portal.  All you'll get is a MAC address.

  So you really have two classes of users.  One has a "known MAC", and
gets full-day access.  So your first priority should be checking for
those users, and letting them in.  You should also check for non-MAC
usernames, and authenticate them as you do today.

  So the only remaining problem is "unknown MAC" users who are trying to
log in.  Write down what you want in simple English:

  When an "unknown MAC" user logs in, check their total time usage
today.  If it's less than 30min, give them up to 30min access.  If it's
more than 30min, deny them access (or somehow direct them to the captive

> I've solved this by writing these two lines in file "hints"
> DEFAULT User-Name =~
> "^[0-9A-F]{2}-[0-9A-F]{2}-[0-9A-F]{2}-[0-9AF]{2}-[0-9A-F]{2}-[0-9A-F]{2}$"
>        User-Name := "freeinternetfor30minutes"

  Well, no.  You're talking about an *implementation*.  That's not a
solution.  The requirements above say nothing about re-writing user names.

> It worked very well except all users previously authenticated by MAC
> address didn't get theis own profiles, but they got logged in as
> "freeinternetfor30minutes" with bandwidth limitations.

  Exactly.  Because you didn't divide the problem into pieces.

  Take one piece you know how to solve: "known MAC" users.  If you see a
login with MAC, check the MAC against a list of "known MAC" users.  If
it's found, let them in.  Otherwise, do something else.

  Doing a series of simple checks is MUCH easier than trying to come up
with one magic rule set which solves all problems.  This is the base of
the "divide and conquer" strategy.

> OK, that was logical, I deleted those two lines and wrote some unlung
> logic to the "sites-available/default"
>         if(notfound){ #if user not in database
>                 update reply {
>                     Reply-Message := "Wrong username or password"
>                 }
>         # if username was MAC address, try to login as
> "freeinternetfor30minutes"

  Again, there's no need to re-write the User-Name.  It is very, very,

>                 if (User-Name
> =~/^([0-9a-f]{2})-([0-9a-f]{2})-([0-9a-f]{2})-([0-9a-f]{2})-([0-9a-f]{2})-([0-9a-f]{2})$/i){
>                         update reply {
>                                 Reply-Message := "Hello Guest, I'will
> try to give you 30 minutes for free, if you didn't allready used it."
>                         }
>                         update request{
>                                 User-Name := "freeinternetfor30minutes"
>                         }

  Again, why would this EVER be a good idea?

>                         update control {
>                                 Auth-Type := "Accept"
>                         }

  You're not setting Session-Timeout.  So they can stay on for as long
as they want.

>                 }
>                else {
>                       ok = reject
>                }

  I don't see why this is here.

> That is working fine, users can connect to the network, BUT accounting
> section logges their username in database as original MAC address, not
> rewritted username freeinternetfor30minutes .

  Yes.  That is a GOOD IDEA.  You need to COMPLETELY FORGET about the
username "freeinternetfor30minutes".  It's a BAD IDEA.

> Also no bandwidth
> limitations arn't sent with Access-Accept, but I think that could be
> solved easyly.


> I've also tries to use module "attr_rewrite". I wrote those lines of
> code to "modules/attr_rewrite"

  Why?  You've got the idea to re-write the username.  This makes no
sense.  It's not part of the requirements.

  It seems you just randomly chose a particular solution, rather than
trying to solve the problem piece by piece.

> and unhashed rewrite_user in "sites-available/default". I see that
> rewriting does happen, BUT then
> update control {
>     Auth-Type := "Accept"
> }
> seems to stop working even if I put rewrite_user before "update control"

  Well, I'm not even going to try to understand that.  The solution is
wrong, so there's no surprise it doesn't work.

> AND also in accounting section User-Name is still MAC address, not
> rewritten username.

  This is a good thing.

  How do you expect to track 30min usage per user, when all usernames
are "freeinternetfor30minutes" ?

> I am stuck now, without any idea. Can anyone tell me, is this even
> possible what I am trying to do and if so, what path should I take.

  It's possible.  The path is very simple.

> Would it be possible to create new virtual server and pass rewritten
> username to that virtual server, which would try to login as
> "freeinternetfor30minutes"

  Don't do that.  FORGET ABOUT that username.  It is indescribably
wrong.  It will not solve the problem.  It will CREATE problems.

  Alan DeKok.

More information about the Freeradius-Users mailing list