On Jun 12, 2021, at 8:55 AM, David Herselman via Freeradius-Users <freeradius-users@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.