duplicate-users   [plain text]



User Collision in FreeRadius
----------------------------

0.  INTRODUCTION

    A.  What is it?

        User collision is the ability to uniquely authenticate duplicate
        usernames in radius. In addition, it provides resources to
        correctly identify each duplicate user in the accounting logs.

    B.  Who needs it and why?

        Many ISPs are acquiring other ISPs in local or remote areas.  This
        causes problems with centralizing services such as radius because
        of the overlap in usernames between ISPs.

        For example:

        o  ISP A (with 10,000 users) acquires ISP B (with 1,000 users).
        o  ISP A determines that 375 of ISP B's 1,000 usernames conflict
           with usernames already in use at ISP A (eg 'foo' is valid
           username on both ISPs)
        o  ISP A, therefore, cannot merge its user files with ISP B and
           centralize radius

        Now, about now, many of you are thinking, "what about realms?"  
        Well, realms are great, but, in general, it will require the end
        user to add "@domain.com", which is a pain. It means ISP A has to
        call 375 people and tell them to add that to their login name.

        And now some of you are thinking, "why couldn't you add the realm
        in the server based on some other attribute (such as NAS-IP or
        Calling-Station)?"  The answer is, you could, but both of those
        solutions are a pill to maintain.  For example, what if you want
        to merge the huntgroups (and NASs) of ISP A and ISP B?  Then the
        NAS-IP method falls apart.  And god forbid the user call from a
        different number or change their line for Calling-Station.

        So how to solve it?  Enter user collision code in radius...

    C.  How does it work?

        Currently, it only works when authenticating users via the
        following methods in FreeRadius:

        o  'users' file ( Auth-Types 'Local' and 'Crypt-Local' _ONLY_ )
        o  cached password (and shadow) file users
				o  rlm_fastusers module (see README.rlm_fastusers)

        That's it so far.  Perhaps other module authors will include it in
        their code later, but that is for them to decide.

        Btw, the reason user collision cannot be implemented (efficiently)
        on a non-cached /etc/passwd file is because getpwnam() will always
        return the first user it finds with a matching username.  Thus, if
        you're going to use the /etc/passwd file, you MUST set 'cache =
        yes' in your radiusd.conf.  Or, you could always just put
        duplicate usernames in the 'users' files, but you should probably
        be caching anyway if you want a speedy server :)

1.  Authentication

    It currently works by using the password of the user to uniquely
    identify and auth- enticate them.

    Example:

    ISP A user 'foo' has password 'bar'
    ISP B user 'foo' has password 'bleah'

    If the user logs in with 'bar' as their password, their login will be
    accepted and they will get the reply attributes associated with what
    you've entered for the user 'foo' password 'bar' entry.

    If the user logs in with 'bleah' as the password, again, they'll be
    authenticated, but they will get the reply attributes associated with
    user 'foo' password 'bleah'.

    So, what happens if two users have the same password?  IT
    BREAKS.  Well, ok, it doesn't "break", but every user with the
    associated pass will get the same reply attributes, causing grief for
    you.  THE CODE DOES NOT CHECK FOR THIS, THAT IS YOUR JOB!

    NOTE:  Again, user collision authentication *depends* on the passwords
    being distinct!

    So the security minded among us are now agast.  I'm not much for this
    method myself, but trust me, the corporate folks are gonna love it.  
    And it's not inherently insecure as long as the passwords remain
    different.

2.  Accounting

    Ok, so now, how can we tell in the accounting logs which user 'foo'
    logged in?  Well, again, you have a little work to do.  The code
    identifies the user via a unique value assigned to the 'Class' reply
    attribute in the users file.

    For example:

    foo Auth-Type := Local, User-Password == "bar"
    Class = 0x0001

    foo Auth-Type := Local, User-Password == "bleah"
    Class = 0x0002

    Now, you'd add other attributes as well, but let's just start with
    'Class' by itself as a reply.  When a user 'foo' logs in with password
    'bar', the 'Class=0x0001' reply item gets sent back to the NAS they
    dialed into.  The NAS then adds 'Class=0x0001' to the Accounting
    'Start' packet it sends for that user, thus uniquely identifying *this*
    'foo' in the your accounting logs.

    If the user 'foo' logs in with password 'bleah', you will get
    'Class=0x0002' in your accounting logs.

    Now, again, you should note that it is *your job* to make sure the
    'Class' values are different for each user.  If you don't, I can assure
    you the phones will ring off the hook when bitchy users get their
    bills.

    Obviously, this method works only for users in your 'users' files.  

    If you are using a cached passwd file, then the "Full name" field in
    the passwd file you cached will be passed back to the NAS as the value
    of 'Class'.

    Example:

    /etc/passwd  ->  test:x:500:500:0x1001:/dev/null:/dev/null

    In this case, "0x1001" will be passed as the value for the 'Class'
    attribute when the Auth-Accept packet gets sent back to the NAS, and
    then you should see 'Class=0x1001' for that user in your accounting
    logs.

    Once again, it is your job to ensure that these Class values are unique
    for each user.

D.  *Does* it work?

    As of 10-01-2000, it is *extremely alpha*.  If you find bugs, by all
    means let met know at jeff@apex.net, but make sure you include
    relavent sections of your 'users' file and debug output from the
    server (radiusd -X).

1.  USAGE

		Set 'usercollide=yes' in your radiusd.conf and either restart or
    kill -HUP radiusd.

2.  CAVEATS

    Currently does not work with all modules (ie, sql, ldap, etc).

3.  ACKNOWLEDGEMENT

    Jeff Carneal - Author
    Alan DeKok - for telling me about the 'Class' attribute :)