[pve-devel] [PATCH pve-manager 4/4] api2: network: check vlan permissions for local bridges

DERUMIER, Alexandre alexandre.derumier at groupe-cyllene.com
Fri Jun 2 14:32:10 CEST 2023


Le vendredi 02 juin 2023 à 13:39 +0200, Fabian Grünbichler a écrit :
> On May 26, 2023 9:27 am, Alexandre Derumier wrote:
> > We need to display the bridge is the user have a permission
> > on any vlan on the bridge.
> > 
> > to avoid to check permissions on 4096 vlans for each bridge
> > (could be slow with a lot of bridges),
> > we first list vlans where acls are defined.
> > 
> > (4000 check took 60ms on 10year xeon server, should be enough
> > for any network where the total number of vlans is limited)
> 
> some sort of spec here for how the ACL looks like would be nice to
> have
> (while it's possible to reverse it from the code, it's always nicer
> to
> have the expection explicit as well).
> 
> > 
> > Signed-off-by: Alexandre Derumier <aderumier at odiso.com>
> > ---
> >  PVE/API2/Network.pm | 20 +++++++++++++++++++-
> >  1 file changed, 19 insertions(+), 1 deletion(-)
> > 
> > diff --git a/PVE/API2/Network.pm b/PVE/API2/Network.pm
> > index ba3b3e0e..39f17d14 100644
> > --- a/PVE/API2/Network.pm
> > +++ b/PVE/API2/Network.pm
> > @@ -240,17 +240,35 @@ __PACKAGE__->register_method({
> >  
> >         if (my $tfilter = $param->{type}) {
> >             my $vnets;
> > +           my $bridges_vlans_acl = {};
> >             #check access for local bridges
> >             my $can_access_vnet = sub {
> > +               my $bridge = $_[0];
> >                 return 1 if $authuser eq 'root at pam';
> >                 return 1 if $rpcenv->check_any($authuser,
> > "/sdn/zones/local", ['SDN.Audit', 'SDN.Allocate'], 1);
> > -               return 1 if $rpcenv->check_any($authuser,
> > "/sdn/vnets/$_[0]", ['SDN.Audit', 'SDN.Allocate'], 1);
> > +               return 1 if $rpcenv->check($authuser,
> > "/sdn/vnets/$bridge", ['SDN.Audit'], 1);
> 
> why does this drop the Allocate? we usually have the "more
> privileged"
> privilege in addition to Audit (if there is one).

I think allocate maybe sense on zone. (as what's we allocate are
vnets).
(it should be removed on /sdn/vnets/$_[0]).


But I don't, maybe if user add a simple acl like "/" + propagate with
SDN.allocate only, we want to give it access everywhere ?


> 
> > +               my $bridge_vlan = $bridges_vlans_acl->{$bridge};
> > +               for my $tag (sort keys %$bridge_vlan) {
> > +                   return 1 if $rpcenv->check($authuser,
> > "/sdn/vnets/$bridge.$tag", ['SDN.Audit'], 1);
> 
> wouldn't $bridge/$tag be more natural? it would allow propagation
> from a
> bridge to all tags using the usual propagate flag as well..
> 
> this could also live in pve-access-control as a special helper, then
> we
> wouldn't need to do this dance here (it would be the first
> iterate_acl_tree call site outside of pve-access-control!).
> 
> something like this in PVE::RPCEnvironment:
> 
> sub check_sdn_vlan(.., $bridge, $priv) {
>   .. iterate over all vlans and check while iterating, returning
> early for first one with access
> }
> 
> basically:
> 
> my $bridge = PVE::AccessControl::find_acl_tree_node($cfg->{acl_root},
> "/sdn/vnets/$bridge");
> if ($bridge) {
>   for my $vlan (keys $bridge->{children}->%$) {
>     return 1 if $self->check_any(...);
>   }
>   return 1 if # check propagate on bridge itself
> }
> return 0;
> 
> > +               }
> >             };
> >  
> >             if ($have_sdn && $param->{type} eq 'any_bridge') {
> >                 $vnets = PVE::Network::SDN::get_local_vnets(); #
> > returns already access-filtered
> >             }
> >  
> > +           #find all vlans where we have specific acls
> > +           if ($tfilter =~ /^any(_local)?_bridge$/) {
> > +               my $cfg = $rpcenv->{user_cfg};
> > +               my $vnets_acl_root = $cfg->{acl_root}->{children}-
> > >{sdn}->{children}->{vnets};
> > +               PVE::AccessControl::iterate_acl_tree("/",
> > $vnets_acl_root, sub {
> > +                   my ($path, $node) = @_;
> > +                   if ($path =~ /\/(.*)\.(\d+)$/) {
> > +                       $bridges_vlans_acl->{$1}->{$2} = 1;
> > +                   }
> > +               });
> > +           }
> 
> because this iterates over *all* ACLs, only to then return upon the
> first match above in $can_access_vnet..
> 
> it should also be
> 
> iterate_acl_tree("/sdn/vnets", ..) or "/sdn/vnets/$bridge" if vlan
> tags
> live as children of the bridge (path and the node should match!).
> there
> also is "find_acl_tree_node" so you don't need to make assumptions
> about
> how the nodes are laid out.
> 

Thanks ! I was really banging my head to implement this properly &&
fast ^_^


> I do wonder whether something that supports ranges would be more
> appropriate rather then encoding this in ACLs directly though..
>  could
> always be added later on though (e.g., named vlan objects that define
> a
> set of vlans).

yes, I was thinking the same to avoid too much acl when you need to
access to many vlans.

> 
> > +
> >             for my $k (sort keys $ifaces->%*) {
> >                 my $type = $ifaces->{$k}->{type};
> >                 my $match = $tfilter eq $type || ($tfilter =~
> > /^any(_local)?_bridge$/ && ($type eq 'bridge' || $type eq
> > 'OVSBridge'));
> > -- 
> > 2.30.2
> > 
> > 
> > _______________________________________________
> > pve-devel mailing list
> > pve-devel at lists.proxmox.com
> > https://antiphishing.cetsi.fr/proxy/v3?i=MlZSTzBhZFZ6Nzl4c3EyN7fbSKDePLMxi5u5_onpAoI&r=cm1qVmRYUWk2WXhYZVFHWA0PXtTaYxz7-FIOTkZBm34_dHdSch-gXn7ST9eGhQLN&f=S1Zkd042VWdrZG5qQUxxWk5ps4t67kNuHsBZzdzhpquLKuXqTZLIq2K1DfKr9N61yBafm7AuAITd6bHtRU4zEQ&u=https%3A//lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel&k=F1is
> > 
> > 
> > 
> 
> 
> _______________________________________________
> pve-devel mailing list
> pve-devel at lists.proxmox.com
> https://antiphishing.cetsi.fr/proxy/v3?i=MlZSTzBhZFZ6Nzl4c3EyN7fbSKDePLMxi5u5_onpAoI&r=cm1qVmRYUWk2WXhYZVFHWA0PXtTaYxz7-FIOTkZBm34_dHdSch-gXn7ST9eGhQLN&f=S1Zkd042VWdrZG5qQUxxWk5ps4t67kNuHsBZzdzhpquLKuXqTZLIq2K1DfKr9N61yBafm7AuAITd6bHtRU4zEQ&u=https%3A//lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel&k=F1is
> 



More information about the pve-devel mailing list