Can anyone offer some configuration advice? Our wireless deployment automatically assigns users to any one of around 20 client VLANS. We have a very small number of MAC addresses (currently 2) that for one reason or another need a static IP. We use RADIUS to make sure they are put on one specific VLAN. This is currently done with a MySQL table of MAC addresses and the following section in the post auth: # Return a static vlan for those in the static IP group if ("%{sql:SELECT COUNT(*) FROM eduroam_static WHERE mac='%{Calling-Station-Id}'}" != 0) { update reply { Tunnel-Type := VLAN Tunnel-Medium-Type := IEEE-802 Tunnel-Private-Group-ID := 641 } } While this works quite nicely, I have two concerns. One is the efficiency overhead. It is performing a SQL lookup on every auth just to make sure 2 MAC addresses are put in the correct VLAN. The other is that we do not have a resilient database server, so when that reboots for patching my FreeRADIUS servers fall over. Build a better database infrastructure is one solution, but I was wondering if there is a better way of doing this? Being such a small dataset, is it possible to maintain an array or list, then use a function to say something like 'if (%{Calling-Station-Id} is in list) {.....'? I could make that if statement a big list of 'this mac or this mac or...', but it could get messy. I would also like to keep the list of special MAC addresses in its own file. This would allow us to deploy the list via puppet. My googling has not turned up anything like what I want, apart from the mac2vlan file used by VPMS. Running a VPMS server seems like overkill too. Any suggestions appreciated. Yours Dave Hartburn
On 02/11/16 12:40, David Hartburn wrote:
Build a better database infrastructure is one solution, but I was wondering if there is a better way of doing this?
Better DB infra. *is* the better way in my opinion - for what it's worth, we run our radius servers with a local (same box) SQL read-only replica of the DB - but you can easily wrap this in a cache instance (which we *also* do): cache staticip { key = "%{Calling-Station-Id}" update request { Tmp-Integer-0 := "%{sql:select count...}" } } ...then in the policy: post-auth { staticip if (Tmp-Integer-0 != 0) { update reply ... } }
Being such a small dataset, is it possible to maintain an array or list, then use a function to say something like 'if (%{Calling-Station-Id} is in list) {.....'?
You could store the list in a text file and read it with rlm_passwd, or a users file with rlm_files. We've got a couple of "outside-of-SQL" exceptions stored in things like that. You can iterate over the list with foreach.
You could store the list in a text file and read it with rlm_passwd, or a users file with rlm_files. We've got a couple of "outside-of-SQL" exceptions stored in things like that.
You can iterate over the list with foreach.
Thanks for the suggestion. Do you have any examples you can offer of using foreach with rlm_files? I can not find much in the way of examples or documentation. In mods-enables/files, I have: files eduroam_static_ip { key = "%{Calling-Station-ID}" usersfile = ${confdir}/eduroam_static_ip } The file itself just contains the MAC address I am testing with: 42-42-42-42-42-42 Then in the sites file post auth, I have tried: foreach (eduroam_static_ip) { if (%{Foreach-Variable-0} == %{Calling-Station-Id}) { update reply { Tunnel-Type := VLAN Tunnel-Medium-Type := IEEE-802 Tunnel-Private-Group-ID := 641 } } } /etc/raddb-kent/sites-enabled/kent-eduroam[559]: Parse error after "foreach": unexpected token "(" Errors reading or parsing /etc/raddb-kent/radiusd.conf It looks like I'm missing the syntax for telling it to use the file as a list of attributes. Cheers Dave
On 02/11/16 15:57, David Hartburn wrote:
The file itself just contains the MAC address I am testing with: 42-42-42-42-42-42
Oh of course, that's even easier. "files" returns "ok" if it matches but not otherwise (IIRC). You can just do this: postauth { eduroam_static_ip if (ok) { update reply ... } } No need to do foreach. I was thinking about the problem the wrong way round.
Thanks. I think that is one thing I keep failing to get the correct way round with FreeRADIUS, you do not do 'if (do something)', you do something then check the result with an if. Once you are in the right mind set, it does make some quite neat and tidy configs. It is not quite working though, do you think I'm specifying my file correctly? It certainly seems to be reading it in, running with -X: # Loading module "eduroam_static_ip" from file /etc/raddb-kent/mods-enabled/files files eduroam_static_ip { usersfile = "/etc/raddb-kent/eduroam_static_ip" key = "%{Calling-Station-ID}" } ..... # Instantiating module "eduroam_static_ip" from file /etc/raddb-kent/mods-enabled/files reading pairlist file /etc/raddb-kent/eduroam_static_ip Then during an auth test: (10) eduroam_static_ip: EXPAND %{Calling-Station-ID} (10) eduroam_static_ip: --> 42-42-42-42-42-42 (10) [eduroam_static_ip] = noop (10) if (ok) { (10) if (ok) -> FALSE I had tried following closely the MacAuth guide on the wiki (https://wiki.freeradius.org/guide/mac-auth), so I added the Reply-To after my MACs just to see if having an attribute in there made a difference. With a few different formats thrown in, that now reads: # eduroam_static_ip # # Contains a list of MAC addresses to be assigned to a particular VLAN # so they can obtain a static IP address. 42-42-42-42-42-42 Reply-Message = "Moooo" 424242424242 Reply-Message = "Quack" '42-42-42-42-42-42' Reply-Message = "Oink" "42-42-42-42-42-42" Reply-Message = "Woof" I was expecting only the first one to work, but it is still failing to match. Dave On 02/11/16 16:02, Phil Mayers wrote:
On 02/11/16 15:57, David Hartburn wrote:
The file itself just contains the MAC address I am testing with: 42-42-42-42-42-42
Oh of course, that's even easier. "files" returns "ok" if it matches but not otherwise (IIRC). You can just do this:
postauth { eduroam_static_ip if (ok) { update reply ... } }
No need to do foreach. I was thinking about the problem the wrong way round. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
On 02/11/16 16:42, David Hartburn wrote:
files eduroam_static_ip { usersfile = "/etc/raddb-kent/eduroam_static_ip"
If you are calling this "files" instance in a post-auth section, either: 1. change "usersfile" to "postauth_usersfile" 2. call it as "eduroam_static_ip.authorize" to execute the authorize handler Probably #1 vs. #2
Morning, Brilliant, that did the trick (#1). Many thanks for your help on this one, I appreciate it. Dave On 02/11/16 16:55, Phil Mayers wrote:
On 02/11/16 16:42, David Hartburn wrote:
files eduroam_static_ip { usersfile = "/etc/raddb-kent/eduroam_static_ip"
If you are calling this "files" instance in a post-auth section, either:
1. change "usersfile" to "postauth_usersfile" 2. call it as "eduroam_static_ip.authorize" to execute the authorize handler
Probably #1 vs. #2 - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
On Nov 2, 2016, at 12:42 PM, David Hartburn <D.J.Hartburn@kent.ac.uk> wrote: I think that is one thing I keep failing to get the correct way round with FreeRADIUS, you do not do 'if (do something)', you do something then check the result with an if.
Yes. It's not a real language, and there are no functions. Which makes it a bit weird.
Once you are in the right mind set, it does make some quite neat and tidy configs.
It is not quite working though, do you think I'm specifying my file correctly? It certainly seems to be reading it in, running with -X: # Loading module "eduroam_static_ip" from file /etc/raddb-kent/mods-enabled/files files eduroam_static_ip { usersfile = "/etc/raddb-kent/eduroam_static_ip" key = "%{Calling-Station-ID}" } ..... # Instantiating module "eduroam_static_ip" from file /etc/raddb-kent/mods-enabled/files reading pairlist file /etc/raddb-kent/eduroam_static_ip
Then during an auth test: (10) eduroam_static_ip: EXPAND %{Calling-Station-ID} (10) eduroam_static_ip: --> 42-42-42-42-42-42 (10) [eduroam_static_ip] = noop
Which means it didn't match.
(10) if (ok) { (10) if (ok) -> FALSE
I had tried following closely the MacAuth guide on the wiki (https://wiki.freeradius.org/guide/mac-auth), so I added the Reply-To after my MACs just to see if having an attribute in there made a difference. With a few different formats thrown in, that now reads: # eduroam_static_ip # # Contains a list of MAC addresses to be assigned to a particular VLAN # so they can obtain a static IP address. 42-42-42-42-42-42 Reply-Message = "Moooo" 424242424242 Reply-Message = "Quack" '42-42-42-42-42-42'
You should't need (or use) quotes.
Reply-Message = "Oink" "42-42-42-42-42-42" Reply-Message = "Woof"
I was expecting only the first one to work, but it is still failing to match.
Again, reading the FULL debug log helps. Maybe the Calling-Station-Id has spaces in it? Alan DeKok.
On Wed, Nov 02, 2016 at 12:40:28PM +0000, David Hartburn wrote:
Build a better database infrastructure is one solution, but I was wondering if there is a better way of doing this?
Being such a small dataset, is it possible to maintain an array or list,
For a couple of MAC addresses, and assuming they don't change often, then personally I'd just chuck them in a text file and use rlm_files. Matthew -- Matthew Newton, Ph.D. <mcn4@leicester.ac.uk> Systems Specialist, Infrastructure Services, I.T. Services, University of Leicester, Leicester LE1 7RH, United Kingdom For IT help contact helpdesk extn. 2253, <ithelp@le.ac.uk>
participants (4)
-
Alan DeKok -
David Hartburn -
Matthew Newton -
Phil Mayers