Help testing if a variable contains an IPv4
Alan DeKok
aland at deployingradius.com
Sat Jun 12 15:05:40 CEST 2021
On Jun 12, 2021, at 8:55 AM, David Herselman via Freeradius-Users <freeradius-users at lists.freeradius.org> wrote:
> I'm trying to allow non MFA logins from configuration revisioning systems where the target device doesn't support SSH key based authentication. I started constructing an unlang check using '<ipv4prefix>' and hit some quirks.
>
> Most of our devices include the calling station's source IP in their request, whilst a few send the reverse DNS lookup strings. How do I test if a variable matches the structure of an IPv4 IP?
It depends.
In RADIUS, attributes have a data type. Some are type "string", and others are type "ipaddr". The first one can contain an ASCII string which represents the *printed* form on an IP address. But it's not an IP address.
In contrast, the "ipaddr" data type is a 32-bit IPv4 address.
> My problem appears to be that '<ipv4prefix>&String < 41.0.0.0/29' returns true, for example:
Because an ASCII string isn't a 32-bit IPv4 address.
> (0) Calling-Station-Id = "oxidized.syrex.co.za"
> (0) if (&Client-Shortname == "core_routers") && !(&User-Name == "revisioncfg" && &Calling-Station-Id && <ipv4prefix>&Calling-Station-Id < 41.0.0.0/29) {
That won't work. What you're asking is for it to do a DNS lookup (generally a bad idea, too), and then compare the resulting IP address to the prefix.
What's actually happening is that it's casting the first 32-bits of the string to an IP address, and then checking that.
The solution is to copy the Calling-Station-ID to an attribute of type "ipaddr" first. e.g. Tmp-IP-Address-0. Then, compare that address to the prefix:
update request {
Tmp-IP-Address-0 := &Calling-Station-Id
}
if (<ipv4prefix>&Tmp-IP-Address-0 < 41.0.0.0/29) {
...
}
Alan DeKok.
More information about the Freeradius-Users
mailing list