Friday, July 25, 2014

Freeradius Access By SSID

I use the Meraki products for wireless and they were supposed to be the super-advanced-easy-interface-with-custom-configuration-no-issue APs with cloud manager, MDM, 600 horse power, 4wd, etc, etc.

If you need to setup a wireless network with a few SSIDs and all your users have the same access, then it works. If you also want to have your users limited to one device, it works too. But if you need certain users to have limited access and certain users to have regular access then good luck. The only option available on the Meraki system is to assign policies per device. Therefore, if you have devices that multiple users use, then you are out of luck.

I had an SSID set and then I configured a Freeradius server and everyone authenticated using the Radius server that connected to a MySQL database and pulled user info.

Since I work in a school, I wanted to have different access for Staff and different access for Students. The Meraki support team told me that it is not possible to assign policies on a per username basis even if you have Active Directory, LDAP or Radius.

So, after a lot of searching I figured out a way to do it through the Freeradius server. It turned out to be pretty simple in the end.

First in the policy.conf file you add the following:

rewrite_called_station_to_ssid {
                if (Called-Station-Id =~ /^([0-9a-f]{2})[-:]?([0-9a-f]{2})[-:.]?([0-9a-f]{2})[-:]?([0-9a-f]{2})[-:.]?([0-9a-f]{2})[-:]?([0-9a-f]{2})[-:]?([-a-$
                        update request {
                                Called-Station-Id := "%{1}%{2}%{3}%{4}%{5}%{6}"
                                Called-Station-SSID := "%{7}"
                        }
                }
                else {
                        noop
                }
        }
When the client sends an authorization request to the radius server, the packet has the attribute of Called-Station-Id and the value of the mac address of the AP then ":" and then the SSID that the user is trying to authenticate to. View here the complete instructions. So what that does is to split the value into the mac address of the AP and the SSID in two. The SSID is saved in the Called-Station-SSID.

Then in the dictionary file (it should be in the freeradius directory), add
ATTRIBUTE        Called-Station-SSID        3010                string
Then open up the file sites-enabled/default. In that file there are sections separated with {}. Find the section authorize and add
rewrite_called_station_id
after the preprocess.

Next add a table in your database with 2 columns; groupname and groupssid. Then add this to the file sites-enabled/default in the post_auth section:

if("%{sql:SELECT COUNT(*) FROM radusergroup,radgroupssid WHERE radusergroup.groupname = radgroupssid.groupname and radusergroup.username= '%{User-Name}' AND radusergroup.groupname='Staff' and radgroupssid.ssid= '%{Called-Station-SSID}'} >0"){
                ok
        }
        else {
                reject
        }
        sql

This assumes that you have freeradius configured with MySQL and your users belong in groups and that your controller sends the attribute Called-Station-Id as mentioned above. This will not allow access to SSIDs that you do not have listed in your database.

My Blog List