Matching multiple LDAP-groups during post-auth

classic Classic list List threaded Threaded
9 messages Options
| Threaded
Open this post in threaded view
|

Matching multiple LDAP-groups during post-auth

falz-2
We use LDAP-groups (from AD, if that matters) to map
radius-reply-items for general network access on switches, routers,
optical gear, etc. Each vendor is their own special flower so needs
its own thing.

The way we're handling this currently is in post-auth where we specify
reply-items per group using if/elseif/else per
https://networkradius.com/doc/3.0.10/unlang/keywords.html.

This works great if things are simple - you're a member of one group
or another. However, we've not yet gotten it to work if one is a
member of multiple groups, and to have each group match and get
reply-items from each.

Example of now:

if (LDAP-Group == "network-administrators") {
        update reply {
                cisco-avpair = "shell:priv-lvl=15",
                Service-Type = "6",
                Juniper-Local-User-Name = "superuser",
                PaloAlto-Admin-Role = "superuser",
        }
}
elsif (LDAP-Group == "network-users") {
        update reply {
                cisco-avpair = "shell:priv-lvl=1",
                Juniper-Local-User-Name = "op",
                PaloAlto-Admin-Role = "devicereader",
        }
}
else {
        reject
}

Note that this will do a single match and bail out of the if
statement. What we'd like to do is to keep matching accumulatively.
The use case is per above it's layer2/3 devices, we'd like to add some
other types of gear to the list where someone in the above groups
shouldnt have access to, but someone in network-administrators AND
$othergroup should have access to.

Per Unlang, it looks like there is a case/switch statement but I
believe we'd be hitting the same limitation there.

tldr; how can we match multiple LDAP-groups and get reply-items from
all that match?

Cheers,
Chris
-
List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
| Threaded
Open this post in threaded view
|

Re: Matching multiple LDAP-groups during post-auth

Users mailing list
On Thu, Mar 25, 2021 at 9:01 AM Chris Wopat <[hidden email]> wrote:
[snipped]

> Note that this will do a single match and bail out of the if
> statement. What we'd like to do is to keep matching accumulatively.
> The use case is per above it's layer2/3 devices, we'd like to add some
> other types of gear to the list where someone in the above groups
> shouldnt have access to, but someone in network-administrators AND
> $othergroup should have access to.
>
> Per Unlang, it looks like there is a case/switch statement but I
> believe we'd be hitting the same limitation there.
>
> tldr; how can we match multiple LDAP-groups and get reply-items from
> all that match?

Chris,
Thank you for posting your snippet, as it was helpful for me to
develop a similar setup in my org. :)
I've been doing some reading on LDAP-Group, and from what I could
find, switch/case doesn't work with it.
I'm not entirely sure why, but I saw Alan explicitly tell someone else
to use if/elseif instead... that reply was also from several years
back, so maybe that's no longer accurate?

Have you considered using nested ifs to query twice for the
"network-admins AND $othergroup" scenario?
If you're concerned about LDAP load / query time, you can enable
caching in the ldap module; then the LDAP-Group list is saved and
lookups happen against the cache instead of being re-queried each time
you ask for it.

I'd suggest investigating the syntax "&LDAP-Group[*]" as it seems to
be preferred over just "LDAP-Group", as well.

Regards,
Braden
-
List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
| Threaded
Open this post in threaded view
|

Re: Matching multiple LDAP-groups during post-auth

Michael Schwartzkopff-3
On 31.03.21 01:56, Braden McGrath via Freeradius-Users wrote:

> On Thu, Mar 25, 2021 at 9:01 AM Chris Wopat <[hidden email]> wrote:
> [snipped]
>> Note that this will do a single match and bail out of the if
>> statement. What we'd like to do is to keep matching accumulatively.
>> The use case is per above it's layer2/3 devices, we'd like to add some
>> other types of gear to the list where someone in the above groups
>> shouldnt have access to, but someone in network-administrators AND
>> $othergroup should have access to.
>>
>> Per Unlang, it looks like there is a case/switch statement but I
>> believe we'd be hitting the same limitation there.
>>
>> tldr; how can we match multiple LDAP-groups and get reply-items from
>> all that match?
> Chris,
> Thank you for posting your snippet, as it was helpful for me to
> develop a similar setup in my org. :)
> I've been doing some reading on LDAP-Group, and from what I could
> find, switch/case doesn't work with it.
> I'm not entirely sure why, but I saw Alan explicitly tell someone else
> to use if/elseif instead... that reply was also from several years
> back, so maybe that's no longer accurate?
>
> Have you considered using nested ifs to query twice for the
> "network-admins AND $othergroup" scenario?
> If you're concerned about LDAP load / query time, you can enable
> caching in the ldap module; then the LDAP-Group list is saved and
> lookups happen against the cache instead of being re-queried each time
> you ask for it.
>
> I'd suggest investigating the syntax "&LDAP-Group[*]" as it seems to
> be preferred over just "LDAP-Group", as well.
>
> Regards,
> Braden
> -
> List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html


