1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
|
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 :)
|