rlm_rest: Adding additional parameters

Alan DeKok aland at deployingradius.com
Tue Mar 1 13:03:29 UTC 2022


On Mar 1, 2022, at 7:44 AM, Rens Houben via Freeradius-Users <freeradius-users at lists.freeradius.org> wrote:
> I've got a FreeRADIUS setup that's working well - the RADIUS server calls a REST API to handle access requests, which connects to a database that's administered via a web frontend. Smooth sailing, and has been for several years.

  That's good.

> However, due to circumstances involving the company that supplied (and supplies the support for) our core routers going out of the router biz we've had to acquire new core routers from a different vendor... And, perhaps unsurprisingly, said vendor's hardware speaks a different dialect.

  Vendors... :(

> The good news, such as it is, is that with some judicious parallel naming the actual /values/ can stay the same, but the /attribute names/ will change. Worse (from my perspective), my manager would very much like it if, while both sets of core routers are connected to our network, a connection attempt could be handled by either type of router while only being a single "Connection" entry in the frontend.
> 
> Thankfully, I'm - if I say so myself - a fairly decent programmer and I've been able to rewrite the code logic so that the getAttributes() call (which creates the json dictionary that is then sent back by the REST API as the response) takes a 'vendor' parameter which pertinent parts use to determine how to respond -- IE, for a certain part, getAttributes('Ericsson') will yield '{'Qos-Metering-Profile-Name': 'test-down', 'Qos-Policing-Profile-Name': 'test-up'}' whereas getAttributes('ERX') yields '{'ERX-Ingress-Policy-Name': 'test-up', 'ERX-Egress-Policy-Name': 'test-down'}' 

  Why do that?  Just keep the functions / logic / web / REST stuff the same.  And fix it all up in FreeRADIUS.  But if your current function works, it may be best to just leave it.

> This part works and has been tested, but what I now need is to find a good way to /supply/ that 'Vendor' parameter to the function.

  %{client:vendor} 

  There's no "vendor" field in the "client" definition?  Meh.  Just add one:

client foo {
	ipaddr = 1.2.3.4
	secret = woo
	vendor = juniper
}

  You can put pretty much anything you want into the "client" definition, so long as it doesn't conflict with an existing config item.

> I've already restructured the FreeRADIUS config to use virtual servers so that I'll be able to use a different processing path depending on which client is asking, but I'm currently blanking on how best to add a 'Vendor=<...>' attribute to the REST request. 

  See above.  It's pretty simple.

> I'd prefer to do that in the authorize{} function but I'm not 100% sure if I can just use update{} to add an arbitrary variable to the request.

  You can do that, too.  Create a "Local-Vendor-Name" attribute in raddb/dictionary, and assign it values in an "update" section.  Then use it like anything else.

> Worst case, which I'd prefer to avoid, I could just create two different copies of rlm_rest, one for the Ericssons and one for the ERXen and send them to different entry points in the REST API, but that'd require a whole lot more code duplication than I'm comfortable with.

  Yeah, there's no need to do that.

  Alan DeKok.



More information about the Freeradius-Users mailing list