Nas-IP-Address regexp matching in hints/huntgroups working in 2.2.0 and not in 3.0.13
Hi, I'm configuring a Freeradius 3.0.13 server and I'm testing the configuration we have on a 2.2.0 Freeradius. On our 2.2.0 we've implemented some entries like the following one within the hints file: DEFAULT User-Name =~ "^(xx[e0][0-9]{3})$", NAS-IP-Address !~ "10\.10\.1\.11[89]$", NAS-IP-Address !~ "10\.10\.2\.(10|20)$" User-Name := "%{User-Name}@imp" (If you are wondering why we have multiple "NAS-IP-Address !~" on a single line is because we've reached the maximum length for the string passed to !~ and so we've split the string in multiple "NAS-IP-Address !~" blocks) The behavior we've implemented is: if username matches the regexp and NAS-IP-Address does not match any of the regexps on the same line, then add a realm to the username. The above configuration does not give any error but it does not work on 3.0.13. The same happens with huntgroups where regexp matching on NAS-IP-Address like the following one does not work anymore: brocade-fos NAS-IP-Address =~ "10\.10\.[18]8\.2[34]$" I've noticed that regexp matching within hints file works on User-Name, in fact the following cfg works and matches an access from user xx0123 when NAS-IP-Address is different from 10.10.1.118 and 10.10.1.254: DEFAULT User-Name =~ "^(fc[e0][0-9]{3})$", NAS-IP-Address != "10.10.1.118", NAS-IP-Address != "10.10.1.254" This solution is really much more verbose, because without regexp matching I would need to add tens of "NAS-IP-Address != x.x.x.x" entries (I don't know if there is a limit to their number) instead of using regexp to make the whole thing more compact. So my questions are: 1) should regexp matching work within hints and huntgroups file for NAS-IP-Address in 3.0.13 as it worked in 2.2.0? 2) if they do not work anymore, how should I implement "if you are user XXXX (with regexp) and the NAS-IP-Address is not one of the listed ones, then do User-Name manipulation? Best regards, Gianni Costanzi
On Dec 6, 2017, at 11:06 AM, Gianni Costanzi <gianni.costanzi@gmail.com> wrote:
Hi, I'm configuring a Freeradius 3.0.13 server and I'm testing the configuration we have on a 2.2.0 Freeradius.
On our 2.2.0 we've implemented some entries like the following one within the hints file:
DEFAULT User-Name =~ "^(xx[e0][0-9]{3})$", NAS-IP-Address !~ "10\.10\.1\.11[89]$", NAS-IP-Address !~ "10\.10\.2\.(10|20)$" User-Name := "%{User-Name}@imp"
Regexes on IP addresses are terrible...
(If you are wondering why we have multiple "NAS-IP-Address !~" on a single line is because we've reached the maximum length for the string passed to !~ and so we've split the string in multiple "NAS-IP-Address !~" blocks)
That's a v2 limitation. v3 has removed much of that.
The behavior we've implemented is: if username matches the regexp and NAS-IP-Address does not match any of the regexps on the same line, then add a realm to the username.
The above configuration does not give any error but it does not work on 3.0.13. The same happens with huntgroups where regexp matching on NAS-IP-Address like the following one does not work anymore:
Regular expressions are not supported for IP address in the "users" or "hints" or "huntgroups" file.
So my questions are: 1) should regexp matching work within hints and huntgroups file for NAS-IP-Address in 3.0.13 as it worked in 2.2.0?
No.
2) if they do not work anymore, how should I implement "if you are user XXXX (with regexp) and the NAS-IP-Address is not one of the listed ones, then do User-Name manipulation?
Use Unlang if ((User-Name =~ /regex/) && \ ((NAS-IP-Address =~ /regex/) || \ (NAS-IP-Address =~ /regex/) ... But realistically, if you have a list of IP addresses, it's better to put them into groups, and check the group. See "rlm_passwd", and "man rlm_passwd". You can create groups which match a list of addresses (no regex), and then just do group checking. Alan DeKok.
On Wed, Dec 6, 2017 at 5:11 PM, Alan DeKok <aland@deployingradius.com> wrote:
On Dec 6, 2017, at 11:06 AM, Gianni Costanzi <gianni.costanzi@gmail.com> wrote:
But realistically, if you have a list of IP addresses, it's better to put them into groups, and check the group. See "rlm_passwd", and "man rlm_passwd".
You can create groups which match a list of addresses (no regex), and then just do group checking.
Alan DeKok.
Thank you very much for the really quick answer, I'll give a look at the docs. The important thing is that I can match those groups within the hints file to implement my conditional User-Name manipulation, I'll hope docs will clarify my doubts (otherwise you'll read me soon :) ). Best regards, Gianni Costanzi
On Dec 6, 2017, at 11:22 AM, Gianni Costanzi <gianni.costanzi@gmail.com> wrote:
Thank you very much for the really quick answer, I'll give a look at the docs. The important thing is that I can match those groups within the hints file to implement my conditional User-Name manipulation, I'll hope docs will clarify my doubts (otherwise you'll read me soon :) ).
The point is that the "hints" and "huntgroups" file format is 25 years old. They shouldn't really be used by more. v3 has so much more functionality in "unlang" that it's usually better to just use that. Alan DeKok.
The point is that the "hints" and "huntgroups" file format is 25 years old. They shouldn't really be used by more.
v3 has so much more functionality in "unlang" that it's usually better to just use that.
Alan DeKok
You’re right, I’ll try to find the time to learn about unlang and understand where I should implement the wanted behavior.. I’m in a hurry with this activity and the first step was trying to make it work with the old Conf. I think it should not be a problem to do user manipulation with unlang instead of hints file, but I can I also set hunt groups with unlang in order to be able to match them within the users file? Btw huntgroups Management without regexps is not a big problem for us due to the small number of entries defined. Gianni
-- --< Sent from GMail mobile >--
Find me on LinkedIn: http://it.linkedin.com/in/giannicostanzi My blog: http://networkingpills.wordpress.com My best photos on 500px: http://500px.com/GianniCostanzi PGP Key Fingerprint: 2404 1798 E01F F6BF 0FA3 AA07 B6D5 040F 2EDD 456A --------------------------------------------------------------------------------------------------------------
On Dec 6, 2017, at 11:39 AM, Gianni Costanzi <gianni.costanzi@gmail.com> wrote:
You’re right, I’ll try to find the time to learn about unlang and understand where I should implement the wanted behavior.. I’m in a hurry with this activity and the first step was trying to make it work with the old Conf. I think it should not be a problem to do user manipulation with unlang instead of hints file, but I can I also set hunt groups with unlang in order to be able to match them within the users file?
No, but you can set another attribute in "unlang" and check it in the "users" file. See raddb/dictionary for instructions on creating local attributes. Create a "string" attribute with a name like "My-Group". Then, set it in unlang: update request { My-Group := "foo" } And check it in the "users" file: DEFAULT My-Group == "foo" ... Alan DeKok.
2) if they do not work anymore, how should I implement "if you are user XXXX (with regexp) and the NAS-IP-Address is not one of the listed ones, then do User-Name manipulation?
Use Unlang
if ((User-Name =~ /regex/) && \ ((NAS-IP-Address =~ /regex/) || \ (NAS-IP-Address =~ /regex/) ...
But realistically, if you have a list of IP addresses, it's better to put them into groups, and check the group. See "rlm_passwd", and "man rlm_passwd".
You can create groups which match a list of addresses (no regex), and then just do group checking.
Alan DeKok.
Hi Alan, I was thinking about what you've told me yesterday.. I think that matching NAS-IP-Addresses in order to set a specific "group" attribute as you've suggested can work to replace the huntgroups logic I'm using in the old Freeradius 2.2.0 config.. If I've understood well, implementing the hints' file logic I'm using in 2.2.0 must be done with Unlang, so the following hints code DEFAULT User-Name =~ "^(xx[e0][0-9]{3})$", NAS-IP-Address !~ "10\.10\.1\.11[89]$", NAS-IP-Address !~ "10\.10\.2\.(10|20)$" User-Name := "%{User-Name}@imp" should become this Unlang code: if (User-Name =~ /^(xx[e0][0-9]{3})$/) \ && NAS-IP-Address !~ /10\.10\.1\.11[89]$/ \ && NAS-IP-Adddress !~ /10\.10\.2\.(10|20)$/) { User-Name := "%{User-Name}@imp" } If this should work, I still don't know in which configuration file I should put this code in order to manipulate the User-Name in the preprocessing step, before authentication on SQL/files happens. Best regards, Gianni Costanzi
authorize section of the default virtual server for a vanilla install. AFTER the modules that service the request but before the first calls to eg pap and EAP etc alan On 7 Dec 2017 3:35 pm, "Gianni Costanzi" <gianni.costanzi@gmail.com> wrote:
2) if they do not work anymore, how should I implement "if you are user XXXX (with regexp) and the NAS-IP-Address is not one of the listed ones, then do User-Name manipulation?
Use Unlang
if ((User-Name =~ /regex/) && \ ((NAS-IP-Address =~ /regex/) || \ (NAS-IP-Address =~ /regex/) ...
But realistically, if you have a list of IP addresses, it's better to put them into groups, and check the group. See "rlm_passwd", and "man rlm_passwd".
You can create groups which match a list of addresses (no regex), and then just do group checking.
Alan DeKok.
Hi Alan, I was thinking about what you've told me yesterday.. I think that matching NAS-IP-Addresses in order to set a specific "group" attribute as you've suggested can work to replace the huntgroups logic I'm using in the old Freeradius 2.2.0 config..
If I've understood well, implementing the hints' file logic I'm using in 2.2.0 must be done with Unlang, so the following hints code
DEFAULT User-Name =~ "^(xx[e0][0-9]{3})$", NAS-IP-Address !~ "10\.10\.1\.11[89]$", NAS-IP-Address !~ "10\.10\.2\.(10|20)$" User-Name := "%{User-Name}@imp"
should become this Unlang code:
if (User-Name =~ /^(xx[e0][0-9]{3})$/) \ && NAS-IP-Address !~ /10\.10\.1\.11[89]$/ \ && NAS-IP-Adddress !~ /10\.10\.2\.(10|20)$/) { User-Name := "%{User-Name}@imp" }
If this should work, I still don't know in which configuration file I should put this code in order to manipulate the User-Name in the preprocessing step, before authentication on SQL/files happens.
Best regards, Gianni Costanzi - List info/subscribe/unsubscribe? See http://www.freeradius.org/ list/users.html
On Thu, Dec 7, 2017 at 6:24 PM, Alan Buxey <alan.buxey@gmail.com> wrote:
authorize section of the default virtual server for a vanilla install. AFTER the modules that service the request but before the first calls to eg pap and EAP etc
alan
if (User-Name =~ /^(xx[e0][0-9]{3})$/) \ && NAS-IP-Address !~ /10\.10\.1\.11[89]$/ \ && NAS-IP-Adddress !~ /10\.10\.2\.(10|20)$/) { User-Name := "%{User-Name}@imp" }
If this should work, I still don't know in which configuration file I should put this code in order to manipulate the User-Name in the preprocessing step, before authentication on SQL/files happens.
Best regards, Gianni Costanzi
Hi, I've tried to add the following code within authorize section of default virtual server, just after the preprocess directive: preprocess if (&User-Name =~ /^AAAAA$/) { update request { &User-Name := "BBBBB" } } It seems to work (radius debug says noop for that block of code but the User-Name is correctly translated from AAAA to BBBB). So I've tried to implement the code I need to replicate what I was using in older Freeradius: if (&User-Name =~ /^(xx[e0][0-9]{3})$/ \ && NAS-IP-Address !~ /REGEXP/ \ && NAS-IP-Address !~ /REGEXP/ \ && NAS-IP-Address !~ /REGEXP/ \ [...] && NAS-IP-Address !~ /REGEXP/ \ && NAS-IP-Address !~ /REGEXP/ { update request { &User-Name := "%{User-Name}@myrealm" } } The problem now is that there are too many conditions and radius server does not start: including configuration file /etc/raddb/sites-enabled/default /etc/raddb/sites-enabled/default[273]: Reference "(&User-Name =~ /^(xx[e0][0-9]{3})$/ && NAS-IP-Address !~ [...] [...]&& NAS-IP-Address !~ /REGEXP/ ) " is too long Failed expanding section name /etc/raddb/sites-enabled/default[326]: Failed allocating memory for section Errors reading or parsing /etc/raddb/radiusd.conf If I reduce the number of "&& NAS-IP-Address" rows it works. I'd like to implement the following work-around code, splitting the check of NAS-IP-Addresses in multiple If blocks, but I need your help to tell me if and how I can set a temporary variable match_found: if (&User-Name =~ /^(xx[e0][0-9]{3})$/) { match_found = 0 if (NAS-IP-Address =~ /REGEXP/ \ && NAS-IP-Address =~ /REGEXP/ \ && NAS-IP-Address =~ /REGEXP/ \) { match_found = 1 } [...] if (NAS-IP-Address =~ /REGEXP/ \ && NAS-IP-Address =~ /REGEXP/ \ && NAS-IP-Address =~ /REGEXP/ \) { match_found = 1 } if (match_found == 0) { update request { &User-Name := "%{User-Name}@myrealm" } } } The logic would be the same, change the Username only if it matches the username regexp and does not match any of the NAS-IP-Address regexps. Can I allocate a temporary variable like match_found? It doesn't work as I've written above (/etc/raddb/sites-enabled/default[273]: Errors parsing authorize section.). Furthermore, could I have the same "memory allocation for section" error even with the code above? I don't know how radius is working behind the scenes with this Unlang code, so I need your help. Best regards, thank you in advance for any help Gianni Costanzi
On Dec 15, 2017, at 6:29 AM, Gianni Costanzi <gianni.costanzi@gmail.com> wrote:
So I've tried to implement the code I need to replicate what I was using in older Freeradius:
if (&User-Name =~ /^(xx[e0][0-9]{3})$/ \ && NAS-IP-Address !~ /REGEXP/ \ && NAS-IP-Address !~ /REGEXP/ \ && NAS-IP-Address !~ /REGEXP/ \ [...] && NAS-IP-Address !~ /REGEXP/ \ && NAS-IP-Address !~ /REGEXP/ { update request { &User-Name := "%{User-Name}@myrealm" } }
The problem now is that there are too many conditions and radius server does not start:
As I suggested earlier... see "man rlm_passwd". You can create local groups for the NASes. i.e. instead of listing masses of regular expressions, just create a simple flat file with (a) the IP of the NAS, and (b) the group it should belong to. You can create a local "NAS-Group" attribute. See the rlm_passwd documentation for examples. Then in the "authorize" section, do: if ((User-Name =~ /regex/) && (NAS-Group == "foo")) { ... }
If I reduce the number of "&& NAS-IP-Address" rows it works.
Using groups is simpler than large numbers of if / then / else conditions. Alan DeKok.
On Fri, Dec 15, 2017 at 12:42 PM, Alan DeKok <aland@deployingradius.com> wrote:
On Dec 15, 2017, at 6:29 AM, Gianni Costanzi <gianni.costanzi@gmail.com> wrote:
So I've tried to implement the code I need to replicate what I was using in older Freeradius:
if (&User-Name =~ /^(xx[e0][0-9]{3})$/ \ && NAS-IP-Address !~ /REGEXP/ \ && NAS-IP-Address !~ /REGEXP/ \ && NAS-IP-Address !~ /REGEXP/ \ [...] && NAS-IP-Address !~ /REGEXP/ \ && NAS-IP-Address !~ /REGEXP/ { update request { &User-Name := "%{User-Name}@myrealm" } }
The problem now is that there are too many conditions and radius server does not start:
As I suggested earlier... see "man rlm_passwd". You can create local groups for the NASes.
i.e. instead of listing masses of regular expressions, just create a simple flat file with (a) the IP of the NAS, and (b) the group it should belong to. You can create a local "NAS-Group" attribute. See the rlm_passwd documentation for examples.
Then in the "authorize" section, do:
if ((User-Name =~ /regex/) && (NAS-Group == "foo")) { ... }
If I reduce the number of "&& NAS-IP-Address" rows it works.
Using groups is simpler than large numbers of if / then / else conditions.
Alan DeKok.
Thank you very much, I think I've understood now the whole picture, I should be able to implement what I need with the passwd module (it seems to work, looking at the first tests I've done). I still don't understand when I should use &User-Name and when User-Name, since both seem to work, but I need to read the manuals with more attention (Always being in a hurry doesn't help).
Have a nice weekend Gianni
participants (3)
-
Alan Buxey -
Alan DeKok -
Gianni Costanzi