SB's very rough notes to:
FreeRadius and MySQL

Scott Bartlett ( contact ). Last updated March 28th 2002. [FreeRadius is currently at version 0.5]

These notes are in somewhat random order, with important bits at the end - I *very strongly recommend* you read through
*everything* and take note where appropriate before configuring your system.

1. Original Notes, Sept 13th 2001 - FreeRadius 0.2 and MySQL 3.23.42.
2. Additional Random Snippets, Oct 16th 2001.
3. More Additional Random Snippets, Nov 14th 2001.
4. Notes about FreeRadius 0.5 changes, March 28 2002.

[Quick Tip: Since FreeRadius 0.5 you NO LONGER need to put 'sql' in the 'authenticate' section of radiusd.conf - see bottom of page for details!]


Original Notes, Sept 13th 2001
Back to top

Introduction

I've been playing about with FreeRadius (currently at build 0.2) and also getting it to work authenticating to a MySQL database. Lots of people seem to be posting to the freeradius-users list that they've been trying to do the same and have found it tricky due to the lack of documentation. Thus, to help anyone out there who wants it, I've jotted down my notes and put them here.

Please note: This isn't official documentation. It's not even UNofficial documentation. It's not documentation of any type by any stretch of the imagination. So far, it's just my own personal notes, written on the fly. Little editing, little detail. I will try to improve when I can, or have additional information - don't hold your breath though, as life can get busy around here. The notes focus on the SQL element, NOT generally on getting FreeRadius installed and configured and operational with text files (maybe later!) although there is a little bit on that.

Also note: I'm not a programmer - editing low-level code and compiling stuff is not something I'm particularly familiar with. My background and experience on Linux (and other stuff) puts me in the system admin/networking bracket (I'm a network builder and web app developer by day), so please bear that in mind here. Feel free to mail me, especially with suggestions and any info useful to add here, but please don't ask me 'how to I compile' stuff. Thanks.

System

SuSe Linux 7.0 on Intel, FreeRadius 0.2, MySQL 3.23.42. I have a Cisco 3640 wired in acting as a test NAS unit. I hopefully plan to finally deploy to RedHat 7.1 if things work out OK.

Notes

These initial notes are derived from an email message I send to someone working on the same problem. These notes are very brief, but outline the steps I found necessary to prod things into life. They also assume that MySQL (server, client, developer libs etc) is already installed on your server, that you know how to use MySQL (I'm learning), that you understand what RADIUS is and does and what RADIUS attributes are, and you know some reasonable Linux system admin shell stuff. There are no guarantees of accuracy or completeness here - I may well have missed bits out. You takes your chances...

Well, as noted I got it working. Here goes:

I compiled and installed FreeRadius - I just grabbed the source tarball, unpacked it, did ./configure, make etc - and then got it working with text files OK. To summarise getting the text files configured : I just entered details of my test NAS in /usr/local/etc/raddb/clients.conf (and in 'naslist'??) and created an example user account in /usr/local/etc/raddb/users. In /usr/local/etc/raddb/radiusd.conf I changed the default port to run on 1645 (old port) to match what our existing boxes use, and said 'yes' to all the logging options. At this point I also said 'no' to using proxy to keep stuff simple. No other changes as far as I recall. I created a user account under RedHat called 'radius' in a group called 'radius' and then just blanket chown'd the various radius directories to that user (bit of a sledgehammer there, but it was quick! Just to be sure the account can access all the right stuff). In radiusd.conf I told it to run under the radius user and group. Then I manually fired up /usr/local/sbin/radiusd.

I used NTradPing (downloadable from MasterSoft on a desktop Windows PC to send test packets towards the radius server. Authentication worked fine. Accounting (remember to switch NTradPing to use the right port!) always failed. I thought it was the config causing the latter, but I then tried from the NAS itself by actually dialing in and it worked fine. I also set up demo user accounts to give a) static IP and b) static IP and local-subnet routing and they all worked fine. Still couldn't get the accounting to work in NTRadPing though... but hey, reality worked so I didn't really care.

OK, so at this point I have text-file authentication working in FreeRadius

Then off to SQL:

First I created a new empty 'radius' database in MySQL, granted permissions to root - I'm using the root MySQL user for the moment whilst testing.

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 freeradius/src/modules/rlm_sql/drivers/rlm_sql_mysql/db_mysql.sql. This is the bit that isn't really documented anywhere (like in the FAQ) and is the thing most people seem to be asking. How you run that script is up to you and how you like to admin MySQL. 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. SQLion, dbtools etc) or whatever.

In /usr/local/etc/raddb/radiusd.conf, I added a line saying 'sql' between 'suffix' and 'files' in the authorize{} section towards the end of the file and also put 'sql' only (unix and pam commented out) in the authenticate{} section too [NB: this last bit no longer required in 0.5+ !! - see end of page - SB]. I also added 'sql' to the accounting{} section too between 'unix' and 'radutmp'. This should then put the sql module in the 'right places' in the chain for each function.

In /usr/local/etc/raddb/sql.conf I just put in the correct MySQL user name and password to use - in my case so far the root and rootpass. The database and table names were all the defaults, so I left them. I switched sqltrace to yes for fun (!). That was it.

I killed and restarted /usr/local/sbin/radiusd.

I created some dummy data in the database to test against. You don't seem to need any Auth-Type lines anywhere (another thing which trips people up, I think). It goes something like this:

I then stopped and restarted radiusd, and it seemed to work. Voila! Done.

Interestingly, NTRadPing could also then send accounting start packets and they log OK, although stops still didn't work.

Additional Notes:

Someone noted on the list that if in radcheck you use attribute Crypt-Password, instead of Password, to use encrypted passwords you just need to put the encrypted password in the value field and that's it (i.e. UNIX crypt'd password). Haven't tried this personally yet.