If the user is member of multiple groups, the LDAP-Group is a
Attribute-List (=Array).

see the man pages of unlang.

I used LDAP-Group array checks to select VPN connections. Please see

https://blog.sys4.de/strongswan-vpn-based-on-groups-en.html

for my solution. Hope my ideas can help you.


Mit freundlichen Grüßen,

--

[*] sys4 AG
 
https://sys4.de, +49 (89) 30 90 46 64
Schleißheimer Straße 26/MG,80333 München
 
Sitz der Gesellschaft: München, Amtsgericht München: HRB 199263
Vorstand: Patrick Ben Koetter, Marc Schiffbauer, Wolfgang Stief
Aufsichtsratsvorsitzender: Florian Kirstein

-
List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
| Threaded
Open this post in threaded view
|

Re: Matching multiple LDAP-groups during post-auth

falz-2
In reply to this post by Users mailing list
On Tue, Mar 30, 2021 at 6:56 PM Braden McGrath via Freeradius-Users
<[hidden email]> wrote:
>
> Have you considered using nested ifs to query twice for the
> "network-admins AND $othergroup" scenario?
> If you're concerned about LDAP load / query time, you can enable
> caching in the ldap module; then the LDAP-Group list is saved and
> lookups happen against the cache instead of being re-queried each time
> you ask for it.

using a complicated series of ANDs is something we hope to not have to
fall back on due to complexity.

Let's say there were 5 groups:

* 3 groups for 'network' layer2/3
* 2 groups for 'optical' layer1

.. there's 31 combinations of 5 items, meaning 31 IF statements, which
is unruly.

Thanks for the caching tip, unsure if this is currently enabled but will do so!


On Wed, Mar 31, 2021 at 2:14 AM Michael Schwartzkopff <[hidden email]> wrote:

>
> If the user is member of multiple groups, the LDAP-Group is a
> Attribute-List (=Array).
>
> see the man pages of unlang.
>
> I used LDAP-Group array checks to select VPN connections. Please see
>
> https://blog.sys4.de/strongswan-vpn-based-on-groups-en.html
>
> for my solution. Hope my ideas can help you.

Very helpful thank you. I haven't used "case" before- since it's in a
switch, in the link above, you mention " have to use the switch / case
structure since a user can be member of multiple groups". Does this
mean that the switch/case statement will update the reply for *all*
matching cases, not just the first hit?

If so this is exactly what I'm looking for, but my brain assumed, due
to the "switch", that the first hit would win and it would stop
processing after that.

--Chris
-
List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
| Threaded
Open this post in threaded view
|

Re: Matching multiple LDAP-groups during post-auth

Alan DeKok-2
On Mar 31, 2021, at 7:42 AM, Chris Wopat <[hidden email]> wrote:
> using a complicated series of ANDs is something we hope to not have to
> fall back on due to complexity.

  The unfortunate reality is that complexity has to go somewhere.

> Let's say there were 5 groups:
>
> * 3 groups for 'network' layer2/3
> * 2 groups for 'optical' layer1
>
> .. there's 31 combinations of 5 items, meaning 31 IF statements, which
> is unruly.

  I'm not sure why you need those combinations.  Why not just:

* do network layer
AND
* do optical layer?

  Perhaps the rules really are "network 1 AND optical 1 gets A, network 1 AND optical 2 gets B", with A / B being completely different.  In that case, you really do need massive amounts of ANDs.

  The general solution is to split your rules into independent sets, and then combine the sets.

> Very helpful thank you. I haven't used "case" before- since it's in a
> switch, in the link above, you mention " have to use the switch / case
> structure since a user can be member of multiple groups". Does this
> mean that the switch/case statement will update the reply for *all*
> matching cases, not just the first hit?

  It only uses the first one it finds.

  Why not just do 3 IFs for network later, followed by 2 IFs for optical layer?

  You can always add an extra "if" to catch the case of "no matching group was found".

        if network 1
                update reply for network 1
        else if network 2
                ...
        else
                update reply with fake attribute saying "no match"

        if optical 1
                update reply for optical 1
        else if ...
                ...
        else
                update reply with fake attribute saying "no match"

        if reply has "no match"
                reject

  Alan DeKok.


-
List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
| Threaded
Open this post in threaded view
|

Re: Matching multiple LDAP-groups during post-auth

falz-2
On Wed, Mar 31, 2021 at 7:04 AM Alan DeKok <[hidden email]> wrote:

>
> On Mar 31, 2021, at 7:42 AM, Chris Wopat <[hidden email]> wrote:
> >
> > .. there's 31 combinations of 5 items, meaning 31 IF statements, which
> > is unruly.
>
>   I'm not sure why you need those combinations.  Why not just:
>
> * do network layer
> AND
> * do optical layer?
>
>   Perhaps the rules really are "network 1 AND optical 1 gets A, network 1 AND optical 2 gets B", with A / B being completely different.  In that case, you really do need massive amounts of ANDs.
>
>   The general solution is to split your rules into independent sets, and then combine the sets.


