Free Radius and MySQL HowTo Notes
LinuxGuru.....Satish Patel ( linuxtrap@yahoo.co.in )
This is my first project okie.... getting stared you should get FreeRadius
compiled, installed and running in a basic text file configuration (e.g. using
the 'users' file) on your box. This I'm not going to describe in details (read
the stuff in /docs, etc), but it should basically be the following:
1 - Get the latest FreeRadius source code tarball from ftp://ftp.freeradius.org/pub/radius/freeradius.tar.gz.
If you're so minded, get the latest CVS instead.
2 - Unpack the tarball and install it. On my own system the basic steps were all
that was needed, and everything got dumped in the standard places:
tar xvf freeradius.tar.gz
cd freeradius
./configure
make
make install
Note that you might need to add options to ./configure if you installed MySQL to
a non-standard place, or want FreeRadius to a non-standard place, or want or
need any other odd bits and pieces. I was keeping it simple and didn't need to.
Then you should configure FreeRadius appropriately. It's best to start with a
simple config using the standard text files, if at least only to test that
FreeRadius installed OK and will work. To very briefly summarise getting the
text files configured :
1 - Edit /usr/local/etc/raddb/clients.conf and enter the details of your NAS
unit(s). There are examples here, so it should be easy. Tip: You'll also want to
enter 'localhost' here for testing purposes (i.e. so you can use radtest).
2 - Edit /usr/local/etc/raddb/users and create an example user account. The file
is commented on how to do this. I'm not going to repeat that here. If you've
previously used another RADIUS server with text-file configuration (e.g.
Livingston, Cistron) you'll know what goes here...
3 - Edit /usr/local/etc/raddb/realms. I just put a single line 'DEFAULT LOCAL'
and that was sufficient to strip any suffix domain names in given user names -
if you're using realms or proxing you'll doubtless need to do something else
here, but I recommend you start with this then come back to setting up realms/
proxying when you know MySQL is working. If you're not using realms, just ignore
this.
4 - Edit /usr/local/etc/raddb/radiusd.conf and change as needed. For my own
installation I changed the default port to run on 1645 (old port) to match what
our existing boxes use (but otherwise make sure your NAS and FreeRadius are
using the same) and said 'yes' to all the logging options (I'd strongly
recommend you do switch on all the logging to start with). At this point I also
said 'no' to using proxy to keep stuff simple. I then told it to run under the
'radius' user and group (I'd initially installed FreeRadius as root and didn't
want to run it as such, so I created a user account called 'radius' in a group
called 'radius' and then just blanket chown'd and chgrp'd the various radius
directories to that user just to be sure the account can access all the right
stuff. A bit of a sledgehammer there, but it was quick! I'm sure there's a
better and/or more elegant way of doing this!). The rest of the radiusd.conf
file was left alone.
At this point you should be able to manually fired up /usr/local/sbin/radiusd.
You should do this with the debug turned on so you can see what happens:
/usr/local/sbin/radiusd -X
Lots of stuff will scroll to the screen, and it should tell you it's ready to
accept requests. If you get an error, READ THE DEBUG, then check the docs, check
the above and try again.
You should now be able to use FreeRadius. You can use radtest to test an account
from the command line:
radtest username password servername port secret
So, if your example user is 'fred' with password 'wilma', your server is called
'radius.domain.com', is using port 1645, and you put localhost (or your
localhost's IP) in clients.conf with a secret of 'mysecret', you should use:
radtest fred wilma radius.domain.com 1645 mysecret
And you should get back something like:
Sending Access-Request of id 226 to 127.0.0.1:1645
User-Name = 'fred'
User-Password = '\304\2323\326B\017\376\322?K\332\350Z;}'
NAS-IP-Address = radius.domain.com
NAS-Port = 1645
rad_recv : Access-Accept packet from host 127.0.0.1:1645,id=226, length=56
Framed-IP-Address = 80.84.161.1
Framed-Protocol = PPP
Service-Type = Framed-User
Framed-Compression = Van-Jacobson-TCP-IP
Framed-IP- Netmask = 255.255.255.255
You should get an 'Access Accept' response. If you don't, do not pass Go, do not
collect £200. Go back and check everything. Read the docs, READ THE DEBUG!!
Personally, I used NTradPing (downloadable from MasterSoft) on a desktop Windows
PC to send test packets towards the radius server - very handy tool. If you do
this, or test from any other machine, remember your PC (or other machine) needs
to be in your NAS list in clients.conf too!
OK, so at this point you should have text-file authentication working in
FreeRadius...
Setting up the RADIUS database in MySQL
First, you should a new empty 'radius' database in MySQL and login user with
permissions to that database. You could of course call the database and the user
anything you like but we'll stick to 'radius' for both for the purposes of this
discussion
Next up, you need to create the schema for the database. There is a file which
describes this and is actually a SQL script file. It can be found at /src/modules/rlm_sql/drivers/rlm_sql_mysql/db_mysql.sql
where you untar'd FreeRadius. This is the bit that, at least at the time I
originally wrote these notes, wasn't really documented anywhere and was the
thing most people seemed to be asking.
How you run that script is up to you and how you like to admin MySQL. The
easiest way is to:
mysql -uroot -prootpass radius < db_mysql.sql
...where 'root' and 'rootpass' are your mysql root name and password
respectively.
I happened to run it using MacSQL 2.0 on my Powerbook G4/OS X machine (Cool...).
You could do it on the server, or use a MySQL admin tool from a Windows PC (e.g.
MySQL CC, SQLion, dbtools etc) or whatever.
Now you have the database running, albeit empty.
Configuring FreeRadius to use MySQL
Edit /usr/local/etc/raddb/sql.conf and enter the server, name and password
details to connect to your MySQL server and the RADIUS database. The database
and table names should be left at the defaults if you used the default schema.
For testing/debug purposes, switch on sqltrace if you wish - FreeRadius will
dump all SQL commands to the debug output with this on.
If you're stripping all realm names (i.e. you want user joe@domain.com to
authenticate as just 'joe'), then in sql.conf, under the 'query config:
username' section, you MAY need to adjust the line(s) referring to sql_user_name.
I needed to do this originally because we want to dump all realms, but you
probably won't need to do this with the latest FreeRadius. For example, in our
case I needed to uncomment the line:
sql_user_name = '%{Stripped-User-Name}'
...and comment out the following line referring to just User-Name. If you want
to see what's happening here, switch on all the logging options in radiusd.conf
and run radiusd in debug mode (-X) to see what's happening : you'll see "
user@domain" being passed to MySQL when using User-Name, but just "user" when
using Stripped-User-Name. Using the latter, realms worked for me (basically, I
strip everything, as all user names are unique on the server anyway). Of course,
set all your other SQL options as needed (database login details, etc)
Edit /usr/local/etc/raddb/radiusd.conf and add a line saying 'sql' to the
authorize{} section (which is towards the end of the file). The best place to
put it is just before the 'files' entry. Indeed, if you'll just be using MySQL,
and not falling back to text files, you could comment out or lose the 'files'
entry altogether.
Also add a line saying 'sql' to the accounting{} section too between 'unix' and
'radutmp'. FreeRadius will now do accounting to MySQL as well.
The end of your radiusd.conf should then look something like this:
authorise {
preprocess
chap
mschap
#counter
#attr_filter
#eap
suffix
sql
#files
#etc_smbpasswd
}
authenticate {
authtype PAP {
pap
}
authtype CHAP {
chap
}
authtype MS-CHAP{
mschap
}
#pam
#unix
#authtype LDAP {
# ldap
#}
}
preacct {
preprocess
suffix
#files
}
accounting {
acct_unique
detail
#counter
unix
sql
radutmp
#sradutmp
}
session {
radutmp
}
Populating MySQL
You should now created some dummy data in the database to test against. It goes
something like this:
* In usergroup, put entries matching a user account name to a group name.
* In radcheck, put an entry for each user account name with a 'Password'
attribute with a value of their password.
* In radreply, create entries for each user-specific radius reply attribute
against their username
* In radgroupreply, create attributes to be returned to all group members
Here's a dump of tables from the 'radius' database from mysql on my test box
(edited slightly for clarity). This example includes three users, one with a
dynamically assigned IP by the NAS (fredf), one assigned a static IP (barney),
and one representing a dial-up routed connection (dialrouter):
mysql> select * from usergroup;
+----+---------------+-----------+
| id | UserName | GroupName |
+----+---------------+-----------+
| 1 | fredf | dynamic |
| 2 | barney | static |
| 2 | dialrouter | netdial |
+----+---------------+-----------+
3 rows in set (0.00 sec)
mysql> select * from radcheck;
+----+----------------+----------------+------------------+------+
| id | UserName | Attribute | Value | Op |
+----+----------------+----------------+------------------+------+
| 1 | fredf | Password | wilma | == |
| 2 | barney | Password | betty | == |
| 2 | dialrouter | Password | dialup | == |
+----+----------------+----------------+------------------+------+
3 rows in set (0.02 sec)
mysql> select * from radgroupcheck;
+----+------------+-------------------+---------------------+------+
| id | GroupName | Attribute | Value | Op |
+----+------------+-------------------+---------------------+------+
| 1 | dynamic | Auth-Type | Local | := |
| 2 | static | Auth-Type | Local | := |
| 3 | netdial | Auth-Type | Local | := |
+----+------------+-------------------+---------------------+------+
3 rows in set (0.01 sec)
mysql> select * from radreply;
+----+------------+-------------------+---------------------------------+------+
| id | UserName | Attribute | Value | Op |
+----+------------+-------------------+---------------------------------+------+
| 1 | barney | Framed-IP-Address | 1.2.3.4 | := |
| 2 | dialrouter | Framed-IP-Address | 2.3.4.1 | := |
| 3 | dialrouter | Framed-IP-Netmask | 255.255.255.255 | := |
| 4 | dialrouter | Framed-Routing | Broadcast-Listen | := |
| 5 | dialrouter | Framed-Route | 2.3.4.0 255.255.255.248 | := |
| 6 | dialrouter | Idle-Timeout | 900 | := |
+----+------------+-------------------+---------------------------------+------+
6 rows in set (0.01 sec)
mysql> select * from radgroupreply;
+----+-----------+--------------------+---------------------+------+
| id | GroupName | Attribute | Value | Op |
+----+-----------+--------------------+---------------------+------+
| 34 | dynamic | Framed-Compression | Van-Jacobsen-TCP-IP | := |
| 33 | dynamic | Framed-Protocol | PPP | := |
| 32 | dynamic | Service-Type | Framed-User | := |
| 35 | dynamic | Framed-MTU | 1500 | := |
| 37 | static | Framed-Protocol | PPP | := |
| 38 | static | Service-Type | Framed-User | := |
| 39 | static | Framed-Compression | Van-Jacobsen-TCP-IP | := |
| 41 | netdial | Service-Type | Framed-User | := |
| 42 | netdial | Framed-Protocol | PPP | := |
+----+-----------+--------------------+---------------------+------+
12 rows in set (0.01 sec)
mysql>
In this example, 'barney' (who is a single user dialup) only needs an attribute
for IP address in radreply so he gets his static IP - he does not need any other
attributes here as all the others get picked up from the 'static' group entries
in radgroupreply.
'fred' needs no entries in radreply as he is dynamically assigned an IP via the
NAS - so he'll just get the 'dynamic' group entries from radgroupreply ONLY.
'dialrouter' is a dial-up router, so as well as needing a static IP it needs
route and mask attributes (etc) to be returned. Hence the additional entries.
'dialrouter' also has an idle-timeout attribute so the router gets kicked if
it's not doing anything - you could add this for other users too if you wanted
to. Of course, if you feel like or need to add any other attributes, that's kind
of up to you!
Note the operator ('op') values used in the various tables. The password check
attribute should use ==. Most return attributes should have a := operator,
although if you're returning multiple attributes of the same type (e.g. multiple
Cisco- AVpair's) you should use the += operator instead otherwise only the first
one will be returned. Read the docs for more details on operators.
If you're stripping all domain name elements from usernames via realms, remember
NOT to include the domain name elements in the usernames you put in the MySQL
tables - they should get stripped BEFORE the database is checked, so name@domain
will NEVER match if you're realm stripping (assuming you follow point 2 above) –
you should just have 'name' as a user in the database. Once it's working
without, and if you want more complex realm handling, go back to work out not
stripping (and keeping name@domain in the db) if you really want to.
Auth-Type Note, Feb 2003: At the time of writing (i.e. up to and including
FreeRadius 0.8.1), FreeRadius will default to an Auth-Type of 'local' if one is
not found. This means that you do not need to include this (i.e. the
radgroupcheck table above could actually be empty, and indeed is on my own box),
but you probably should include it for clarity and for future-proofing in case
FreeRadius changes. Please note that a previous version of this page indicated
that Auth-Type should be included in the rad(group)reply tables. It appears that
this is incorrect and that Auth-Type should be in the rad(group)check tables.
Other than Auth-Type, for simple setups, you probably need nothing in
radgroupcheck - unless you want users dialing certain nas'es, etc etc.
Using FreeRadius and MySQL
Fire up radiusd again in debug mode. The debug output should show it connecting
to the MySQL database. Use radtest (or NTradPing) to test again - the user
should authenticate and the debug output should show FreeRadius talking to MySQL.
You're done!
Additional Snippets:
To use encrypted passwords in radcheck use the attribute 'Crypt-Password',
instead of 'Password', and just put the encrypted password in the value field. (
i.e. UNIX crypt'd password).
To get NTradPing to send test accounting (e.g. stop) packets it needs arguments,
namely acct-session-time. Put something like 'Acct-Session-Time=99999' into the
'Additional RADIUS Attributes' box when sending stops. Thanks to JL for the tip.
If you have a Cisco nas, set the cisco-vsa-hack
Running a backup FreeRadius server and need to replicate the RADIUS database to
it? I followed Colin Bloch's basic instructions at http://www.ls-l.net/mysql/
and got replication setup between two MySQL servers. Real easy. Read the MySQL
docs on replication for more details. Note that MySQL replication is
one-way-only.
On the subject of backup servers. If you want to run TWO MySQL servers and have
FreeRadius fall over between them, you'll need to do something like this:
duplicate your sql.conf and edit the second copy to reflect connecting to your
backup server ; then name the files something like sql1.conf and sql2.conf ; in
radiusd.conf change and duplicate the include line for sql.conf to include
sql1.conf and sql2.conf instead ; in the 'authorize' section of radiusd.conf
change the 'sql' entry to a 'group' one, like this:
group {
sql1 {
fail = 1
notfound = return
noop = 2
ok = return
updated = 3
reject = return
userlock = 4
invalid = 5
handled = 6
}
sql2 {
fail = 1
notfound = return
noop = 2
ok = return
updated = 3
reject = return
userlock = 4
invalid = 5
handled = 6
}
}
Note that if FreeRadius fails over to the second MySQL server and tries to
update the accounting table (radacct), nasty things might possibly happen to
your replication setup and database integrity as the first MySQL server won't
have got the updates...
Auther : Satish Patel
Company: Tulip It Services Ltd. ( Datacenter )
-- end--
Apache
reported from :
http://www.geocities.com/satish_patel_2000_2000/