Help testing if a variable contains an IPv4

David Herselman dhe at syrex.co
Sat Jun 12 19:11:52 CEST 2021


Hi Alan,

Many thanks, the following now works as expected:

(1)   Calling-Station-Id = "oxidized.syrex.co.za"
(1)       update request {
(1)         Tmp-IP-Address-0 := &Calling-Station-Id -> 41.0.0.5
(1)       } # update request = noop
(1)       if ((&Client-Shortname == "isp_core") && !(&User-Name == "revisioncfg" && &Tmp-IP-Address-0 && <ipv4prefix>&Tmp-IP-Address-0 < 41.0.0.0/29)) {
(1)       EXPAND &Client-Shortname
(1)          --> isp_core
(1)       if ((&Client-Shortname == "isp_core") && !(&User-Name == "revisioncfg" && &Tmp-IP-Address-0 && <ipv4prefix>&Tmp-IP-Address-0 < 41.0.0.0/29))  -> FALSE

(32)   Calling-Station-Id = "197.91.242.47"
(32)       update request {
(32)         Tmp-IP-Address-0 := &Calling-Station-Id -> 197.91.242.47
(32)       } # update request = noop
(32)       if ((&Client-Shortname == "isp_core") && !(&User-Name == " revisioncfg" && &Tmp-IP-Address-0 && <ipv4prefix>&Tmp-IP-Address-0 < 41.0.0.0/29)) {
(32)       EXPAND &Client-Shortname
(32)          --> isp_core
(32)       if ((&Client-Shortname == "isp_core") && !(&User-Name == " revisioncfg" && &Tmp-IP-Address-0 && <ipv4prefix>&Tmp-IP-Address-0 < 41.0.0.0/29))  -> TRUE

What it however does allow is for someone to set a DNS PTR record for their source IP as a hostname that would resolve to an IP in the 41.0.0.0/29 subnet. I presume I should limit validation to numeric values only by first validating Calling-Station-Id =~ /^\d{1,3}(\.\d{1,3}){3}$/ ?


Regards
David Herselman


-----Original Message-----
From: Freeradius-Users <freeradius-users-bounces+dhe=syrex.co at lists.freeradius.org> On Behalf Of Alan DeKok
Sent: Saturday, 12 June 2021 3:06 PM
To: FreeRadius users mailing list <freeradius-users at lists.freeradius.org>
Subject: Re: Help testing if a variable contains an IPv4

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.


-
List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html



More information about the Freeradius-Users mailing list