I got the realms to work : I'd not spotted the line in the section of sql.conf referring to stripped-user-name. I commented out the user-name line and uncommented the stripped one, and it now seems to work...[No longer seems to be an issue in latest versions - SB]

Things I want/need to do:

Don't know how to get Accept mode working under SQL.

Need to work out how to do replication in MySQL for redundancy purposes (anyone any FAQ's??)

 


Additional Random Snippets, Oct 16th 2001
Back to top

I've accumulated a number of extra snippets of information from emails I've sent and received which might prove useful. So, in no particular order:

----------

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            |
+----+----------------+----------------+------------------+
|  1 | fredf          | Password       | wilma            |
|  2 | barney         | Password       | betty            |
|  2 | dialrouter     | Password       | dialup           |
+----+----------------+----------------+------------------+
3 rows in set (0.02 sec)

mysql> select * from radgroupcheck;
Empty set (0.00 sec)

mysql> select * from radreply;

+----+------------+-------------------+---------------------------------+
| id | UserName   | Attribute         | Value                           |
+----+------------+-------------------+---------------------------------+
|  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               |
+----+-----------+--------------------+---------------------+
| 34 | dynamic   | Framed-Compression | Van-Jacobsen-TCP-IP |
| 33 | dynamic   | Framed-Protocol    | PPP                 |
| 32 | dynamic   | Service-Type       | Framed-User         |
| 31 | dynamic   | Auth-Type          | Local               |
| 35 | dynamic   | Framed-MTU         | 1500                |
| 36 | static    | Auth-Type          | Local               |
| 37 | static    | Framed-Protocol    | PPP                 |
| 38 | static    | Service-Type       | Framed-User         |
| 39 | static    | Framed-Compression | Van-Jacobsen-TCP-IP |
| 40 | netdial   | Auth-Type          | Local               |
| 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!

----------

Edited from an email

1. For simple setups, you probably need nothing in radgroupcheck - unless you want users dialing certain nas'es, etc etc.

2. I haven't really worked out yet if nas and realms actually worked in mysql - on my test server I config'ed up the text files for those instead and then they worked, even whilst auth'ing via MySQL. In the realms file I just put a line 'DEFAULT LOCAL' and that was sufficient to strip any suffix domain names in given user names.

3 If you're stripping all realm names, then in sql.conf, in the 'query config: username' section, UNcomment this 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)

4. Using NTRadPing as a test tool, it doesn't do accounting for me properly. I could get it to log accounting starts, but not stops. Using a real NAS, the accounting works. Weird.

5. 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). 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.

6. Assuming it works (see note 2), I think the 'nas' field in the realms table should read 'LOCAL' and the authport field can be blank (just like with the realms text file). Still need to actually fiddle and try this ;-)

7. If you have a Cisco nas, set the cisco-vsa-hack.

8. Make sure your authenticate and authorise sections at the bottom of radius conf have an 'sql' entry (before or replacing 'files'). Ditto in accounting. The tail of my radiusd.conf looks like this (commented lines skipped):

authorise {
	preprocess
	suffix	
	sql
}

authenticate {
	sql
}

preacct {	
	suffix
	preprocess
}

accounting {
	detail
	unix
	sql
	radutmp
}

session {
	radutmp
}

----------

RE: MySQL Replication for redundancy purposes

I followed Colin Bloch's instructions at http://www.ls-l.net/mysql/ and got replication setup between two MySQL servers. Real easy. Nice one Colin! Thanks...

 


More Additional Random Snippets, Nov 14th 2001
Back to top

I really should put all this stuff in order, instead of randomly adding bits to the bottom...

Oh yeah : ABSOLUTELY MAKE SURE you have the mysql-devel (headers and libraries) package installed with your MySQL, otherwise freeradius won't compile with MySQL support properly. Many people seem to miss having this.

Regarding NTradPing's inability to send accounting stops properly : I received a tip from JL who notes : "In order for the accounting process to parse the packet correctly, it needs arguments, namely acct-session-time." So, put something like 'Acct-Session-Time=99999' into the 'Additional RADIUS Attributes' box when sending stops... thanks JL...

 


Notes about FreeRadius 0.5 changes, March 28 2002.
Back to top

In FreeRadius 0.5 there are a couple of changes to be aware of (they actually occur in later CVS releases of 0.4).

The first is a change which affects the SQL config. You no longer require an "sql" entry in the "authenticate" section of radius.conf. If you have one there (e.g. if you have upgraded from 0.4), FR will stop with an error noting this fact. Just remove the entry from radiusd.conf.

Secondly, the SQL schema has changed slightly to include an "op" field (CHAR 2) in radcheck and radgroupcheck. If you upgrade from 0.4 then you will probably need to do this manually - the schema file included with 0.5 shows this in detail.

--end--