FreeRADIUS policy to restrict certain users trying to log on a specific device

freeradius

What I have:
freeradius 2.1.10 on debian, configured to use a database.

How it works now:
There are many devices on the network and users, the users log on devices to configure them and so on. The users can log on to anything. For example some devices (ciscos) the user account on radius comes along with privileges (cisco-avpair attribute) that restrict what that individual can and cannot do on cisco devices.

What I want freeradius to do in addition, for a specific special case:
There's a special device that only select users should be able to authenticate into. Everyone else should be just denied access. (so, more strict than the cisco example above).

What I think I should be doing is first define my own attribute for example company-special-privilege so that I can set that for some users in the database with a value of 0 or 1. Then define some policy in policy.conf.

What I'm asking:
Never done policies and I don't understand where they're applied in the rest of the freeradius config (where should I put my special_access policy).
Also unsure how to formulate it but the following pseudocode should represent what I want:

special_access {
    if (request to log in $special_device_ip) {
        if ($username company-special-privilege) {
            reject #
        }
    }
}

From the above I don't know how to get the device IP or the attribute that the user is set with. I'm not doing a == 1 on the attribute in the second condition in case the user doesn't have the attribute as I don't know what that would imply but any user that doesn't have 1 must be rejected.

Best Answer

You should put it in raddb/policy.conf inside the policy {} stanza. Then they can be referenced (by their name) as you would a normal module, in authorize, authenticate, post-auth etc...

Policies in FreeRADIUS are essentially macros, they're not functions, they don't take arguments.

Defining a special attribute to control policy decisions is fine, do it in raddb/dictionary unless you have an IANA number and want to spin your own custom dictionary. An easier way may just be to query SQL directly.

I'm not sure what you want to do specifically, but here's an example that may help... Modify as necessary

special_access {
    if ("%{Called-Station-ID}" == 'special device') {
        if ("%{sql:SELECT special_priv FROM table WHERE username = '%{User-Name}'}" != '1') {
            reject
        }
    }
}
Related Topic