Applying the same rule to multiple values in an attribute/config value
Howdy! So, we're reviving the old RFC7542 chestnut because we've found that there is appetite for it. The basic policy for it is done, but a question was raised about the capability to apply the functionality to multiple realms. The basics are this: if (&request:User-Name =~ /([a-zA-Z0-9\.-]+)!([a-zA-Z0-9\.-]*)\@(.+)/) { # Store the three parts of the User-Name, store the original User-Name too update control { RFC7542-User-Name := &User-Name } # Format: not_local_realm!...@local_realm: Rewrite User-Name for suffix if (("%{1}" != "${policy.rfc7542_suffix}") && ("%{3}" == "${policy.rfc7542_suffix}")) { update request { User-Name := "%{2}@%{1}" } } # Format: local_realm!...@not_local_realm: Rewrite User-Name for suffix if (("%{1}" == "${policy.rfc7542_suffix}") && ("%{3}" != "${policy.rfc7542_suffix}")) { update request { User-Name := "%{2}@%{1}" } } # end of if suffix # Restore the User-Name to its original glory. if (&control:RFC7542-User-Name && (&request:User-Name != &control:RFC7542-User-Name)) { update request { User-Name := &control:RFC7542-User-Name } update control { RFC7542-User-Name !* ANY } } The question now is the '$policy.rfc7542_suffix' bit. This is currently just defined as a simple value, i.e. 'blahblah.realm'. If we were to define it as a multiple value (semicolon-separated), would it make sense to use a foreach() loop across it, turn each entry into a variable and just check if the value is contained in the regex? The worry I have here is that there's a lot of processing to do, a lot of looping, and if the powers that be (Alan, Arran, Matthew et al) have a better suggestion, I'd love to hear it. Please remember, this is for 3.0.x, with looking at upstreaming this to you guys to give FR RFC7542 capabilities. I await your suggestions :-) With Regards Stefan Paetow Consultant, Trust and Identity t: +44 (0)1235 822 125 gpg: 0x3FCE5142 xmpp: stefanp@jabber.dev.ja.net skype: stefan.paetow.janet jisc.ac.uk Jisc is a registered charity (number 1149740) and a company limited by guarantee which is registered in England under Company No. 5747339, VAT No. GB 197 0632 86. Jisc’s registered office is: One Castlepark, Tower Hill, Bristol, BS2 0JA. T 0203 697 5800.
On Feb 11, 2019, at 11:41 AM, Stefan Paetow <Stefan.Paetow@JISC.AC.UK> wrote:
So, we're reviving the old RFC7542 chestnut because we've found that there is appetite for it. The basic policy for it is done, but a question was raised about the capability to apply the functionality to multiple realms.
RFC 7542 doesn't allow for multiple realms in an NAI. Section 3.3.1 explicitly recommends against this: In RADIUS-based environments, the use of decorated NAI is NOT RECOMMENDED for the following reasons: ... lots and lots ...
The basics are this:
if (&request:User-Name =~ /([a-zA-Z0-9\.-]+)!([a-zA-Z0-9\.-]*)\@(.+)/) { # Store the three parts of the User-Name, store the original User-Name too update control { RFC7542-User-Name := &User-Name }
The RFC 7542 format is "utf8-username@utf8-realm". The "utf8-realm" portion is pretty much a valid DNS domain name. The "utf8-username" is opaque, and has no meaning outside of the "owning" domain. As for the FR config ,the whole rewrite / suffix / re-write back thing should be avoided. If you are going to mark up the "utf8-username" portion with routing information, it's best to modify the "suffix" module configuration. i.e. pick out the realm you want to use, and look that up. Don't munge the User-Name.
The question now is the '$policy.rfc7542_suffix' bit. This is currently just defined as a simple value, i.e. 'blahblah.realm'. If we were to define it as a multiple value (semicolon-separated), would it make sense to use a foreach() loop across it, turn each entry into a variable and just check if the value is contained in the regex?
I'm not sure what you're trying to do here...
The worry I have here is that there's a lot of processing to do, a lot of looping, and if the powers that be (Alan, Arran, Matthew et al) have a better suggestion, I'd love to hear it. Please remember, this is for 3.0.x, with looking at upstreaming this to you guys to give FR RFC7542 capabilities.
FreeRADIUS already supports RFC 7542. That RFC largely documents prior practices going back to 1996. It doesn't really define anything new, other than saying "don't use decorated NAIs". So I'm not clear what you're doing here, or why. Why is there a need to mangle the User-Name? Is it to add realm routing information? See RFC 7542 Section 3.3.1 for reasons why explicit routing paths are problematic: https://tools.ietf.org/html/rfc7542#section-3.3.1 Alan DeKok.
Hang on Alan, In 2016 you wrote this:
FreeRADIUS server must be able to handle the standard RFC4282 NAI, and authenticate NAIs that are local to it. The inner identity obviously remains the standard NAI for the real home realm, unless someone else has a better idea:
The inner user-name is always either unqualified ("bob'), or qualified with a local domain name. : :
Scenario 2: Outer = realhome.realm!username@intermediate.realm. Route on to 'realhome.realm'. Authenticate locally at 'realhome.realm'.
The key here is *who does this*.
If you have "realm1!user@realm2", then the packet MUST be routed by third parties to "realm2". Because it is the domain name which appears after the "@". "realm2" then notices that the user portion is in a special format. A format which it understands. The AAA server for "realm2" can then decompose the "realm1!user" string into "realm1" and "user". And then re-compose it into "user@realm1". At which point the AAA server for "realm2" can forward the packet to "user@realm1". : :
The existing "realm" module isn't smart enough to do this kind of double lookup. Though I suppose it shouldn't be too hard to add (hint hint). Just have it check for a realm, and if the realm is local, do *another* check for realm on the user portion.
It can be done manually in "unlang". But it means replicating the logic in rlm_realm, and re-writing it unlang statements.
So, this is what we've done in the end.
So, we're reviving the old RFC7542 chestnut because we've found that there is appetite for it. The basic policy for it is done, but a question was raised about the capability to apply the functionality to multiple realms.
RFC 7542 doesn't allow for multiple realms in an NAI. Section 3.3.1 explicitly recommends against this:
It doesn't explicitly forbid it, it recommends against it (and I totally get the reasons why this should be avoided). However, Section 3.3.1 of the RFC uses exactly that kind of example, but explains that the username must be rewritten to the standard NAI format sans decoration. That was what I still had to figure out (or try and get away with non-standard unlang processing to make sure that it didn't start looping).
As for the FR config ,the whole rewrite / suffix / re-write back thing should be avoided. If you are going to mark up the "utf8-username" portion with routing information, it's best to modify the "suffix" module configuration.
Ok, I'll look at that again and see what can be done, but I'm not sure whether that's allowed if the EAP identity is originally set to 'home.realm!anonymous@another.realm'. Suffix doesn't rewrite that, does it?
i.e. pick out the realm you want to use, and look that up. Don't munge the User-Name.
There was no objection in 2016, but I'll take your point. :-)
If we were to define it as a multiple value (semicolon-separated), would it make sense to use a foreach() loop across it, turn each entry into a variable and just check if the value is contained in the regex?
I'm not sure what you're trying to do here...
Ok, the way the current unlang is written is that it uses *one* value in an if statement. If I now provide a list of values i.e. the configuration option rfc7542_suffix is defined as say 'realm1.org;realm2.net;local.realm', how can I do a simple "check the regex against what's defined in that list"? Of course if the 'suffix' module configuration allows me to work with the realms I have defined in proxy.conf, then the point is moot, but if not... I'll have to construct a loop of sorts, no? But does foreach() work on configuration items? I don't think so?
So I'm not clear what you're doing here, or why. Why is there a need to mangle the User-Name? Is it to add realm routing information?
The original User-Name has 'routing information' (i.e. 'home.realm!anonymous@another.realm'). The EAP identity has the same set (because it's an EAP conversation). We 'munge' the User-Name to 'anonymous@home.realm' to get suffix to route it correctly. Then, to avoid the 'Identity does not match User-Name. Setting from EAP identity' error message, we restore the User-Name to what it was before routing, i.e. 'home.realm!anonymous@another.realm'. On the target system, the same happens, but at that point, the target system identifies that 'home.realm!anonymous@another.realm' is destined to itself and everything in the rest of the conversation stays the same. One thing that I *have* forgotten is that RFC 7542 says that the inner identity MUST NOT be decorated. That's what I failed to do... I'll have to revisit this.
See RFC 7542 Section 3.3.1 for reasons why explicit routing paths are problematic:
I am aware of these reasons, yes. We know they are problematic, but again, given that this is the only way to say 'You MUST go there first' (which stems from a FR conversation in 2016 where I asked this and was told to read the RFC in question and then started a discussion on the list about it), this is what we have... I hope this helps? Stefan Paetow Consultant, Trust and Identity t: +44 (0)1235 822 125 gpg: 0x3FCE5142 xmpp: stefanp@jabber.dev.ja.net skype: stefan.paetow.janet jisc.ac.uk Jisc is a registered charity (number 1149740) and a company limited by guarantee which is registered in England under Company No. 5747339, VAT No. GB 197 0632 86. Jisc’s registered office is: One Castlepark, Tower Hill, Bristol, BS2 0JA. T 0203 697 5800.
On Feb 11, 2019, at 5:48 PM, Stefan Paetow <Stefan.Paetow@JISC.AC.UK> wrote:
Hang on Alan,
In 2016 you wrote this:
Quoting my own words against me. That's a winning tactic. :)
So, this is what we've done in the end.
OK.
As for the FR config ,the whole rewrite / suffix / re-write back thing should be avoided. If you are going to mark up the "utf8-username" portion with routing information, it's best to modify the "suffix" module configuration.
Ok, I'll look at that again and see what can be done, but I'm not sure whether that's allowed if the EAP identity is originally set to 'home.realm!anonymous@another.realm'. Suffix doesn't rewrite that, does it?
The Suffix module doesn't rewrite the User-Name, or the EAP identity. There's also the issue that re-writing User-Name without changing EAP identity is bad. Most servers (including FreeRADIUS) will reject such packets.
i.e. pick out the realm you want to use, and look that up. Don't munge the User-Name.
There was no objection in 2016, but I'll take your point. :-)
That's for non-EAP authentication, unfortunately.
Ok, the way the current unlang is written is that it uses *one* value in an if statement. If I now provide a list of values i.e. the configuration option rfc7542_suffix is defined as say 'realm1.org;realm2.net;local.realm', how can I do a simple "check the regex against what's defined in that list"? Of course if the 'suffix' module configuration allows me to work with the realms I have defined in proxy.conf, then the point is moot, but if not... I'll have to construct a loop of sorts, no? But does foreach() work on configuration items? I don't think so?
"foreach" doesn't work on configuration items. You shouldn't need it though. The idea being intermediate routing is that each stage only takes care of *one* realm. It's not really good to say "here's a list of realms, pick one". IIRC, 802.11u does that for realm selection, but it's rather a bit different.
So I'm not clear what you're doing here, or why. Why is there a need to mangle the User-Name? Is it to add realm routing information?
The original User-Name has 'routing information' (i.e. 'home.realm!anonymous@another.realm'). The EAP identity has the same set (because it's an EAP conversation). We 'munge' the User-Name to 'anonymous@home.realm' to get suffix to route it correctly. Then, to avoid the 'Identity does not match User-Name. Setting from EAP identity' error message, we restore the User-Name to what it was before routing, i.e. 'home.realm!anonymous@another.realm'.
On the target system, the same happens, but at that point, the target system identifies that 'home.realm!anonymous@another.realm' is destined to itself and everything in the rest of the conversation stays the same.
OK. But I'm still not clear why there's a list of realms separated by semicolons.
One thing that I *have* forgotten is that RFC 7542 says that the inner identity MUST NOT be decorated. That's what I failed to do... I'll have to revisit this.
See RFC 7542 Section 3.3.1 for reasons why explicit routing paths are problematic:
I am aware of these reasons, yes. We know they are problematic, but again, given that this is the only way to say 'You MUST go there first' (which stems from a FR conversation in 2016 where I asked this and was told to read the RFC in question and then started a discussion on the list about it), this is what we have...
I hope this helps?
Sure. Alan DeKok.
The Suffix module doesn't rewrite the User-Name, or the EAP identity.
There's also the issue that re-writing User-Name without changing EAP identity is bad. Most servers (including FreeRADIUS) will reject such packets.
Indeed. Hence the 'munging' of the User-Name (to ensure EAP Identity and User-Name are identical to the end).
That's for non-EAP authentication, unfortunately.
Right.
"foreach" doesn't work on configuration items. You shouldn't need it though. The idea being intermediate routing is that each stage only takes care of *one* realm. It's not really good to say "here's a list of realms, pick one".
Ok.
On the target system, the same happens, but at that point, the target system identifies that 'home.realm!anonymous@another.realm' is destined to itself and everything in the rest of the conversation stays the same. OK. But I'm still not clear why there's a list of realms separated by semicolons.
Ok, assume I have three realms defined in proxy.conf: 'my.realm', 'another.realm', and 'yet.another'. To make the comparison easier, I don't want to have my users extend the comparison from this (which only handles one realm, defined in 'rfc7542_suffix'): if (("%{1}" == "${policy.rfc7542_suffix}") && ("%{3}" != "${policy.rfc7542_suffix}")) { : : } To this (apologies for the pseudo-code): if ((("%{1}" == "my.realm") && ("%{3}" != "my.realm")) || \ (("%{1}" == "another.realm") && ("%{3}" != "another.realm")) || \ (("%{1}" == "yet.another") && ("%{3}" != "yet.another")) { If I could construct a loop that iterates over my realms, then I could simply do the comparison, but you've given me an idea (i.e. defining a new 'realm' instance that uses the bang to route): realm bang_realm { format = prefix delimiter = "!" } if (&request:User-Name =~ /([a-zA-Z0-9\.-]+)!([a-zA-Z0-9\.-]*)\@(.+)/) { # Format: not_local_realm!...@local_realm: Rewrite User-Name for suffix bang_realm } else { suffix } Does that (or something similar) make more sense? :-) If so, I'll test this and see what we get. It still leaves the EAP identity and the outer User-Name decorated though. :-/ With Regards Stefan Paetow Consultant, Trust and Identity t: +44 (0)1235 822 125 gpg: 0x3FCE5142 xmpp: stefanp@jabber.dev.ja.net skype: stefan.paetow.janet jisc.ac.uk Jisc is a registered charity (number 1149740) and a company limited by guarantee which is registered in England under Company No. 5747339, VAT No. GB 197 0632 86. Jisc’s registered office is: One Castlepark, Tower Hill, Bristol, BS2 0JA. T 0203 697 5800.
On Feb 11, 2019, at 6:27 PM, Stefan Paetow <Stefan.Paetow@JISC.AC.UK> wrote:
If I could construct a loop that iterates over my realms, then I could simply do the comparison, but you've given me an idea (i.e. defining a new 'realm' instance that uses the bang to route):
realm bang_realm { format = prefix delimiter = "!" }
Yes, that's better.
if (&request:User-Name =~ /([a-zA-Z0-9\.-]+)!([a-zA-Z0-9\.-]*)\@(.+)/) { # Format: not_local_realm!...@local_realm: Rewrite User-Name for suffix bang_realm } else { suffix }
Does that (or something similar) make more sense? :-)
Yes.
If so, I'll test this and see what we get. It still leaves the EAP identity and the outer User-Name decorated though. :-/
Well, there isn't much choice there. Alan DeKok.
So, Alan, What would you like me to call that new realm configuration (if I were to want to submit this upstream)? bangrealm? bang_realm? Gimme a name and I'll submit an upstream PR for the new realm entry :-) With Regards Stefan Paetow Consultant, Trust and Identity t: +44 (0)1235 822 125 gpg: 0x3FCE5142 xmpp: stefanp@jabber.dev.ja.net skype: stefan.paetow.janet jisc.ac.uk Jisc is a registered charity (number 1149740) and a company limited by guarantee which is registered in England under Company No. 5747339, VAT No. GB 197 0632 86. Jisc’s registered office is: One Castlepark, Tower Hill, Bristol, BS2 0JA. T 0203 697 5800. On 12/02/2019, 15:34, "Freeradius-Users on behalf of Alan DeKok" <freeradius-users-bounces+stefan.paetow=jisc.ac.uk@lists.freeradius.org on behalf of aland@deployingradius.com> wrote: On Feb 11, 2019, at 6:27 PM, Stefan Paetow <Stefan.Paetow@JISC.AC.UK> wrote: > If I could construct a loop that iterates over my realms, then I could simply do the comparison, but you've given me an idea (i.e. defining a new 'realm' instance that uses the bang to route): > > realm bang_realm { > format = prefix > delimiter = "!" > } Yes, that's better. > if (&request:User-Name =~ /([a-zA-Z0-9\.-]+)!([a-zA-Z0-9\.-]*)\@(.+)/) { > # Format: not_local_realm!...@local_realm: Rewrite User-Name for suffix > bang_realm > } else { > suffix > } > > Does that (or something similar) make more sense? :-) Yes. > If so, I'll test this and see what we get. It still leaves the EAP identity and the outer User-Name decorated though. :-/ Well, there isn't much choice there. Alan DeKok. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
On Tue, 2019-02-12 at 15:54 +0000, Stefan Paetow wrote:
What would you like me to call that new realm configuration (if I were to want to submit this upstream)?
bangrealm? bang_realm?
This thread feels like it's been dragged back to the 1980's... :( I thought bang paths were long gone (for the better). Matthew
'exclamation_realm' sounds... bad. I know, bang_realm is not much better, but... That's why I'm asking you. Stefan Paetow Consultant, Trust and Identity t: +44 (0)1235 822 125 gpg: 0x3FCE5142 xmpp: stefanp@jabber.dev.ja.net skype: stefan.paetow.janet jisc.ac.uk Jisc is a registered charity (number 1149740) and a company limited by guarantee which is registered in England under Company No. 5747339, VAT No. GB 197 0632 86. Jisc’s registered office is: One Castlepark, Tower Hill, Bristol, BS2 0JA. T 0203 697 5800. On 12/02/2019, 17:14, "Freeradius-Users on behalf of Matthew Newton" <freeradius-users-bounces+stefan.paetow=jisc.ac.uk@lists.freeradius.org on behalf of mcn@freeradius.org> wrote: On Tue, 2019-02-12 at 15:54 +0000, Stefan Paetow wrote: > What would you like me to call that new realm configuration (if I > were to want to submit this upstream)? > > bangrealm? bang_realm? This thread feels like it's been dragged back to the 1980's... :( I thought bang paths were long gone (for the better). Matthew - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
On Feb 12, 2019, at 10:54 AM, Stefan Paetow <Stefan.Paetow@JISC.AC.UK> wrote:
What would you like me to call that new realm configuration (if I were to want to submit this upstream)?
bangrealm? bang_realm?
Gimme a name and I'll submit an upstream PR for the new realm entry :-)
Call it "bangpath". It's a familiar term, and people should know what it means. Alan DeKok.
Wicked, thank you. Also, I also figured out how to resolve the other problem. Instead of looping, I do this: Define rfc7542_suffix = 'example.com|another.example.com|example.obsolete.com|still.in.use.com' rfc7542.authorize { if (&request:User-Name =~ /([a-zA-Z0-9\.-]+)!([a-zA-Z0-9\.-]*)\@(.+)/) { # do this otherwise %{3} does not resolve in the comparison update control { RFC7542-String-1 := "%{1}" RFC7542-String-2 := "%{3}" } if (!(&control:RFC7542-String-1 =~ /^(${policy.rfc7542_suffix})$/) && \ (&control:RFC7542-String-2 =~ /^(${policy.rfc7542_suffix})$/)) { bangpath } if ((&control:RFC7542-String-1 =~ /^(${policy.rfc7542_suffix})$/) && \ !(&control:RFC7542-String-2 =~ /^(${policy.rfc7542_suffix})$/)) { bangpath } update control { RFC7542-String-1 !* ANY RFC7542-String-2 !* ANY } } } The ${policy.rfc7542_suffix} value gets expanded into a pretty /^(value|value2|value3)$/ regex, and hey presto... I look for the realm in the list, regex says yes or no, and I can apply the new 'bangpath' realm processor. The only thing where I and someone else diverge on is that I've defined two strings because I don't accidentally want to trample all over any potentially-defined Tmp-String-* attributes. What say you? Better this way, or Tmp-String-* be damned? :-) Stefan Paetow Consultant, Trust and Identity t: +44 (0)1235 822 125 gpg: 0x3FCE5142 xmpp: stefanp@jabber.dev.ja.net skype: stefan.paetow.janet jisc.ac.uk Jisc is a registered charity (number 1149740) and a company limited by guarantee which is registered in England under Company No. 5747339, VAT No. GB 197 0632 86. Jisc’s registered office is: One Castlepark, Tower Hill, Bristol, BS2 0JA. T 0203 697 5800. On 12/02/2019, 17:42, "Freeradius-Users on behalf of Alan DeKok" <freeradius-users-bounces+stefan.paetow=jisc.ac.uk@lists.freeradius.org on behalf of aland@deployingradius.com> wrote: On Feb 12, 2019, at 10:54 AM, Stefan Paetow <Stefan.Paetow@JISC.AC.UK> wrote: > What would you like me to call that new realm configuration (if I were to want to submit this upstream)? > > bangrealm? bang_realm? > > Gimme a name and I'll submit an upstream PR for the new realm entry :-) Call it "bangpath". It's a familiar term, and people should know what it means. Alan DeKok. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
On Feb 12, 2019, at 6:26 PM, Stefan Paetow <Stefan.Paetow@JISC.AC.UK> wrote:
Also, I also figured out how to resolve the other problem. Instead of looping, I do this:
That looks good.
The only thing where I and someone else diverge on is that I've defined two strings because I don't accidentally want to trample all over any potentially-defined Tmp-String-* attributes. What say you? Better this way, or Tmp-String-* be damned?
Better to use well-known and named attributes for one purpose. We can always add these attributes to the internal dictionary. Alan DeKok.
Alrighty then. We'll have a pull request coming at you sometime in the near future. :-) Stefan Paetow Consultant, Trust and Identity t: +44 (0)1235 822 125 gpg: 0x3FCE5142 xmpp: stefanp@jabber.dev.ja.net skype: stefan.paetow.janet jisc.ac.uk Jisc is a registered charity (number 1149740) and a company limited by guarantee which is registered in England under Company No. 5747339, VAT No. GB 197 0632 86. Jisc’s registered office is: One Castlepark, Tower Hill, Bristol, BS2 0JA. T 0203 697 5800. On 13/02/2019, 14:17, "Freeradius-Users on behalf of Alan DeKok" <freeradius-users-bounces+stefan.paetow=jisc.ac.uk@lists.freeradius.org on behalf of aland@deployingradius.com> wrote: On Feb 12, 2019, at 6:26 PM, Stefan Paetow <Stefan.Paetow@JISC.AC.UK> wrote: > Also, I also figured out how to resolve the other problem. Instead of looping, I do this: That looks good. > The only thing where I and someone else diverge on is that I've defined two strings because I don't accidentally want to trample all over any potentially-defined Tmp-String-* attributes. What say you? Better this way, or Tmp-String-* be damned? Better to use well-known and named attributes for one purpose. We can always add these attributes to the internal dictionary. Alan DeKok. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Hi Alan, a further question has come to my mind when configuring this "bangpath" realm. When the conditions are met and it is executed, it provides a value to &Request:Realm, so "suffix" results in "noop" and, hence, it Rejects the authentication because in our "sites-enabled/abfab-tr-idp" file we have the following: suffix { updated = 1 noop = reject } I'm not sure why this was set here. I guess because we wanted that if no realm was resolved using the Trust Router, it should fail right away (I'm not sure that's necessarily true, though, as I guess it will eventually fail nonetheless as it will try to authenticate a local user that does not exist). But now we have two different resolvers instead of just one. Would it have any security implications if I removed the "noop" line? If I do that it works. If that's not desirable, would it be acceptable to make the check that if &request:Realm is set, then circumvent the suffix module? Best regards, Alex El 13/2/19 a las 14:40, Stefan Paetow escribió:
Alrighty then.
We'll have a pull request coming at you sometime in the near future.
:-)
Stefan Paetow Consultant, Trust and Identity
t: +44 (0)1235 822 125 gpg: 0x3FCE5142 xmpp: stefanp@jabber.dev.ja.net skype: stefan.paetow.janet
jisc.ac.uk
Jisc is a registered charity (number 1149740) and a company limited by guarantee which is registered in England under Company No. 5747339, VAT No. GB 197 0632 86. Jisc’s registered office is: One Castlepark, Tower Hill, Bristol, BS2 0JA. T 0203 697 5800.
On 13/02/2019, 14:17, "Freeradius-Users on behalf of Alan DeKok" <freeradius-users-bounces+stefan.paetow=jisc.ac.uk@lists.freeradius.org on behalf of aland@deployingradius.com> wrote:
On Feb 12, 2019, at 6:26 PM, Stefan Paetow <Stefan.Paetow@JISC.AC.UK> wrote: > Also, I also figured out how to resolve the other problem. Instead of looping, I do this:
That looks good.
> The only thing where I and someone else diverge on is that I've defined two strings because I don't accidentally want to trample all over any potentially-defined Tmp-String-* attributes. What say you? Better this way, or Tmp-String-* be damned?
Better to use well-known and named attributes for one purpose. We can always add these attributes to the internal dictionary.
Alan DeKok.
- List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
- List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
-- Alejandro Perez-Mendez Technical Specialist (AAA), Trust & Identity M (+34) 619 333 219 Skype alejandro_perez_mendez jisc.ac.uk
On Feb 14, 2019, at 3:17 PM, Alex Perez-Mendez <Alex.Perez-Mendez@jisc.ac.uk> wrote:
a further question has come to my mind when configuring this "bangpath" realm. When the conditions are met and it is executed, it provides a value to &Request:Realm, so "suffix" results in "noop" and, hence, it Rejects the authentication because in our "sites-enabled/abfab-tr-idp" file we have the following: suffix { updated = 1 noop = reject }
Well.. don't do that, then. :)
I'm not sure why this was set here. I guess because we wanted that if no realm was resolved using the Trust Router, it should fail right away (I'm not sure that's necessarily true, though, as I guess it will eventually fail nonetheless as it will try to authenticate a local user that does not exist).
But now we have two different resolvers instead of just one. Would it have any security implications if I removed the "noop" line? If I do that it works.
I would instead do: bangpath if (!updated) { suffix { ... } } i.e. run bangpath first, and then suffix only if there's no match for bangpath.
If that's not desirable, would it be acceptable to make the check that if &request:Realm is set, then circumvent the suffix module?
The "realm" module does that already. Alan DeKok.
I would instead do:
bangpath if (!updated) { suffix { ... } }
I would favour this approach. I assume that if I call bangpath inside a policy recipe, this would still apply: rfc7542_recipe if (!updated) { suffix { ... } } If I muck about with the control list, it would be making a difference to the status of 'updated', correct? Otherwise we'll update the recipe to include the call to suffix directly as per above. :-) With Regards Stefan Paetow Consultant, Trust and Identity t: +44 (0)1235 822 125 gpg: 0x3FCE5142 xmpp: stefanp@jabber.dev.ja.net skype: stefan.paetow.janet jisc.ac.uk Jisc is a registered charity (number 1149740) and a company limited by guarantee which is registered in England under Company No. 5747339, VAT No. GB 197 0632 86. Jisc’s registered office is: One Castlepark, Tower Hill, Bristol, BS2 0JA. T 0203 697 5800.
If I muck about with the control list, it would be making a difference to the status of 'updated', correct?
Wouldn't. WOULDN'T. Wouldn't be making a difference to the status, correct? Sorry, it's late. Stefan Paetow Consultant, Trust and Identity t: +44 (0)1235 822 125 gpg: 0x3FCE5142 xmpp: stefanp@jabber.dev.ja.net skype: stefan.paetow.janet jisc.ac.uk Jisc is a registered charity (number 1149740) and a company limited by guarantee which is registered in England under Company No. 5747339, VAT No. GB 197 0632 86. Jisc’s registered office is: One Castlepark, Tower Hill, Bristol, BS2 0JA. T 0203 697 5800.
On Feb 14, 2019, at 7:39 PM, Stefan Paetow <Stefan.Paetow@jisc.ac.uk> wrote:
If I muck about with the control list, it would be making a difference to the status of 'updated', correct?
Wouldn't. WOULDN'T. Wouldn't be making a difference to the status, correct?
It won't change the status. Alan DeKok.
El 15/2/19 a las 2:14, Alan DeKok escribió:
On Feb 14, 2019, at 7:39 PM, Stefan Paetow <Stefan.Paetow@jisc.ac.uk> wrote:
If I muck about with the control list, it would be making a difference to the status of 'updated', correct? Wouldn't. WOULDN'T. Wouldn't be making a difference to the status, correct? It won't change the status.
Yep, this definitely worked. [...] rfc7542_recipe # Standard RADIUS NAI routing if (!updated) { suffix { updated = 1 noop = reject } } [...] The only thing we need to make sure about is making sure "rfc7542_recipe" does not change the "updated" status when it does not resolve a realm. Otherwise, we would need to check for the presence of the Realm attribute :(. Thanks
Alan DeKok.
- List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
-- Alejandro Perez-Mendez Technical Specialist (AAA), Trust & Identity M (+34) 619 333 219 Skype alejandro_perez_mendez jisc.ac.uk Jisc is a registered charity (number 1149740) and a company limited by guarantee which is registered in England under Company No. 5747339, VAT No. GB 197 0632 86. Jisc’s registered office is: One Castlepark, Tower Hill, Bristol, BS2 0JA. T 0203 697 5800. Jisc Services Limited is a wholly owned Jisc subsidiary and a company limited by guarantee which is registered in England under company number 2881024, VAT number GB 197 0632 86. The registered office is: One Castle Park, Tower Hill, Bristol BS2 0JA. T 0203 697 5800.
Yep, this definitely worked.
[...] rfc7542_recipe
# Standard RADIUS NAI routing if (!updated) { suffix { updated = 1 noop = reject } } [...]
The only thing we need to make sure about is making sure "rfc7542_recipe" does not change the "updated" status when it does not resolve a realm. Otherwise, we would need to check for the presence of the Realm attribute :(.
If fact, that's happening. When "rfc7542_recipe" does not find a Trust Router realm, but resolves a local one (Ie. this is the home IDP for the End User), it does include a Realm attribute but does not change the "update" status. Should it? It is actually updating the Request by adding a Realm to it.... On the proxy: idp3_1 | (18) bangpath: Checking for prefix before "!" idp3_1 | (18) bangpath: Looking up realm "test5.org" for User-Name = "test5.org!@test3.org" idp3_1 | (18) bangpath: Found realm "apc.org%test5.org" idp3_1 | (18) bangpath: Adding Realm = "apc.org%test5.org" idp3_1 | (18) bangpath: Proxying request from user test5.org!@test3.org to realm apc.org%test5.org idp3_1 | (18) bangpath: Preparing to proxy authentication request to realm "apc.org%test5.org" idp3_1 | (18) [bangpath] = updated idp3_1 | (18) } # if (!(&control:RFC7542-Realm-1 =~ /^(test3.org)$/) && (&control:RFC7542-Realm-2 =~ /^(test3.org)$/)) = updated idp3_1 | (18) if ((&control:RFC7542-Realm-1 =~ /^(test3.org)$/) && !(&control:RFC7542-Realm-2 =~ /^(test3.org)$/)) { idp3_1 | (18) if ((&control:RFC7542-Realm-1 =~ /^(test3.org)$/) && !(&control:RFC7542-Realm-2 =~ /^(test3.org)$/)) -> FALSE idp3_1 | (18) update control { idp3_1 | (18) RFC7542-Realm-1 !* ANY idp3_1 | (18) RFC7542-Realm-2 !* ANY idp3_1 | (18) } # update control = noop idp3_1 | (18) } # if (&request:User-Name =~ /([a-zA-Z0-9\.-]+)!([a-zA-Z0-9\.-]*)\@(.+)/) = updated idp3_1 | (18) } # policy rfc7542.authorize = updated idp3_1 | (18) if (!updated) { idp3_1 | (18) if (!updated) -> FALSE idp3_1 | (18) eap: Request is supposed to be proxied to Realm apc.org%test5.org. Not doing EAP. idp3_1 | (18) [eap] = noop idp3_1 | (18) [expiration] = noop idp3_1 | (18) [logintime] = noop idp3_1 | (18) } # authorize = updated On the IDP: idp5_1 | (11) bangpath: Checking for prefix before "!" idp5_1 | (11) bangpath: Looking up realm "test5.org" for User-Name = "test5.org!@test3.org" idp5_1 | (11) bangpath: Found realm "test5.org" idp5_1 | (11) bangpath: Adding Stripped-User-Name = "@test3.org" idp5_1 | (11) bangpath: Adding Realm = "test5.org" idp5_1 | (11) bangpath: Authentication realm is LOCAL idp5_1 | (11) [bangpath] = ok idp5_1 | (11) } # if ((&control:RFC7542-Realm-1 =~ /^(test5.org)$/) && !(&control:RFC7542-Realm-2 =~ /^(test5.org)$/)) = ok idp5_1 | (11) update control { idp5_1 | (11) RFC7542-Realm-1 !* ANY idp5_1 | (11) RFC7542-Realm-2 !* ANY idp5_1 | (11) } # update control = noop idp5_1 | (11) } # if (&request:User-Name =~ /([a-zA-Z0-9\.-]+)!([a-zA-Z0-9\.-]*)\@(.+)/) = ok idp5_1 | (11) } # policy rfc7542.authorize = ok idp5_1 | (11) if (!updated) { idp5_1 | (11) if (!updated) -> TRUE idp5_1 | (11) if (!updated) { idp5_1 | (11) suffix: Request already has destination realm set. Ignoring idp5_1 | (11) [suffix] = noop idp5_1 | (11) } # if (!updated) = reject idp5_1 | (11) } # authorize = reject So I had to force the updated status when bangpath is executed. So, within rfc7542_recipe: [...] # Format: not_local_realm!...@local_realm: Handle with bangpath if (!(&control:RFC7542-Realm-1 =~ /^(${policy.rfc7542_realms})$/) && \ (&control:RFC7542-Realm-2 =~ /^(${policy.rfc7542_realms})$/)) { bangpath updated } [...] Best,
Thanks
Alan DeKok.
- List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
-- Alejandro Perez-Mendez Technical Specialist (AAA), Trust & Identity M (+34) 619 333 219 Skype alejandro_perez_mendez jisc.ac.uk Jisc is a registered charity (number 1149740) and a company limited by guarantee which is registered in England under Company No. 5747339, VAT No. GB 197 0632 86. Jisc’s registered office is: One Castlepark, Tower Hill, Bristol, BS2 0JA. T 0203 697 5800. Jisc Services Limited is a wholly owned Jisc subsidiary and a company limited by guarantee which is registered in England under company number 2881024, VAT number GB 197 0632 86. The registered office is: One Castle Park, Tower Hill, Bristol BS2 0JA. T 0203 697 5800.
Hi Alan, thank you for your help. We finally made it work nicely and we are happy to share it upstream. It's shipped as policy.d/rfc7542 and a "bangpath" realm, and enabled by default for the ABFAB-specific server. https://github.com/FreeRADIUS/freeradius-server/pull/2492 Do you think it would make it for 3.0.18? Best regards, Alejandro
Yep, this definitely worked.
[...] rfc7542_recipe
# Standard RADIUS NAI routing if (!updated) { suffix { updated = 1 noop = reject } } [...]
The only thing we need to make sure about is making sure "rfc7542_recipe" does not change the "updated" status when it does not resolve a realm. Otherwise, we would need to check for the presence of the Realm attribute :(. If fact, that's happening. When "rfc7542_recipe" does not find a Trust Router realm, but resolves a local one (Ie. this is the home IDP for the End User), it does include a Realm attribute but does not change the "update" status. Should it? It is actually updating the Request by adding a Realm to it....
On the proxy: idp3_1 | (18) bangpath: Checking for prefix before "!" idp3_1 | (18) bangpath: Looking up realm "test5.org" for User-Name = "test5.org!@test3.org" idp3_1 | (18) bangpath: Found realm "apc.org%test5.org" idp3_1 | (18) bangpath: Adding Realm = "apc.org%test5.org" idp3_1 | (18) bangpath: Proxying request from user test5.org!@test3.org to realm apc.org%test5.org idp3_1 | (18) bangpath: Preparing to proxy authentication request to realm "apc.org%test5.org" idp3_1 | (18) [bangpath] = updated idp3_1 | (18) } # if (!(&control:RFC7542-Realm-1 =~ /^(test3.org)$/) && (&control:RFC7542-Realm-2 =~ /^(test3.org)$/)) = updated idp3_1 | (18) if ((&control:RFC7542-Realm-1 =~ /^(test3.org)$/) && !(&control:RFC7542-Realm-2 =~ /^(test3.org)$/)) { idp3_1 | (18) if ((&control:RFC7542-Realm-1 =~ /^(test3.org)$/) && !(&control:RFC7542-Realm-2 =~ /^(test3.org)$/)) -> FALSE idp3_1 | (18) update control { idp3_1 | (18) RFC7542-Realm-1 !* ANY idp3_1 | (18) RFC7542-Realm-2 !* ANY idp3_1 | (18) } # update control = noop idp3_1 | (18) } # if (&request:User-Name =~ /([a-zA-Z0-9\.-]+)!([a-zA-Z0-9\.-]*)\@(.+)/) = updated idp3_1 | (18) } # policy rfc7542.authorize = updated idp3_1 | (18) if (!updated) { idp3_1 | (18) if (!updated) -> FALSE idp3_1 | (18) eap: Request is supposed to be proxied to Realm apc.org%test5.org. Not doing EAP. idp3_1 | (18) [eap] = noop idp3_1 | (18) [expiration] = noop idp3_1 | (18) [logintime] = noop idp3_1 | (18) } # authorize = updated
On the IDP: idp5_1 | (11) bangpath: Checking for prefix before "!" idp5_1 | (11) bangpath: Looking up realm "test5.org" for User-Name = "test5.org!@test3.org" idp5_1 | (11) bangpath: Found realm "test5.org" idp5_1 | (11) bangpath: Adding Stripped-User-Name = "@test3.org" idp5_1 | (11) bangpath: Adding Realm = "test5.org" idp5_1 | (11) bangpath: Authentication realm is LOCAL idp5_1 | (11) [bangpath] = ok idp5_1 | (11) } # if ((&control:RFC7542-Realm-1 =~ /^(test5.org)$/) && !(&control:RFC7542-Realm-2 =~ /^(test5.org)$/)) = ok idp5_1 | (11) update control { idp5_1 | (11) RFC7542-Realm-1 !* ANY idp5_1 | (11) RFC7542-Realm-2 !* ANY idp5_1 | (11) } # update control = noop idp5_1 | (11) } # if (&request:User-Name =~ /([a-zA-Z0-9\.-]+)!([a-zA-Z0-9\.-]*)\@(.+)/) = ok idp5_1 | (11) } # policy rfc7542.authorize = ok idp5_1 | (11) if (!updated) { idp5_1 | (11) if (!updated) -> TRUE idp5_1 | (11) if (!updated) { idp5_1 | (11) suffix: Request already has destination realm set. Ignoring idp5_1 | (11) [suffix] = noop idp5_1 | (11) } # if (!updated) = reject idp5_1 | (11) } # authorize = reject
So I had to force the updated status when bangpath is executed. So, within rfc7542_recipe:
[...] # Format: not_local_realm!...@local_realm: Handle with bangpath if (!(&control:RFC7542-Realm-1 =~ /^(${policy.rfc7542_realms})$/) && \ (&control:RFC7542-Realm-2 =~ /^(${policy.rfc7542_realms})$/)) { bangpath updated } [...]
Best,
Thanks
Alan DeKok.
- List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
-- Alejandro Perez-Mendez Technical Specialist (AAA), Trust & Identity M (+34) 619 333 219 Skype alejandro_perez_mendez jisc.ac.uk Jisc is a registered charity (number 1149740) and a company limited by guarantee which is registered in England under Company No. 5747339, VAT No. GB 197 0632 86. Jisc’s registered office is: One Castlepark, Tower Hill, Bristol, BS2 0JA. T 0203 697 5800. Jisc Services Limited is a wholly owned Jisc subsidiary and a company limited by guarantee which is registered in England under company number 2881024, VAT number GB 197 0632 86. The registered office is: One Castle Park, Tower Hill, Bristol BS2 0JA. T 0203 697 5800.
On Feb 15, 2019, at 11:19 AM, Alex Perez-Mendez <Alex.Perez-Mendez@jisc.ac.uk> wrote:
thank you for your help. We finally made it work nicely and we are happy to share it upstream. It's shipped as policy.d/rfc7542 and a "bangpath" realm, and enabled by default for the ABFAB-specific server.
https://github.com/FreeRADIUS/freeradius-server/pull/2492
Do you think it would make it for 3.0.18?
I've pulled it in. Alan DeKok.
El 17/2/19 a las 2:39, Alan DeKok escribió:
On Feb 15, 2019, at 11:19 AM, Alex Perez-Mendez <Alex.Perez-Mendez@jisc.ac.uk> wrote:
thank you for your help. We finally made it work nicely and we are happy to share it upstream. It's shipped as policy.d/rfc7542 and a "bangpath" realm, and enabled by default for the ABFAB-specific server.
https://github.com/FreeRADIUS/freeradius-server/pull/2492
Do you think it would make it for 3.0.18? I've pulled it in.
Thanks!
Alan DeKok.
- List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
-- Alejandro Perez-Mendez Technical Specialist (AAA), Trust & Identity M (+34) 619 333 219 Skype alejandro_perez_mendez jisc.ac.uk Jisc is a registered charity (number 1149740) and a company limited by guarantee which is registered in England under Company No. 5747339, VAT No. GB 197 0632 86. Jisc’s registered office is: One Castlepark, Tower Hill, Bristol, BS2 0JA. T 0203 697 5800. Jisc Services Limited is a wholly owned Jisc subsidiary and a company limited by guarantee which is registered in England under company number 2881024, VAT number GB 197 0632 86. The registered office is: One Castle Park, Tower Hill, Bristol BS2 0JA. T 0203 697 5800.
participants (4)
-
Alan DeKok -
Alex Perez-Mendez -
Matthew Newton -
Stefan Paetow