Preserve ldap attributes after proxy
Hi everyone, I'm trying to wrap my head around this, digging in the archives and the wiki with no luck, so I'm looking for a few pointers. We are currently using freeradius to to proxy requests to a central One-Time-password server (which is outside our control). This is purely authentication, we send the cleartext token we received from the NAS, they check and either reject or reply. (The only reason we do this is because the upstream organization is not willing to deal with the administration of the NASes and we've been asked to aggregate traffic) Now with a new solution I also need to query a central ldap database for authorization info: I need to get a given attribute off of user records and present them to the NAS. I was pointing my finger at Filter-Id, but purely because the NAS docs points at it, it could really be anything. If I omit the proxy part, then it's just a straightforward ldap config with adding the attribute as a reply Item mapped to Filter-ID in the ldap.attrmap with +=, getting rid of reading the userPassword so that no one tries to auth against the password there and enable ldap in the authorize section. However, when I then proxy the request these extra Filter-Ids are lost: they are neither proxied (which is just as well, I really don't know what would the homeserver do about it) nor are they sent in my reply. I've found traces of something like this being discussed that this is because there is a separate data structure, but that is over a decade old, and I'm a bit confused on how this supposed to work. Is there a way to keep does attributes (or to get them after proxying, either in post-proxy or post-auth maybe?) by using rlm_ldap? I could probably write a short perl that queries this directly in post-auth, but basically the reason I want to do this in radius instead of the NAS is because I would need a mild hack on my networking to allow it to directly reach the ldap, so I though that, the radius box can reach the ldap, it can talk ldap, the nas is connected anyway.. But if it's troublesome with radius, then I'd rather not hack it. Does anyone have a pointer on what track should I go down? Thanks! tamas
Tamás Becz wrote:
Now with a new solution I also need to query a central ldap database for authorization info: I need to get a given attribute off of user records and present them to the NAS. I was pointing my finger at Filter-Id, but purely because the NAS docs points at it, it could really be anything.
You probably don't want to use Filter-ID. It has a pre-defined meaning. Using it for another purpose is bad.
If I omit the proxy part, then it's just a straightforward ldap config with adding the attribute as a reply Item mapped to Filter-ID in the ldap.attrmap with +=, getting rid of reading the userPassword so that no one tries to auth against the password there and enable ldap in the authorize section.
OK.
However, when I then proxy the request these extra Filter-Ids are lost: they are neither proxied (which is just as well, I really don't know what would the homeserver do about it) nor are they sent in my reply. I've found traces of something like this being discussed that this is because there is a separate data structure, but that is over a decade old, and I'm a bit confused on how this supposed to work.
What you're *not* saying is that you're putting the Filter-ID into the reply list. That gets replaced by the reply from the home server. If you want the attributes kept... put them in another list.
Is there a way to keep does attributes (or to get them after proxying, either in post-proxy or post-auth maybe?) by using rlm_ldap?
No. Put the attributes into the "control" list. That's what it's for. Then, copy them to the reply in post-auth. Alan DeKok.
Hi,
Now with a new solution I also need to query a central ldap database for authorization info: I need to get a given attribute off of user records and present them to the NAS. I was pointing my finger at Filter-Id, but purely because the NAS docs points at it, it could really be anything.
You probably don't want to use Filter-ID. It has a pre-defined meaning. Using it for another purpose is bad.
Yes I got that, but the NAS (which is mainly a VPN concentrator) actually uses the value for assigning firewall rules to the user's session which is precisely what Filter-Id is for if I understand the rfc correctly. Due to the complexity of the nas, it also does other stuff based on this, but filter-id really is the closest in rfc 3850 (Probably this is why they are also pointing at this). However, I will check how hard it is extend with a vendor-specific instead.
However, when I then proxy the request these extra Filter-Ids are lost: they are neither proxied (which is just as well, I really don't know what would the homeserver do about it) nor are they sent in my reply. I've found traces of something like this being discussed that this is because there is a separate data structure, but that is over a decade old, and I'm a bit confused on how this supposed to work.
What you're *not* saying is that you're putting the Filter-ID into the
reply
list. That gets replaced by the reply from the home server.
If you want the attributes kept... put them in another list.
Actually I did ;) But for sure it's only because rlm_ldap either does that or onto the check list, thanks for the clarification.
Is there a way to keep does attributes (or to get them after proxying, either in post-proxy or post-auth maybe?) by using rlm_ldap?
No. Put the attributes into the "control" list. That's what it's for. Then, copy them to the reply in post-auth.
Currently I can't test, but do I understand correctly that rlm_ldap can't put things on the control list, but I could use unlang to copy the attributes from reply to control in authorize after ldap, then copy them back in post-auth? Thanks! tamas
Tamás Becz wrote:
Yes I got that, but the NAS (which is mainly a VPN concentrator) actually uses the value for assigning firewall rules to the user's session which is precisely what Filter-Id is for if I understand the rfc correctly.
OK... you didn't say that originally. Knowing that helps.
Currently I can't test, but do I understand correctly that rlm_ldap can't put things on the control list, but I could use unlang to copy the attributes from reply to control in authorize after ldap, then copy them back in post-auth?
Yes. Alan DeKok.
Hi,
Tamás Becz wrote:
Yes I got that, but the NAS (which is mainly a VPN concentrator) actually uses the value for assigning firewall rules to the user's session which is precisely what Filter-Id is for if I understand the rfc correctly.
OK... you didn't say that originally. Knowing that helps.
Yes, I originally intended to provide that only as background information to help set the context for understanding of what I want to do with ldap. I've drawn the line at a bad place with deciding how much info to put in there. Sorry about it.
Currently I can't test, but do I understand correctly that rlm_ldap can't put things on the control list, but I could use unlang to copy the attributes from reply to control in authorize after ldap, then copy them back in post-auth?
Yes.
I've done some testing. At this point I think it is important to mention that I'm at 2.1.12. While I made it work, I found some gotchas. If I do: authorize { ... ldap update control { Filter-Id += "%{reply:Filter-Id}" } ... } post-auth { ... update reply { Filter-Id += "%{control:Filter-Id}" } ... } Then it's all good until there are multiple attributes, in which case only the first one gets copied (which is all according to the docs). I see that on the 3.x version unlang has been extended with foreach, but is my understanding correct that on the 2.x branch this can't be done with unlang? I see that there's no loop control, but maybe I missed a mass copy operator? I can fix it with perl however: authorize { ... ldap update control { Filter-Id := "%{reply:Filter-Id[*]}" } ... } post-auth { ... update reply { Filter-Id := "%{control:Filter-Id}" } perl ... } Perl: sub post_auth { if ($RAD_REPLY{"Filter-Id"}) { my @blown = split(/\\n/,$RAD_REPLY{"Filter-Id"}); $RAD_REPLY{"Filter-Id"} = \@blown; return RLM_MODULE_UPDATED; } else { return RLM_MODULE_OK; } } However I don't see a way in rlm_perl for directly touching control, so I have to keep unlang around, which is ok, but if I got to call perl anyway then I might as well skip unlang if possible. Is there a way to do that? Thanks! tamas
Tamás Becz wrote:
I've done some testing. At this point I think it is important to mention that I'm at 2.1.12. While I made it work, I found some gotchas.
Because 2.1.12 is *old*.
However I don't see a way in rlm_perl for directly touching control
It should be there. If it's not, upgrade to 2.2.5.
, so I have to keep unlang around, which is ok, but if I got to call perl anyway then I might as well skip unlang if possible. Is there a way to do that?
Upgrade to a recent version of the server. In v3, you can do list to list copies. So that's easier. Alan DeKok.
Hi,
I've done some testing. At this point I think it is important to mention that I'm at 2.1.12. While I made it work, I found some gotchas.
Because 2.1.12 is *old*.
Yes, I know, however that's what RH is shipping currently, unfortunately.
However I don't see a way in rlm_perl for directly touching control
It should be there. If it's not, upgrade to 2.2.5.
Ok, thanks. Currently that's rather an infrastructural headache, but yep, that's my issue. Also, I did look at the source and figured that probably RAD_CHECK and RAD_CONFIG is essentially both the control list, and found that the wiki says check is deprecated naming for control. So I just changed ldap.attrmap to put the attribute as checkItem (which at this point I assume means also control) instead of replyItem, got rid of all the unlang, and left perl only in post auth to set $RAD_REPLY{"Filter-Id"} = $RAD_CHECK{"Filter-Id"}; and it seems to work. However, I'm right now a bit of unsure that what's happening is really what I think is happening, or just a lucky coincidence and I'm doing something stupid?
, so I have to keep unlang around, which is ok, but if I got to call perl
anyway
then I might as well skip unlang if possible. Is there a way to do that?
Upgrade to a recent version of the server.
In v3, you can do list to list copies. So that's easier.
Yep, once we move towards RH7. Thanks, tamas
On 10-11-14 14:14, Alan DeKok wrote:
However I don't see a way in rlm_perl for directly touching control
It should be there. If it's not, upgrade to 2.2.5.
It looks like it's possible in 2.1.12 as well, with the RAD_CONFIG hash. It can be used in the same way as RAD_REPLY. However, rlm_perl can segfault in version 2.1, there is a fix for in since 2.2 (see https://github.com/FreeRADIUS/freeradius-server/commit/ecb3cd1dbedb764ab9853...). Maybe Redhat has backported this fix, I only know Debian hasn't. -- Herwin Weststrate
Hi,
It looks like it's possible in 2.1.12 as well, with the RAD_CONFIG hash. It can be used in the same way as RAD_REPLY.
That was my conclusion as well.
However, rlm_perl can segfault in version 2.1, there is a fix for in since 2.2 (see https://github.com/FreeRADIUS/freeradius- server/commit/ecb3cd1dbedb764ab98532dae5e0b5bfc9571b00). Maybe Redhat has backported this fix, I only know Debian hasn't.
Thanks, I will check this out. tamas
Hi,
However, rlm_perl can segfault in version 2.1, there is a fix for in since 2.2 (see https://github.com/FreeRADIUS/freeradius- server/commit/ecb3cd1dbedb764ab98532dae5e0b5bfc9571b00). Maybe Redhat has backported this fix, I only know Debian hasn't.
They did, but thanks for the headsup! tamas
participants (3)
-
Alan DeKok -
Herwin Weststrate -
Tamás Becz