FreeRadius Virtual Servers w different user lists working, but it ain't pretty!



  • This applies to the package "freeradius2 1.7.6_2" running on pfSense 2.3.3-RELEASE.

    I have a setup with multiple WiFi AP's in which multiple SSIDs route users into multiple VLANs. I'm using FreeRadius for auth which works great. However, user access to the different SSIDs (and therefore VLANs) needs to be controlled separately as my APs (running DDWRT) don't support fancy NAS functions like VLAN tagging using FreeRadius.

    To make sure users cannot access SSIDs/VLANS they shouldn't I need to run multiple instances or virtual servers of FreeRadius. As the GUI does not support this (yet) some manual config changes is needed. Getting this up and running was easier than I imagined so I thought I should share as I assume others might run into this limitation of the FreeRadius GUI.

    Ideally this should be implemented in the GUI but I haven't looked into the process of doing GUI additions. I'm not sure how to best implement such a feature either.

    To the point.
    The "/usr/local/etc/raddb/radiusd.conf" file calls an "$INCLUDE sites-enabled/" at the very end.
    This calls every config in the "/usr/local/etc/raddb/sites-enabled" directory which contains symlinks to "/usr/local/etc/raddb/sites-available". On a fresh install this means only the "default" config.
    To define a new virtual server I copied the default config in sites-available. I chose to call it "visitors".
    I then created a symlink to "/usr/local/etc/raddb/sites-available/visitors" in "/usr/local/etc/raddb/sites-enabled".
    I also changed owner and permissions on the new config and the symlink to match the default config.
    To differentiate the virtual server from the default I then edited the "visitors" config adding a few lines.

    server visit {
            listen {
                    type = auth
                    ipaddr = 192.196.1.1
                    port = 1813
            }
    
    

    Adding the above to the very top of the file and closing the server section at the very end of the file ( note the the missing "}" in the code above).

    This defines the virtual server. I chose to run it on port 1813 as the default runs on 1812. The next step is to make the virtual server use a different user list than the default. I'm using basic file and clear-text but this other methods are defined similarly.
    I copied "/usr/local/etc/raddb/users" to "/usr/local/etc/raddb/users_visitors" and edited both files to match my needs.
    To make this new file available to the config I added a section to the very end of "/usr/local/etc/raddb/modules/files".

    files visit {
    	usersfile = ${confdir}/users_visitors
    }
    

    The last step was a bit tricky to figure out at first but in the end is fairly logical. I edited the "visitors" config and found the line "files" in the "authorize" section. If you're using text based user files like me, this is the default auth type. "files" in this case means "load the files" module which in it's turn loads the default "users" file. As I added a custom pointer as shown in the code block above, the "files" entry could be changed to "visit".

    I reloaded the radiusd service (service radiusd onerestart) and was a bit surprised that it actually worked as I hoped! :D

    Note that GUI changes normally overwrites configs and that updates to the package probably will mess up the manual changes. This shouldn't be any real problem as long as I don't mess around in the GUI or update FreeRadius without realising it…

    If anyone knows of a different/better way of going about this, please share.

    I think it would be really cool to be able to do this from the GUI in the future as well. Maybe a very basic version could be fairly easy to incorporate? Any ideas on how this could be implemented would be interesting to discuss.