We do this currently, but have an issue with having a reject at the
end of each, as it will reject users that are only a part of the 2nd
group.


> > Very helpful thank you. I haven't used "case" before- since it's in a
> > switch, in the link above, you mention " have to use the switch / case
> > structure since a user can be member of multiple groups". Does this
> > mean that the switch/case statement will update the reply for *all*
> > matching cases, not just the first hit?
>
>   It only uses the first one it finds.
>
>   Why not just do 3 IFs for network later, followed by 2 IFs for optical layer?
>
>   You can always add an extra "if" to catch the case of "no matching group was found".
>
>         if network 1
>                 update reply for network 1
>         else if network 2
>                 ...
>         else
>                 update reply with fake attribute saying "no match"
>
>         if optical 1
>                 update reply for optical 1
>         else if ...
>                 ...
>         else
>                 update reply with fake attribute saying "no match"
>
>         if reply has "no match"
>                 reject

This is very similar to what we're doing now, except your 'no match'
stuff, which may in fact be the actual fix.

To clarify, you're using some BS reply-item, which is in some vendor
dictionary just to store this variable string, then comparing that at
the end? In theory this sounds like it would resolve this for us.

Looking at the dictionary file, it says to use between 3000 and 4000
for local attributes, perhaps just plopping something like this in
that file would work?

  ATTRIBUTE      Local-Reject-Check         3000    string

OR perhaps as an int:

  ATTRIBUTE      Local-Reject-Check         3000    integer


What we have now is:

network:
  if / elsif / elsif / (no reject currently, or it wouldn't make it to
the optical check if not in network group)

optical:
  if / elsif / else reject


The solution you list seems sane on paper, we hadn't thought about
using a reply item to store a variable for a later check, but assuming
that's all possible, I think this is our winner.

--Chris
-
List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
| Threaded
Open this post in threaded view
|

Re: Matching multiple LDAP-groups during post-auth

Alan DeKok-2
On Mar 31, 2021, at 8:30 AM, Chris Wopat <[hidden email]> wrote:
> To clarify, you're using some BS reply-item, which is in some vendor
> dictionary just to store this variable string, then comparing that at
> the end? In theory this sounds like it would resolve this for us.
>
> Looking at the dictionary file, it says to use between 3000 and 4000
> for local attributes, perhaps just plopping something like this in
> that file would work?

  Yes  That would work.

>  ATTRIBUTE      Local-Reject-Check         3000    string
>
> OR perhaps as an int:
>
>  ATTRIBUTE      Local-Reject-Check         3000    integer

  It doesn't really matter.  All that matters is if it exists.

  Maybe make it a string, and then put the value as *why* it didn't match.

> What we have now is:
>
> network:
>  if / elsif / elsif / (no reject currently, or it wouldn't make it to
> the optical check if not in network group)
>
> optical:
>  if / elsif / else reject
>
> The solution you list seems sane on paper, we hadn't thought about
> using a reply item to store a variable for a later check, but assuming
> that's all possible, I think this is our winner.

  Sounds like it.

        if network 1 ...
                ...
        else {
                update reply {
                        Local-Reject-Check += "No matching network"
                }
        }

    if optical 1 ...
                ...
        else {
                update reply {
                        Local-Reject-Check += "No matching optical"
                }
        }

        if (&reply:Local-Reject-Check) {
                reject
        }

  And that should do it.

  Alan DeKok.

-
List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
| Threaded
Open this post in threaded view
|

Re: Matching multiple LDAP-groups during post-auth

falz-2
On Wed, Mar 31, 2021 at 7:34 AM Alan DeKok <[hidden email]> wrote:

>         if network 1 ...
>                 ...
>         else {
>                 update reply {
>                         Local-Reject-Check += "No matching network"
>                 }
>         }
>
>         if optical 1 ...
>                 ...
>         else {
>                 update reply {
>                         Local-Reject-Check += "No matching optical"
>                 }
>         }
>
>         if (&reply:Local-Reject-Check) {
>                 reject
>         }
>
>   And that should do it.

Thanks for the sample config. Just chiming in to say that this
*mostly* worked, the last item, which appears to be checking the
existence of "Local-Reject-Check" within the reply, didn't work and
I'd always get a reject.

Note I'm on FreeRADIUS 2 still, on my todo list is upgrade to v3, will
plug away at it more when I do that.

--Chris
-
List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
| Threaded
Open this post in threaded view
|

Re: Matching multiple LDAP-groups during post-auth

Alan DeKok-2
On Apr 6, 2021, at 10:35 AM, Chris Wopat <[hidden email]> wrote:
>
> Thanks for the sample config. Just chiming in to say that this
> *mostly* worked, the last item, which appears to be checking the
> existence of "Local-Reject-Check" within the reply, didn't work and
> I'd always get a reject.

  Maybe just give the attribute a value?

> Note I'm on FreeRADIUS 2 still, on my todo list is upgrade to v3, will
> plug away at it more when I do that.

  Sure.

  I haven't looked at v2 in about 3 years, so I can't help much there, sorry.

  Alan DeKok.

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