public inbox for pve-devel@lists.proxmox.com
 help / color / mirror / Atom feed
From: "Fabian Grünbichler" <f.gruenbichler@proxmox.com>
To: Proxmox VE development discussion <pve-devel@lists.proxmox.com>
Subject: Re: [pve-devel] [PATCH pve-manager 4/4] api2: network: check vlan permissions for local bridges
Date: Fri, 02 Jun 2023 13:39:55 +0200	[thread overview]
Message-ID: <1685703684.s6g3qc3qqp.astroid@yuna.none> (raw)
In-Reply-To: <20230526072724.1605613-5-aderumier@odiso.com>

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@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@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).

> +		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.

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).

> +
>  	    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@lists.proxmox.com
> https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
> 
> 
> 




  reply	other threads:[~2023-06-02 11:40 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-05-26  7:27 [pve-devel] [PATCH pve-manager 0/4] add vnet/localbridge permissions management Alexandre Derumier
2023-05-26  7:27 ` [pve-devel] [PATCH pve-manager 1/4] add vnet permissions panel Alexandre Derumier
2023-05-26  7:27 ` [pve-devel] [PATCH pve-manager 2/4] add permissions management for "local" network zone Alexandre Derumier
2023-06-02 11:39   ` Fabian Grünbichler
2023-06-02 12:21     ` DERUMIER, Alexandre
2023-06-02 14:18       ` DERUMIER, Alexandre
2023-05-26  7:27 ` [pve-devel] [PATCH pve-manager 3/4] api2: network: check permissions for local bridges Alexandre Derumier
2023-06-02 11:39   ` Fabian Grünbichler
2023-05-26  7:27 ` [pve-devel] [PATCH pve-manager 4/4] api2: network: check vlan " Alexandre Derumier
2023-06-02 11:39   ` Fabian Grünbichler [this message]
2023-06-02 12:32     ` DERUMIER, Alexandre

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1685703684.s6g3qc3qqp.astroid@yuna.none \
    --to=f.gruenbichler@proxmox.com \
    --cc=pve-devel@lists.proxmox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal