* [pve-devel] [PATCH-SERIE pve-access-control/pve-manager/qemu-server] check permissions on local bridge @ 2023-06-04 23:37 Alexandre Derumier 2023-06-04 23:37 ` [pve-devel] [PATCH pve-access-control 1/2] access control: add /sdn/vnets/<vnet>/<vlan> path Alexandre Derumier ` (6 more replies) 0 siblings, 7 replies; 18+ messages in thread From: Alexandre Derumier @ 2023-06-04 23:37 UTC (permalink / raw) To: pve-devel add vnet/localbridge permissions management Hi, as we has discuted some weeks ago, this patche serie introduce management of acl for vnets && local bridges I have reuse current sdn permissions path, to have common paths /sdn/vnets/<zone>/<vnet> where the local vmbr are in a virtual "localnetwork" zone /sdn/vnets/local/<vnet> Vlans permissions are also handled with /sdn/vnets/<zone>/<vnet>/<tag> if user have permissions on the zone, he have access to all vnets/vlan if user have permissions on the vnet/tag, he have access to only the specific vlan. if user have permissions on the vnet, he have access to all vlans of the vnet I have reworked the sdn zone panel from the tree, to manage permissions on displayed vnets. some screenshots: https://mutulin1.odiso.net/sdnzone-perm.png https://mutulin1.odiso.net/localzone-perm.png for proxmox7: (for users be able to add permissions before upgrade to pve8) pve-access-control: patch1 (to new /vnet/vlan path) pve-manager : patch1-2 for the new gui changelog v2: - use /vnets/vlan instead /vnets.vlan - rework the bridge filtering when user have access only to a specific vlan - api2 network: always check bridge access if no filter is defined todo: - add permissions on clone/restore ? pve-access-control: Alexandre Derumier (2): access control: add /sdn/vnets/<vnet>/<vlan> path rpcenvironnment: add check_sdn_bridge src/PVE/AccessControl.pm | 1 + src/PVE/RPCEnvironment.pm | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) pve-manager: Alexandre Derumier (3): add vnet permissions panel add permissions management for "localnetwork" zone api2: network: check permissions for local bridges PVE/API2/Cluster.pm | 12 ++ PVE/API2/Network.pm | 26 ++- www/manager6/Makefile | 2 + www/manager6/sdn/Browser.js | 17 +- www/manager6/sdn/VnetACLView.js | 299 +++++++++++++++++++++++++++ www/manager6/sdn/ZoneContentPanel.js | 41 ++++ www/manager6/sdn/ZoneContentView.js | 52 ++++- 7 files changed, 420 insertions(+), 29 deletions(-) create mode 100644 www/manager6/sdn/VnetACLView.js create mode 100644 www/manager6/sdn/ZoneContentPanel.js qemu-server: Alexandre Derumier (1): api2: add check_bridge_access for create/update vm PVE/API2/Qemu.pm | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) -- 2.30.2 ^ permalink raw reply [flat|nested] 18+ messages in thread
* [pve-devel] [PATCH pve-access-control 1/2] access control: add /sdn/vnets/<vnet>/<vlan> path 2023-06-04 23:37 [pve-devel] [PATCH-SERIE pve-access-control/pve-manager/qemu-server] check permissions on local bridge Alexandre Derumier @ 2023-06-04 23:37 ` Alexandre Derumier 2023-06-04 23:37 ` [pve-devel] [PATCH v2 pve-manager 1/3] add vnet permissions panel Alexandre Derumier ` (5 subsequent siblings) 6 siblings, 0 replies; 18+ messages in thread From: Alexandre Derumier @ 2023-06-04 23:37 UTC (permalink / raw) To: pve-devel Signed-off-by: Alexandre Derumier <aderumier@odiso.com> --- src/PVE/AccessControl.pm | 1 + 1 file changed, 1 insertion(+) diff --git a/src/PVE/AccessControl.pm b/src/PVE/AccessControl.pm index 89b7d90..2fdcd44 100644 --- a/src/PVE/AccessControl.pm +++ b/src/PVE/AccessControl.pm @@ -1284,6 +1284,7 @@ sub check_path { |/sdn |/sdn/zones/[[:alnum:]\.\-\_]+ |/sdn/vnets/[[:alnum:]\.\-\_]+ + |/sdn/vnets/[[:alnum:]\.\-\_]+/[1-9][0-9]{0,3} |/storage |/storage/[[:alnum:]\.\-\_]+ |/vms -- 2.30.2 ^ permalink raw reply [flat|nested] 18+ messages in thread
* [pve-devel] [PATCH v2 pve-manager 1/3] add vnet permissions panel 2023-06-04 23:37 [pve-devel] [PATCH-SERIE pve-access-control/pve-manager/qemu-server] check permissions on local bridge Alexandre Derumier 2023-06-04 23:37 ` [pve-devel] [PATCH pve-access-control 1/2] access control: add /sdn/vnets/<vnet>/<vlan> path Alexandre Derumier @ 2023-06-04 23:37 ` Alexandre Derumier 2023-06-04 23:37 ` [pve-devel] [PATCH v2 qemu-server 1/1] api2: add check_bridge_access for create/update vm Alexandre Derumier ` (4 subsequent siblings) 6 siblings, 0 replies; 18+ messages in thread From: Alexandre Derumier @ 2023-06-04 23:37 UTC (permalink / raw) To: pve-devel Signed-off-by: Alexandre Derumier <aderumier@odiso.com> --- www/manager6/Makefile | 2 + www/manager6/sdn/Browser.js | 17 +- www/manager6/sdn/VnetACLView.js | 299 +++++++++++++++++++++++++++ www/manager6/sdn/ZoneContentPanel.js | 41 ++++ www/manager6/sdn/ZoneContentView.js | 25 ++- 5 files changed, 366 insertions(+), 18 deletions(-) create mode 100644 www/manager6/sdn/VnetACLView.js create mode 100644 www/manager6/sdn/ZoneContentPanel.js diff --git a/www/manager6/Makefile b/www/manager6/Makefile index 2b577c8e..fb9930af 100644 --- a/www/manager6/Makefile +++ b/www/manager6/Makefile @@ -251,10 +251,12 @@ JSSRC= \ sdn/StatusView.js \ sdn/VnetEdit.js \ sdn/VnetView.js \ + sdn/VnetACLView.js \ sdn/VnetPanel.js \ sdn/SubnetEdit.js \ sdn/SubnetView.js \ sdn/ZoneContentView.js \ + sdn/ZoneContentPanel.js \ sdn/ZoneView.js \ sdn/OptionsPanel.js \ sdn/controllers/Base.js \ diff --git a/www/manager6/sdn/Browser.js b/www/manager6/sdn/Browser.js index 09b0c4fe..3dc5a5ad 100644 --- a/www/manager6/sdn/Browser.js +++ b/www/manager6/sdn/Browser.js @@ -25,14 +25,15 @@ Ext.define('PVE.sdn.Browser', { const caps = Ext.state.Manager.get('GuiCap'); - if (caps.sdn['SDN.Audit']) { - me.items.push({ - xtype: 'pveSDNZoneContentView', - title: gettext('Content'), - iconCls: 'fa fa-th', - itemId: 'content', - }); - } + me.items.push({ + nodename: nodename, + zone: sdnId, + xtype: 'pveSDNZoneContentPanel', + title: gettext('Content'), + iconCls: 'fa fa-th', + itemId: 'content', + }); + if (caps.sdn['Permissions.Modify']) { me.items.push({ xtype: 'pveACLView', diff --git a/www/manager6/sdn/VnetACLView.js b/www/manager6/sdn/VnetACLView.js new file mode 100644 index 00000000..8e7f35c1 --- /dev/null +++ b/www/manager6/sdn/VnetACLView.js @@ -0,0 +1,299 @@ +Ext.define('PVE.sdn.VnetACLAdd', { + extend: 'Proxmox.window.Edit', + alias: ['widget.pveSDNVnetACLAdd'], + + url: '/access/acl', + method: 'PUT', + isAdd: true, + isCreate: true, + + width: 400, + initComponent: function() { + let me = this; + + let items = [ + { + xtype: 'hiddenfield', + name: 'path', + value: me.path, + allowBlank: false, + fieldLabel: gettext('Path'), + }, + ]; + + if (me.aclType === 'group') { + me.subject = gettext("Group Permission"); + items.push({ + xtype: 'pveGroupSelector', + name: 'groups', + fieldLabel: gettext('Group'), + }); + } else if (me.aclType === 'user') { + me.subject = gettext("User Permission"); + items.push({ + xtype: 'pmxUserSelector', + name: 'users', + fieldLabel: gettext('User'), + }); + } else if (me.aclType === 'token') { + me.subject = gettext("API Token Permission"); + items.push({ + xtype: 'pveTokenSelector', + name: 'tokens', + fieldLabel: gettext('API Token'), + }); + } else { + throw "unknown ACL type"; + } + + items.push({ + xtype: 'pmxRoleSelector', + name: 'roles', + value: 'NoAccess', + fieldLabel: gettext('Role'), + }); + + items.push({ + xtype: 'proxmoxintegerfield', + name: 'vlan', + minValue: 1, + maxValue: 4096, + allowBlank: true, + fieldLabel: 'Vlan', + emptyText: gettext('All'), + }); + + if (!me.path) { + items.push({ + xtype: 'proxmoxcheckbox', + name: 'propagate', + checked: true, + uncheckedValue: 0, + fieldLabel: gettext('Propagate'), + }); + } + + let ipanel = Ext.create('Proxmox.panel.InputPanel', { + items: items, + onlineHelp: 'pveum_permission_management', + onGetValues: function(values) { + if (values.vlan) { + values.path = values.path + "/" + values.vlan; + delete values.vlan; + } + return values; + }, + }); + + Ext.apply(me, { + items: [ipanel], + }); + + me.callParent(); + }, +}); + +Ext.define('PVE.sdn.VnetACLView', { + extend: 'Ext.grid.GridPanel', + + alias: ['widget.pveSDNVnetACLView'], + + onlineHelp: 'chapter_user_management', + + stateful: true, + stateId: 'grid-acls', + + // use fixed path + path: undefined, + + setPath: function(path) { + let me = this; + + me.path = path; + + if (path === undefined) { + me.down('#groupmenu').setDisabled(true); + me.down('#usermenu').setDisabled(true); + me.down('#tokenmenu').setDisabled(true); + } else { + me.down('#groupmenu').setDisabled(false); + me.down('#usermenu').setDisabled(false); + me.down('#tokenmenu').setDisabled(false); + me.store.load(); + } + }, + initComponent: function() { + let me = this; + + let store = Ext.create('Ext.data.Store', { + model: 'pve-acl', + proxy: { + type: 'proxmox', + url: "/api2/json/access/acl", + }, + sorters: { + property: 'path', + direction: 'ASC', + }, + }); + + store.addFilter(Ext.create('Ext.util.Filter', { + filterFn: item => item.data.path.replace(/(\/sdn\/vnets\/)(.*)\/[0-9]*$/, '$1$2') === me.path, + })); + + let render_ugid = function(ugid, metaData, record) { + if (record.data.type === 'group') { + return '@' + ugid; + } + + return Ext.String.htmlEncode(ugid); + }; + + let render_vlan = function(path, metaData, record) { + let vlan = 'any'; + const match = path.match(/(\/sdn\/vnets\/)(.*)\/([0-9]*)$/); + if (match) { + vlan = match[3]; + } + + return Ext.String.htmlEncode(vlan); + }; + + let columns = [ + { + header: gettext('User') + '/' + gettext('Group') + '/' + gettext('API Token'), + flex: 1, + sortable: true, + renderer: render_ugid, + dataIndex: 'ugid', + }, + { + header: gettext('Role'), + flex: 1, + sortable: true, + dataIndex: 'roleid', + }, + { + header: gettext('Vlan'), + flex: 1, + sortable: true, + renderer: render_vlan, + dataIndex: 'path', + }, + ]; + + + let sm = Ext.create('Ext.selection.RowModel', {}); + + let remove_btn = new Proxmox.button.Button({ + text: gettext('Remove'), + disabled: true, + selModel: sm, + confirmMsg: gettext('Are you sure you want to remove this entry'), + handler: function(btn, event, rec) { + var params = { + 'delete': 1, + path: rec.data.path, + roles: rec.data.roleid, + }; + if (rec.data.type === 'group') { + params.groups = rec.data.ugid; + } else if (rec.data.type === 'user') { + params.users = rec.data.ugid; + } else if (rec.data.type === 'token') { + params.tokens = rec.data.ugid; + } else { + throw 'unknown data type'; + } + + Proxmox.Utils.API2Request({ + url: '/access/acl', + params: params, + method: 'PUT', + waitMsgTarget: me, + callback: () => store.load(), + failure: response => Ext.Msg.alert(gettext('Error'), response.htmlStatus), + }); + }, + }); + + Proxmox.Utils.monStoreErrors(me, store); + + Ext.apply(me, { + store: store, + selModel: sm, + tbar: [ + { + text: gettext('Add'), + menu: { + xtype: 'menu', + items: [ + { + text: gettext('Group Permission'), + disabled: !me.path, + itemId: 'groupmenu', + iconCls: 'fa fa-fw fa-group', + handler: function() { + var win = Ext.create('PVE.sdn.VnetACLAdd', { + aclType: 'group', + path: me.path, + }); + win.on('destroy', () => store.load()); + win.show(); + }, + }, + { + text: gettext('User Permission'), + disabled: !me.path, + itemId: 'usermenu', + iconCls: 'fa fa-fw fa-user', + handler: function() { + var win = Ext.create('PVE.sdn.VnetACLAdd', { + aclType: 'user', + path: me.path, + }); + win.on('destroy', () => store.load()); + win.show(); + }, + }, + { + text: gettext('API Token Permission'), + disabled: !me.path, + itemId: 'tokenmenu', + iconCls: 'fa fa-fw fa-user-o', + handler: function() { + let win = Ext.create('PVE.sdn.VnetACLAdd', { + aclType: 'token', + path: me.path, + }); + win.on('destroy', () => store.load()); + win.show(); + }, + }, + ], + }, + }, + remove_btn, + ], + viewConfig: { + trackOver: false, + }, + columns: columns, + listeners: { + }, + }); + + me.callParent(); + }, +}, function() { + Ext.define('pve-acl-vnet', { + extend: 'Ext.data.Model', + fields: [ + 'path', 'type', 'ugid', 'roleid', + { + name: 'propagate', + type: 'boolean', + }, + ], + }); +}); diff --git a/www/manager6/sdn/ZoneContentPanel.js b/www/manager6/sdn/ZoneContentPanel.js new file mode 100644 index 00000000..5bb081bb --- /dev/null +++ b/www/manager6/sdn/ZoneContentPanel.js @@ -0,0 +1,41 @@ +Ext.define('PVE.sdn.ZoneContentPanel', { + extend: 'Ext.panel.Panel', + alias: 'widget.pveSDNZoneContentPanel', + + title: 'Vnet', + + onlineHelp: 'pvesdn_config_vnet', + + initComponent: function() { + var me = this; + + var permissions_panel = Ext.createWidget('pveSDNVnetACLView', { + title: gettext('Vnet Permissions'), + region: 'center', + border: false, + }); + + var vnetview_panel = Ext.createWidget('pveSDNZoneContentView', { + title: 'Vnets', + region: 'west', + permissions_panel: permissions_panel, + nodename: me.nodename, + zone: me.zone, + width: '50%', + border: false, + split: true, + }); + + Ext.apply(me, { + layout: 'border', + items: [vnetview_panel, permissions_panel], + listeners: { + show: function() { + permissions_panel.fireEvent('show', permissions_panel); + }, + }, + }); + + me.callParent(); + }, +}); diff --git a/www/manager6/sdn/ZoneContentView.js b/www/manager6/sdn/ZoneContentView.js index 1ea65450..08fa9d81 100644 --- a/www/manager6/sdn/ZoneContentView.js +++ b/www/manager6/sdn/ZoneContentView.js @@ -17,17 +17,15 @@ Ext.define('PVE.sdn.ZoneContentView', { initComponent: function() { var me = this; - var nodename = me.pveSelNode.data.node; - if (!nodename) { + if (!me.nodename) { throw "no node name specified"; } - var zone = me.pveSelNode.data.sdn; - if (!zone) { + if (!me.zone) { throw "no zone ID specified"; } - var baseurl = "/nodes/" + nodename + "/sdn/zones/" + zone + "/content"; + var baseurl = "/nodes/" + me.nodename + "/sdn/zones/" + me.zone + "/content"; var store = Ext.create('Ext.data.Store', { model: 'pve-sdnzone-content', groupField: 'content', @@ -48,7 +46,6 @@ Ext.define('PVE.sdn.ZoneContentView', { }; Proxmox.Utils.monStoreErrors(me, store); - Ext.apply(me, { store: store, selModel: sm, @@ -79,11 +76,19 @@ Ext.define('PVE.sdn.ZoneContentView', { dataIndex: 'statusmsg', }, ], - listeners: { - activate: reload, - }, + listeners: { + activate: reload, + show: reload, + select: function(_sm, rec) { + let path = `/sdn/vnets/${rec.data.vnet}`; + me.permissions_panel.setPath(path); + }, + deselect: function() { + me.permissions_panel.setPath(undefined); + }, + }, }); - + store.load(); me.callParent(); }, }, function() { -- 2.30.2 ^ permalink raw reply [flat|nested] 18+ messages in thread
* [pve-devel] [PATCH v2 qemu-server 1/1] api2: add check_bridge_access for create/update vm 2023-06-04 23:37 [pve-devel] [PATCH-SERIE pve-access-control/pve-manager/qemu-server] check permissions on local bridge Alexandre Derumier 2023-06-04 23:37 ` [pve-devel] [PATCH pve-access-control 1/2] access control: add /sdn/vnets/<vnet>/<vlan> path Alexandre Derumier 2023-06-04 23:37 ` [pve-devel] [PATCH v2 pve-manager 1/3] add vnet permissions panel Alexandre Derumier @ 2023-06-04 23:37 ` Alexandre Derumier 2023-06-05 7:38 ` Thomas Lamprecht 2023-06-05 10:12 ` Fabian Grünbichler 2023-06-04 23:37 ` [pve-devel] [PATCH v2 pve-manager 2/3] add permissions management for "localnetwork" zone Alexandre Derumier ` (3 subsequent siblings) 6 siblings, 2 replies; 18+ messages in thread From: Alexandre Derumier @ 2023-06-04 23:37 UTC (permalink / raw) To: pve-devel test first if user have access to the full zone (any bridge/vlan) if a tag is defined, test if user have a specific access to the vlan (or propagate from full bridge acl) if no tag, test if user have access to full bridge. (if trunks are defined, it need also access to full bridge) Signed-off-by: Alexandre Derumier <aderumier@odiso.com> --- PVE/API2/Qemu.pm | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/PVE/API2/Qemu.pm b/PVE/API2/Qemu.pm index 587bb22..4de7b32 100644 --- a/PVE/API2/Qemu.pm +++ b/PVE/API2/Qemu.pm @@ -46,6 +46,12 @@ use PVE::SSHInfo; use PVE::Replication; use PVE::StorageTunnel; +my $have_sdn; +eval { + require PVE::Network::SDN; + $have_sdn = 1; +}; + BEGIN { if (!$ENV{PVE_GENERATING_DOCS}) { require PVE::HA::Env::PVE2; @@ -601,6 +607,34 @@ my $check_vm_create_usb_perm = sub { return 1; }; +my $check_bridge_access = sub { + my ($rpcenv, $authuser, $param) = @_; + + return 1 if $authuser eq 'root@pam'; + + foreach my $opt (keys %{$param}) { + next if $opt !~ m/^net\d+$/; + my $net = PVE::QemuServer::parse_net($param->{$opt}); + my $bridge = $net->{bridge}; + my $tag = $net->{tag}; + my $zone = 'local'; + + if ($have_sdn) { + my $vnet_cfg = PVE::Network::SDN::Vnets::config(); + if (defined(my $vnet = PVE::Network::SDN::Vnets::sdn_vnets_config($vnet_cfg, $bridge, 1))) { + $zone = $vnet->{zone}; + } + } + # test first if user have access to the full zone (any bridge/vlan) + return 1 if $rpcenv->check_any($authuser, "/sdn/zones/$zone", ['SDN.Audit', 'SDN.Allocate'], 1); + # if a tag is defined, test if user have a specific access to the vlan (or propagate from full bridge acl) + return 1 if $tag && $rpcenv->check_any($authuser, "/sdn/vnets/$bridge/$tag", ['SDN.Audit', 'SDN.Allocate'], 1); + # if no tag, test if user have access to full bridge. (if trunks are defined, it need also access to full bridge) + $rpcenv->check_any($authuser, "/sdn/vnets/$bridge", ['SDN.Audit', 'SDN.Allocate']); + } + return 1; +}; + my $check_vm_modify_config_perm = sub { my ($rpcenv, $authuser, $vmid, $pool, $key_list) = @_; @@ -878,7 +912,7 @@ __PACKAGE__->register_method({ &$check_vm_create_serial_perm($rpcenv, $authuser, $vmid, $pool, $param); &$check_vm_create_usb_perm($rpcenv, $authuser, $vmid, $pool, $param); - + &$check_bridge_access($rpcenv, $authuser, $param); &$check_cpu_model_access($rpcenv, $authuser, $param); $check_drive_param->($param, $storecfg); @@ -1578,6 +1612,8 @@ my $update_vm_api = sub { &$check_storage_access($rpcenv, $authuser, $storecfg, $vmid, $param); + &$check_bridge_access($rpcenv, $authuser, $param); + my $updatefn = sub { my $conf = PVE::QemuConfig->load_config($vmid); -- 2.30.2 ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [pve-devel] [PATCH v2 qemu-server 1/1] api2: add check_bridge_access for create/update vm 2023-06-04 23:37 ` [pve-devel] [PATCH v2 qemu-server 1/1] api2: add check_bridge_access for create/update vm Alexandre Derumier @ 2023-06-05 7:38 ` Thomas Lamprecht 2023-06-06 4:20 ` DERUMIER, Alexandre 2023-06-05 10:12 ` Fabian Grünbichler 1 sibling, 1 reply; 18+ messages in thread From: Thomas Lamprecht @ 2023-06-05 7:38 UTC (permalink / raw) To: Proxmox VE development discussion, Alexandre Derumier Am 05/06/2023 um 01:37 schrieb Alexandre Derumier: > test first if user have access to the full zone (any bridge/vlan) > if a tag is defined, test if user have a specific access to the vlan (or propagate from full bridge acl) > if no tag, test if user have access to full bridge. (if trunks are defined, it need also access to full bridge) > > Signed-off-by: Alexandre Derumier <aderumier@odiso.com> > --- > PVE/API2/Qemu.pm | 38 +++++++++++++++++++++++++++++++++++++- > 1 file changed, 37 insertions(+), 1 deletion(-) > > diff --git a/PVE/API2/Qemu.pm b/PVE/API2/Qemu.pm > index 587bb22..4de7b32 100644 > --- a/PVE/API2/Qemu.pm > +++ b/PVE/API2/Qemu.pm > @@ -46,6 +46,12 @@ use PVE::SSHInfo; > use PVE::Replication; > use PVE::StorageTunnel; > > +my $have_sdn; > +eval { > + require PVE::Network::SDN; > + $have_sdn = 1; > +}; > + > BEGIN { > if (!$ENV{PVE_GENERATING_DOCS}) { > require PVE::HA::Env::PVE2; > @@ -601,6 +607,34 @@ my $check_vm_create_usb_perm = sub { > return 1; > }; > > +my $check_bridge_access = sub { > + my ($rpcenv, $authuser, $param) = @_; > + > + return 1 if $authuser eq 'root@pam'; > + > + foreach my $opt (keys %{$param}) { > + next if $opt !~ m/^net\d+$/; > + my $net = PVE::QemuServer::parse_net($param->{$opt}); > + my $bridge = $net->{bridge}; > + my $tag = $net->{tag}; should below move to a method in pve-guest-common, taking $bridge (or name it already $vnet) and $tag as additional parameter, and then be also used by container? > + my $zone = 'local'; > + > + if ($have_sdn) { > + my $vnet_cfg = PVE::Network::SDN::Vnets::config(); > + if (defined(my $vnet = PVE::Network::SDN::Vnets::sdn_vnets_config($vnet_cfg, $bridge, 1))) { > + $zone = $vnet->{zone}; > + } > + } > + # test first if user have access to the full zone (any bridge/vlan) > + return 1 if $rpcenv->check_any($authuser, "/sdn/zones/$zone", ['SDN.Audit', 'SDN.Allocate'], 1); > + # if a tag is defined, test if user have a specific access to the vlan (or propagate from full bridge acl) > + return 1 if $tag && $rpcenv->check_any($authuser, "/sdn/vnets/$bridge/$tag", ['SDN.Audit', 'SDN.Allocate'], 1); > + # if no tag, test if user have access to full bridge. (if trunks are defined, it need also access to full bridge) > + $rpcenv->check_any($authuser, "/sdn/vnets/$bridge", ['SDN.Audit', 'SDN.Allocate']); > + } > + return 1; > +}; > + > my $check_vm_modify_config_perm = sub { > my ($rpcenv, $authuser, $vmid, $pool, $key_list) = @_; > > @@ -878,7 +912,7 @@ __PACKAGE__->register_method({ > > &$check_vm_create_serial_perm($rpcenv, $authuser, $vmid, $pool, $param); > &$check_vm_create_usb_perm($rpcenv, $authuser, $vmid, $pool, $param); > - > + &$check_bridge_access($rpcenv, $authuser, $param); > &$check_cpu_model_access($rpcenv, $authuser, $param); > > $check_drive_param->($param, $storecfg); > @@ -1578,6 +1612,8 @@ my $update_vm_api = sub { > > &$check_storage_access($rpcenv, $authuser, $storecfg, $vmid, $param); > > + &$check_bridge_access($rpcenv, $authuser, $param); > + > my $updatefn = sub { > > my $conf = PVE::QemuConfig->load_config($vmid); ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [pve-devel] [PATCH v2 qemu-server 1/1] api2: add check_bridge_access for create/update vm 2023-06-05 7:38 ` Thomas Lamprecht @ 2023-06-06 4:20 ` DERUMIER, Alexandre 0 siblings, 0 replies; 18+ messages in thread From: DERUMIER, Alexandre @ 2023-06-06 4:20 UTC (permalink / raw) To: pve-devel, t.lamprecht, aderumier > > > > +my $check_bridge_access = sub { > > + my ($rpcenv, $authuser, $param) = @_; > > + > > + return 1 if $authuser eq 'root@pam'; > > + > > + foreach my $opt (keys %{$param}) { > > + next if $opt !~ m/^net\d+$/; > > + my $net = PVE::QemuServer::parse_net($param->{$opt}); > > + my $bridge = $net->{bridge}; > > + my $tag = $net->{tag}; > > should below move to a method in pve-guest-common, taking $bridge (or > name it already $vnet) and $tag > as additional parameter, and then be also used by container? yes indeed! (I'll try to do patch for lxc today). ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [pve-devel] [PATCH v2 qemu-server 1/1] api2: add check_bridge_access for create/update vm 2023-06-04 23:37 ` [pve-devel] [PATCH v2 qemu-server 1/1] api2: add check_bridge_access for create/update vm Alexandre Derumier 2023-06-05 7:38 ` Thomas Lamprecht @ 2023-06-05 10:12 ` Fabian Grünbichler 1 sibling, 0 replies; 18+ messages in thread From: Fabian Grünbichler @ 2023-06-05 10:12 UTC (permalink / raw) To: Proxmox VE development discussion On June 5, 2023 1:37 am, Alexandre Derumier wrote: > test first if user have access to the full zone (any bridge/vlan) > if a tag is defined, test if user have a specific access to the vlan (or propagate from full bridge acl) > if no tag, test if user have access to full bridge. (if trunks are defined, it need also access to full bridge) > > Signed-off-by: Alexandre Derumier <aderumier@odiso.com> > --- > PVE/API2/Qemu.pm | 38 +++++++++++++++++++++++++++++++++++++- > 1 file changed, 37 insertions(+), 1 deletion(-) > > diff --git a/PVE/API2/Qemu.pm b/PVE/API2/Qemu.pm > index 587bb22..4de7b32 100644 > --- a/PVE/API2/Qemu.pm > +++ b/PVE/API2/Qemu.pm > @@ -46,6 +46,12 @@ use PVE::SSHInfo; > use PVE::Replication; > use PVE::StorageTunnel; > > +my $have_sdn; > +eval { > + require PVE::Network::SDN; > + $have_sdn = 1; > +}; > + > BEGIN { > if (!$ENV{PVE_GENERATING_DOCS}) { > require PVE::HA::Env::PVE2; > @@ -601,6 +607,34 @@ my $check_vm_create_usb_perm = sub { > return 1; > }; > > +my $check_bridge_access = sub { > + my ($rpcenv, $authuser, $param) = @_; > + > + return 1 if $authuser eq 'root@pam'; > + > + foreach my $opt (keys %{$param}) { > + next if $opt !~ m/^net\d+$/; > + my $net = PVE::QemuServer::parse_net($param->{$opt}); > + my $bridge = $net->{bridge}; > + my $tag = $net->{tag}; > + my $zone = 'local'; > + > + if ($have_sdn) { > + my $vnet_cfg = PVE::Network::SDN::Vnets::config(); > + if (defined(my $vnet = PVE::Network::SDN::Vnets::sdn_vnets_config($vnet_cfg, $bridge, 1))) { > + $zone = $vnet->{zone}; > + } > + } > + # test first if user have access to the full zone (any bridge/vlan) > + return 1 if $rpcenv->check_any($authuser, "/sdn/zones/$zone", ['SDN.Audit', 'SDN.Allocate'], 1); > + # if a tag is defined, test if user have a specific access to the vlan (or propagate from full bridge acl) > + return 1 if $tag && $rpcenv->check_any($authuser, "/sdn/vnets/$bridge/$tag", ['SDN.Audit', 'SDN.Allocate'], 1); this one IMHO should be $rpcenv->check($authuser, "/sdn/vnets/$bridge/$tag", ['SDN.Use']) if $tag; see comment in cover letter and below. > + # if no tag, test if user have access to full bridge. (if trunks are defined, it need also access to full bridge) > + $rpcenv->check_any($authuser, "/sdn/vnets/$bridge", ['SDN.Audit', 'SDN.Allocate']); trunks also allow (sub)ranges, in that case we could check for those tags? or do we really need the full bridge? these checks here should check for (a not yet existing) 'SDN.Use' privilege, so that we can differentiate between: - Audit: see the config, but neither change nor use its entries - Use: use the entries - Allocate: modify the entries similar to Dominik's series for PCI/USB (where there is 'Modify' to manage the entries, and 'Use' to reference them in guest configs). I agree with Thomas that it likely makes sense to have all of that after the parse_net call in a helper in pve-guest-common, like: sub check_vnet_access { my ($rpcenv, $authuser, $vnet, $tag) = @_; ... } for code reuse with pve-container. > + } > + return 1; > +}; > + > my $check_vm_modify_config_perm = sub { > my ($rpcenv, $authuser, $vmid, $pool, $key_list) = @_; > > @@ -878,7 +912,7 @@ __PACKAGE__->register_method({ > > &$check_vm_create_serial_perm($rpcenv, $authuser, $vmid, $pool, $param); > &$check_vm_create_usb_perm($rpcenv, $authuser, $vmid, $pool, $param); > - > + &$check_bridge_access($rpcenv, $authuser, $param); > &$check_cpu_model_access($rpcenv, $authuser, $param); > > $check_drive_param->($param, $storecfg); > @@ -1578,6 +1612,8 @@ my $update_vm_api = sub { > > &$check_storage_access($rpcenv, $authuser, $storecfg, $vmid, $param); > > + &$check_bridge_access($rpcenv, $authuser, $param); > + > my $updatefn = sub { > > my $conf = PVE::QemuConfig->load_config($vmid); > -- > 2.30.2 > > > _______________________________________________ > pve-devel mailing list > pve-devel@lists.proxmox.com > https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel > > > ^ permalink raw reply [flat|nested] 18+ messages in thread
* [pve-devel] [PATCH v2 pve-manager 2/3] add permissions management for "localnetwork" zone 2023-06-04 23:37 [pve-devel] [PATCH-SERIE pve-access-control/pve-manager/qemu-server] check permissions on local bridge Alexandre Derumier ` (2 preceding siblings ...) 2023-06-04 23:37 ` [pve-devel] [PATCH v2 qemu-server 1/1] api2: add check_bridge_access for create/update vm Alexandre Derumier @ 2023-06-04 23:37 ` Alexandre Derumier 2023-06-04 23:37 ` [pve-devel] [PATCH pve-access-control 2/2] rpcenvironnment: add check_sdn_bridge Alexandre Derumier ` (2 subsequent siblings) 6 siblings, 0 replies; 18+ messages in thread From: Alexandre Derumier @ 2023-06-04 23:37 UTC (permalink / raw) To: pve-devel add a default virtual zone called 'localnetwork' in the ressource tree, and handle permissions like a true sdn zone (no conflict with true sdn zone is possible, as they have 8 characters max) Signed-off-by: Alexandre Derumier <aderumier@odiso.com> --- PVE/API2/Cluster.pm | 12 ++++++++++++ PVE/API2/Network.pm | 5 +++-- www/manager6/sdn/ZoneContentView.js | 27 ++++++++++++++++++++++++++- 3 files changed, 41 insertions(+), 3 deletions(-) diff --git a/PVE/API2/Cluster.pm b/PVE/API2/Cluster.pm index 2e942368..ce0db5f8 100644 --- a/PVE/API2/Cluster.pm +++ b/PVE/API2/Cluster.pm @@ -474,6 +474,18 @@ __PACKAGE__->register_method({ } } + #add default "localnetwork" zone + foreach my $node (@$nodelist) { + my $local_sdn = { + id => "sdn/$node/localnetwork", + sdn => 'localnetwork', + node => $node, + type => 'sdn', + status => 'ok', + }; + push @$res, $local_sdn; + } + if ($have_sdn) { if (!$param->{type} || $param->{type} eq 'sdn') { diff --git a/PVE/API2/Network.pm b/PVE/API2/Network.pm index a43579fa..b3faba1a 100644 --- a/PVE/API2/Network.pm +++ b/PVE/API2/Network.pm @@ -209,7 +209,7 @@ __PACKAGE__->register_method({ type => { description => "Only list specific interface types.", type => 'string', - enum => [ @$network_type_enum, 'any_bridge' ], + enum => [ @$network_type_enum, 'any_bridge', 'any_local_bridge' ], optional => 1, }, }, @@ -254,7 +254,8 @@ __PACKAGE__->register_method({ for my $k (sort keys $ifaces->%*) { my $type = $ifaces->{$k}->{type}; - my $match = $tfilter eq $type || ($tfilter eq 'any_bridge' && ($type eq 'bridge' || $type eq 'OVSBridge')); + my $match = $tfilter eq $type || ($tfilter =~ /^any(_local)?_bridge$/ && ($type eq 'bridge' || $type eq 'OVSBridge')); + delete $ifaces->{$k} if !($match && $can_access_vnet->($k)); } diff --git a/www/manager6/sdn/ZoneContentView.js b/www/manager6/sdn/ZoneContentView.js index 08fa9d81..0eaa742a 100644 --- a/www/manager6/sdn/ZoneContentView.js +++ b/www/manager6/sdn/ZoneContentView.js @@ -26,6 +26,9 @@ Ext.define('PVE.sdn.ZoneContentView', { } var baseurl = "/nodes/" + me.nodename + "/sdn/zones/" + me.zone + "/content"; + if (me.zone === 'localnetwork') { + baseurl = "/nodes/" + me.nodename + "/network?type=any_local_bridge"; + } var store = Ext.create('Ext.data.Store', { model: 'pve-sdnzone-content', groupField: 'content', @@ -95,7 +98,29 @@ Ext.define('PVE.sdn.ZoneContentView', { Ext.define('pve-sdnzone-content', { extend: 'Ext.data.Model', fields: [ - 'vnet', 'status', 'statusmsg', + { + name: 'iface', + convert: function(value, record) { + //map local vmbr to vnet + if (record.data.iface) { + record.data.vnet = record.data.iface; + } + return value; + }, + }, + { + name: 'comments', + convert: function(value, record) { + //map local vmbr comments to vnet alias + if (record.data.comments) { + record.data.alias = record.data.comments; + } + return value; + }, + }, + 'vnet', + 'status', + 'statusmsg', { name: 'text', convert: function(value, record) { -- 2.30.2 ^ permalink raw reply [flat|nested] 18+ messages in thread
* [pve-devel] [PATCH pve-access-control 2/2] rpcenvironnment: add check_sdn_bridge 2023-06-04 23:37 [pve-devel] [PATCH-SERIE pve-access-control/pve-manager/qemu-server] check permissions on local bridge Alexandre Derumier ` (3 preceding siblings ...) 2023-06-04 23:37 ` [pve-devel] [PATCH v2 pve-manager 2/3] add permissions management for "localnetwork" zone Alexandre Derumier @ 2023-06-04 23:37 ` Alexandre Derumier 2023-06-05 10:12 ` Fabian Grünbichler 2023-06-04 23:37 ` [pve-devel] [PATCH v2 pve-manager 3/3] api2: network: check permissions for local bridges Alexandre Derumier 2023-06-05 10:13 ` [pve-devel] [PATCH-SERIE pve-access-control/pve-manager/qemu-server] check permissions on local bridge Fabian Grünbichler 6 siblings, 1 reply; 18+ messages in thread From: Alexandre Derumier @ 2023-06-04 23:37 UTC (permalink / raw) To: pve-devel check if user have access to 1 vlan of the bridge or the bridge itself Signed-off-by: Alexandre Derumier <aderumier@odiso.com> --- src/PVE/RPCEnvironment.pm | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/PVE/RPCEnvironment.pm b/src/PVE/RPCEnvironment.pm index 8586938..fb010cc 100644 --- a/src/PVE/RPCEnvironment.pm +++ b/src/PVE/RPCEnvironment.pm @@ -324,6 +324,23 @@ sub check_full { } } +sub check_sdn_bridge { + my ($self, $username, $path, $privs, $noerr) = @_; + + my $cfg = $self->{user_cfg}; + my $bridge_acl = PVE::AccessControl::find_acl_tree_node($cfg->{acl_root}, $path); + if ($bridge_acl) { + my $vlans = $bridge_acl->{children}; + for my $vlan (keys %$vlans) { + my $vlanpath = "$path/$vlan"; + return 1 if $self->check_any($username, $vlanpath, $privs, $noerr); + } + # check propagate on bridge itself + return 1 if $self->check_any($username, $path, $privs, $noerr); + } + return; +} + sub check_user_enabled { my ($self, $user, $noerr) = @_; -- 2.30.2 ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [pve-devel] [PATCH pve-access-control 2/2] rpcenvironnment: add check_sdn_bridge 2023-06-04 23:37 ` [pve-devel] [PATCH pve-access-control 2/2] rpcenvironnment: add check_sdn_bridge Alexandre Derumier @ 2023-06-05 10:12 ` Fabian Grünbichler 2023-06-06 12:15 ` DERUMIER, Alexandre 0 siblings, 1 reply; 18+ messages in thread From: Fabian Grünbichler @ 2023-06-05 10:12 UTC (permalink / raw) To: Proxmox VE development discussion On June 5, 2023 1:37 am, Alexandre Derumier wrote: > check if user have access to 1 vlan of the bridge > or the bridge itself > > Signed-off-by: Alexandre Derumier <aderumier@odiso.com> > --- > src/PVE/RPCEnvironment.pm | 17 +++++++++++++++++ > 1 file changed, 17 insertions(+) > > diff --git a/src/PVE/RPCEnvironment.pm b/src/PVE/RPCEnvironment.pm > index 8586938..fb010cc 100644 > --- a/src/PVE/RPCEnvironment.pm > +++ b/src/PVE/RPCEnvironment.pm > @@ -324,6 +324,23 @@ sub check_full { > } > } > > +sub check_sdn_bridge { > + my ($self, $username, $path, $privs, $noerr) = @_; instead of $path, passing in just the bridge ID would also work, and maybe be a nicer interface.. > + > + my $cfg = $self->{user_cfg}; > + my $bridge_acl = PVE::AccessControl::find_acl_tree_node($cfg->{acl_root}, $path); > + if ($bridge_acl) { > + my $vlans = $bridge_acl->{children}; > + for my $vlan (keys %$vlans) { > + my $vlanpath = "$path/$vlan"; > + return 1 if $self->check_any($username, $vlanpath, $privs, $noerr); > + } > + # check propagate on bridge itself > + return 1 if $self->check_any($username, $path, $privs, $noerr); this doesn't actually check propagation though? for that you could either: - use $self->permissions (it returns the propagate bit) - query a non-existing vlan child path with check_any > + } > + return; > +} > + > sub check_user_enabled { > my ($self, $user, $noerr) = @_; > > -- > 2.30.2 > > > _______________________________________________ > pve-devel mailing list > pve-devel@lists.proxmox.com > https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel > > > ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [pve-devel] [PATCH pve-access-control 2/2] rpcenvironnment: add check_sdn_bridge 2023-06-05 10:12 ` Fabian Grünbichler @ 2023-06-06 12:15 ` DERUMIER, Alexandre 2023-06-06 12:37 ` Fabian Grünbichler 0 siblings, 1 reply; 18+ messages in thread From: DERUMIER, Alexandre @ 2023-06-06 12:15 UTC (permalink / raw) To: pve-devel > > + # check propagate on bridge itself > > + return 1 if $self->check_any($username, $path, $privs, > > $noerr); > > this doesn't actually check propagation though? for that you could > either: > - use $self->permissions (it returns the propagate bit) > - query a non-existing vlan child path with check_any > > do we really need to check propagation ? Here, we want to check if user have permission to the bridge, if user have an acl on a vlan of the bridge or if user have access to the bridge (propagate or not). for example, if I check with a dummy vlanid ,/sdn/zones/myzone/vnet1/0, It'll be ok if user have propagate on vnet1, but not if user don't have propagate ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [pve-devel] [PATCH pve-access-control 2/2] rpcenvironnment: add check_sdn_bridge 2023-06-06 12:15 ` DERUMIER, Alexandre @ 2023-06-06 12:37 ` Fabian Grünbichler 0 siblings, 0 replies; 18+ messages in thread From: Fabian Grünbichler @ 2023-06-06 12:37 UTC (permalink / raw) To: Proxmox VE development discussion On June 6, 2023 2:15 pm, DERUMIER, Alexandre wrote: >> > + # check propagate on bridge itself >> > + return 1 if $self->check_any($username, $path, $privs, >> > $noerr); >> >> this doesn't actually check propagation though? for that you could >> either: >> - use $self->permissions (it returns the propagate bit) >> - query a non-existing vlan child path with check_any >> >> > > do we really need to check propagation ? > > Here, we want to check if user have permission to the bridge, > > if user have an acl on a vlan of the bridge > > or > > if user have access to the bridge (propagate or not). > > for example, if I check with a dummy vlanid ,/sdn/zones/myzone/vnet1/0, > > It'll be ok if user have propagate on vnet1, but not if user > don't have propagate you are right, we don't need to check for propagation here. so basically we have two parts - maybe those could be added as a comment, and another higher-level one for the whole helper to make it clear what it actually checks: # checks whether user has $privs on the bridge/vnet in any fashion sub check_sdn_bridge { .. # check explicit VLAN tag ACLs .. # check bridge/vnet itself .. } and then we could also turn the order around, and check the bridge first as a fast path that does less work? ^ permalink raw reply [flat|nested] 18+ messages in thread
* [pve-devel] [PATCH v2 pve-manager 3/3] api2: network: check permissions for local bridges 2023-06-04 23:37 [pve-devel] [PATCH-SERIE pve-access-control/pve-manager/qemu-server] check permissions on local bridge Alexandre Derumier ` (4 preceding siblings ...) 2023-06-04 23:37 ` [pve-devel] [PATCH pve-access-control 2/2] rpcenvironnment: add check_sdn_bridge Alexandre Derumier @ 2023-06-04 23:37 ` Alexandre Derumier 2023-06-05 10:13 ` [pve-devel] [PATCH-SERIE pve-access-control/pve-manager/qemu-server] check permissions on local bridge Fabian Grünbichler 6 siblings, 0 replies; 18+ messages in thread From: Alexandre Derumier @ 2023-06-04 23:37 UTC (permalink / raw) To: pve-devel always check permissions, also when not filtered Signed-off-by: Alexandre Derumier <aderumier@odiso.com> --- PVE/API2/Network.pm | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/PVE/API2/Network.pm b/PVE/API2/Network.pm index b3faba1a..55a37c44 100644 --- a/PVE/API2/Network.pm +++ b/PVE/API2/Network.pm @@ -240,23 +240,17 @@ __PACKAGE__->register_method({ if (my $tfilter = $param->{type}) { my $vnets; - my $vnet_cfg; - my $can_access_vnet = sub { # only matters for the $have_sdn case, checked implict - return 1 if $authuser eq 'root@pam' || !defined($vnets); - return 1 if !defined(PVE::Network::SDN::Vnets::sdn_vnets_config($vnet_cfg, $_[0], 1)); # not a vnet - $rpcenv->check_any($authuser, "/sdn/vnets/$_[0]", ['SDN.Audit', 'SDN.Allocate'], 1) - }; if ($have_sdn && $param->{type} eq 'any_bridge') { $vnets = PVE::Network::SDN::get_local_vnets(); # returns already access-filtered - $vnet_cfg = PVE::Network::SDN::Vnets::config(); } 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')); - - delete $ifaces->{$k} if !($match && $can_access_vnet->($k)); + my $match = ($param->{type} eq $type) || ( + ($param->{type} =~ /^any(_local)?_bridge$/) && + ($type eq 'bridge' || $type eq 'OVSBridge')); + delete $ifaces->{$k} if !$match; } if (defined($vnets)) { @@ -264,6 +258,17 @@ __PACKAGE__->register_method({ } } + #always check bridge access + my $can_access_vnet = sub { + return 1 if $authuser eq 'root@pam'; + return 1 if $rpcenv->check_any($authuser, "/sdn/zones/localnetwork", ['SDN.Audit', 'SDN.Allocate'], 1); + return 1 if $rpcenv->check_sdn_bridge($authuser, "/sdn/vnets/$_[0]", ['SDN.Audit', 'SDN.Allocate'], 1); + }; + for my $k (sort keys $ifaces->%*) { + my $type = $ifaces->{$k}->{type}; + delete $ifaces->{$k} if ($type eq 'bridge' || $type eq 'OVSBridge') && !$can_access_vnet->($k); + } + return PVE::RESTHandler::hash_to_array($ifaces, 'iface'); }}); -- 2.30.2 ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [pve-devel] [PATCH-SERIE pve-access-control/pve-manager/qemu-server] check permissions on local bridge 2023-06-04 23:37 [pve-devel] [PATCH-SERIE pve-access-control/pve-manager/qemu-server] check permissions on local bridge Alexandre Derumier ` (5 preceding siblings ...) 2023-06-04 23:37 ` [pve-devel] [PATCH v2 pve-manager 3/3] api2: network: check permissions for local bridges Alexandre Derumier @ 2023-06-05 10:13 ` Fabian Grünbichler 2023-06-06 5:32 ` DERUMIER, Alexandre 6 siblings, 1 reply; 18+ messages in thread From: Fabian Grünbichler @ 2023-06-05 10:13 UTC (permalink / raw) To: Proxmox VE development discussion On June 5, 2023 1:37 am, Alexandre Derumier wrote: > add vnet/localbridge permissions management > > Hi, > as we has discuted some weeks ago, > this patche serie introduce management of acl for vnets && local bridges > > I have reuse current sdn permissions path, to have common paths > > /sdn/vnets/<zone>/<vnet> > > where the local vmbr are in a virtual "localnetwork" zone > > /sdn/vnets/local/<vnet> > > Vlans permissions are also handled with > /sdn/vnets/<zone>/<vnet>/<tag> these paths don't match the patches ;) if the paths were like this, then we could go one step further and admins could set propagate on the zone to hand out access to the full zone, including all vnets *and* vlan tags, and we could just check the vnet (or vnet+tag), and the zone would be implicitly checked as well (by virtue of traversing the ACL path). we'd need to check for consistency of zone+vnet when checking ACLs though, which is not required right now. > > if user have permissions on the zone, he have access to all vnets/vlan > if user have permissions on the vnet/tag, he have access to only the specific vlan. > if user have permissions on the vnet, he have access to all vlans of the vnet these last two I'd do differently. permission on vnet/tag => permission to use that vlan permission on vnet => permission to use the vnet/bridge (without tag) if I want to give permission for all tags, I can simply give out the role on vnet with propagation. since the permissions are only checked when (re)configuring a guest, it doesn't matter that that check is a bit expensive/potentially checking a lot of paths.. > > I have reworked the sdn zone panel from the tree, to manage permissions > on displayed vnets. > > some screenshots: > > https://mutulin1.odiso.net/sdnzone-perm.png > https://mutulin1.odiso.net/localzone-perm.png I didn't check the GUI patches in detail yet, but IMHO they are also less important right now (they are only a convenience feature for the new feature of configuring VLAN access). we'd like to get the basic patches in place this week if possible, if that is too soon I can also fold in some of my suggestions as follow-ups, just tell me what works for you! > for proxmox7: (for users be able to add permissions before upgrade to pve8) > pve-access-control: patch1 (to new /vnet/vlan path) > pve-manager : patch1-2 for the new gui the access control changes should be enough, it's always possible to set the ACLs using the regular ACL GUI and/or `pveum`. it might make sense to have at least the local bridge ACL path (for the zone, or for the zone and the bridges?) in the regular ACL selectors in 7.x as well, if we pull in something in pve-manager, than IMHO it should be that, not the full-flegded new panels. I do think we need a second pve-access-control patch though (for a new SDN.Use privilege and corresponding role), that also needs to go into 7.x > changelog v2: > - use /vnets/vlan instead /vnets.vlan > - rework the bridge filtering when user have access only to a specific vlan > - api2 network: always check bridge access if no filter is defined > > todo: > - add permissions on clone/restore ? > > > > pve-access-control: > > Alexandre Derumier (2): > access control: add /sdn/vnets/<vnet>/<vlan> path > rpcenvironnment: add check_sdn_bridge > > src/PVE/AccessControl.pm | 1 + > src/PVE/RPCEnvironment.pm | 17 +++++++++++++++++ > 2 files changed, 18 insertions(+) > > > pve-manager: > > Alexandre Derumier (3): > add vnet permissions panel > add permissions management for "localnetwork" zone > api2: network: check permissions for local bridges > > PVE/API2/Cluster.pm | 12 ++ > PVE/API2/Network.pm | 26 ++- > www/manager6/Makefile | 2 + > www/manager6/sdn/Browser.js | 17 +- > www/manager6/sdn/VnetACLView.js | 299 +++++++++++++++++++++++++++ > www/manager6/sdn/ZoneContentPanel.js | 41 ++++ > www/manager6/sdn/ZoneContentView.js | 52 ++++- > 7 files changed, 420 insertions(+), 29 deletions(-) > create mode 100644 www/manager6/sdn/VnetACLView.js > create mode 100644 www/manager6/sdn/ZoneContentPanel.js > > qemu-server: > > Alexandre Derumier (1): > api2: add check_bridge_access for create/update vm > > PVE/API2/Qemu.pm | 38 +++++++++++++++++++++++++++++++++++++- > 1 file changed, 37 insertions(+), 1 deletion(-) > > > -- > 2.30.2 > > > _______________________________________________ > pve-devel mailing list > pve-devel@lists.proxmox.com > https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel > > > ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [pve-devel] [PATCH-SERIE pve-access-control/pve-manager/qemu-server] check permissions on local bridge 2023-06-05 10:13 ` [pve-devel] [PATCH-SERIE pve-access-control/pve-manager/qemu-server] check permissions on local bridge Fabian Grünbichler @ 2023-06-06 5:32 ` DERUMIER, Alexandre 2023-06-06 6:54 ` DERUMIER, Alexandre 2023-06-06 7:31 ` Fabian Grünbichler 0 siblings, 2 replies; 18+ messages in thread From: DERUMIER, Alexandre @ 2023-06-06 5:32 UTC (permalink / raw) To: pve-devel Le lundi 05 juin 2023 à 12:13 +0200, Fabian Grünbichler a écrit : > On June 5, 2023 1:37 am, Alexandre Derumier wrote: > > add vnet/localbridge permissions management > > > > Hi, > > as we has discuted some weeks ago, > > this patche serie introduce management of acl for vnets && local > > bridges > > > > I have reuse current sdn permissions path, to have common paths > > > > /sdn/vnets/<zone>/<vnet> > > > > where the local vmbr are in a virtual "localnetwork" zone > > > > /sdn/vnets/local/<vnet> > > > > Vlans permissions are also handled with > > /sdn/vnets/<zone>/<vnet>/<tag> > > these paths don't match the patches ;) > > if the paths were like this, then we could go one step further and > admins could set propagate on the zone to hand out access to the full > zone, including all vnets *and* vlan tags, and we could just check > the > vnet (or vnet+tag), and the zone would be implicitly checked as well > (by > virtue of traversing the ACL path). > > we'd need to check for consistency of zone+vnet when checking ACLs > though, which is not required right now. oh yes, I think it was my first try. currently the vnets id are unique (and possibly (at least in sdn) user could move the vnet between zones. (not implemented, but technically, it'll work, and ifreload is able to online replug the vnet with vm guest running). I don't think it something that user want to do regulary, so maybe it's not a problem to use /zone/vnet/tag and It's more secure if users need to recheck the acl. > > > > > if user have permissions on the zone, he have access to all > > vnets/vlan > > if user have permissions on the vnet/tag, he have access to only > > the specific vlan. > > if user have permissions on the vnet, he have access to all vlans > > of the vnet > > these last two I'd do differently. > > permission on vnet/tag => permission to use that vlan > permission on vnet => permission to use the vnet/bridge (without tag) > yes, make sense > if I want to give permission for all tags, I can simply give out the > role on vnet with propagation. since the permissions are only checked > when (re)configuring a guest, it doesn't matter that that check is a > bit > expensive/potentially checking a lot of paths.. > > > > > I have reworked the sdn zone panel from the tree, to manage > > permissions > > on displayed vnets. > > > > some screenshots: > > > I didn't check the GUI patches in detail yet, but IMHO they are also > less important right now (they are only a convenience feature for the > new feature of configuring VLAN access). Note that the only way currently to create them for local bridge is in the datacenter permissions panel. (permissions on sdn zone can already be done globally). The gui add support for permissions on both vnet && vlan. (and new localnetwork zone) > > we'd like to get the basic patches in place this week if possible, if > that is too soon I can also fold in some of my suggestions as > follow-ups, just tell me what works for you! > > > for proxmox7: (for users be able to add permissions before upgrade > > to pve8) > > pve-access-control: patch1 (to new /vnet/vlan path) > > pve-manager : patch1-2 for the new gui > > the access control changes should be enough, it's always possible to > set > the ACLs using the regular ACL GUI and/or `pveum`. it might make > sense > ok, no problem. (Some doc before upgrade should be enough) > to have at least the local bridge ACL path (for the zone, or for the > zone and the bridges?) in the regular ACL selectors in 7.x as well, > if > we pull in something in pve-manager, than IMHO it should be that, not > the full-flegded new panels. I'll look to rewrok the selector, vnets are not yet displayed. (only sdn zones, and localnetwork zone is also not displayed ) > > I do think we need a second pve-access-control patch though (for a > new > SDN.Use privilege and corresponding role), that also needs to go into > 7.x ok. (I was not sure if Audit was enough, but SDN.Use make sense indeed). > > > changelog v2: > > - use /vnets/vlan instead /vnets.vlan > > - rework the bridge filtering when user have access only to a > > specific vlan > > - api2 network: always check bridge access if no filter is defined > > > > todo: > > - add permissions on clone/restore ? > > > > > > > > pve-access-control: > > > > Alexandre Derumier (2): > > access control: add /sdn/vnets/<vnet>/<vlan> path > > rpcenvironnment: add check_sdn_bridge > > > > src/PVE/AccessControl.pm | 1 + > > src/PVE/RPCEnvironment.pm | 17 +++++++++++++++++ > > 2 files changed, 18 insertions(+) > > > > > > pve-manager: > > > > Alexandre Derumier (3): > > add vnet permissions panel > > add permissions management for "localnetwork" zone > > api2: network: check permissions for local bridges > > > > PVE/API2/Cluster.pm | 12 ++ > > PVE/API2/Network.pm | 26 ++- > > www/manager6/Makefile | 2 + > > www/manager6/sdn/Browser.js | 17 +- > > www/manager6/sdn/VnetACLView.js | 299 > > +++++++++++++++++++++++++++ > > www/manager6/sdn/ZoneContentPanel.js | 41 ++++ > > www/manager6/sdn/ZoneContentView.js | 52 ++++- > > 7 files changed, 420 insertions(+), 29 deletions(-) > > create mode 100644 www/manager6/sdn/VnetACLView.js > > create mode 100644 www/manager6/sdn/ZoneContentPanel.js > > > > qemu-server: > > > > Alexandre Derumier (1): > > api2: add check_bridge_access for create/update vm > > > > PVE/API2/Qemu.pm | 38 +++++++++++++++++++++++++++++++++++++- > > 1 file changed, 37 insertions(+), 1 deletion(-) > > > > > > -- > > 2.30.2 > > > > > > _______________________________________________ > > pve-devel mailing list > > pve-devel@lists.proxmox.com > > https://antiphishing.cetsi.fr/proxy/v3?i=d1l4NXNNaWE4SWZqU0dLWcuTfdxEd98NfWIp9dma5kY&r=MXJUa0FrUVJqc1UwYWxNZ-tmXdGQOM0bQR6kYEgvrmGZrgAumkB5XEgd10kSzvIx&f=c2xMdVN4Smh2R2tOZDdIRKCk7WEocHpTPMerT1Q-Aq5qwr8l2xvAWuOGvFsV3frp2oSAgxNUQCpJDHp2iUmTWg&u=https%3A//lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel&k=fjzS > > > > > > > > > _______________________________________________ > pve-devel mailing list > pve-devel@lists.proxmox.com > https://antiphishing.cetsi.fr/proxy/v3?i=d1l4NXNNaWE4SWZqU0dLWcuTfdxEd98NfWIp9dma5kY&r=MXJUa0FrUVJqc1UwYWxNZ-tmXdGQOM0bQR6kYEgvrmGZrgAumkB5XEgd10kSzvIx&f=c2xMdVN4Smh2R2tOZDdIRKCk7WEocHpTPMerT1Q-Aq5qwr8l2xvAWuOGvFsV3frp2oSAgxNUQCpJDHp2iUmTWg&u=https%3A//lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel&k=fjzS > ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [pve-devel] [PATCH-SERIE pve-access-control/pve-manager/qemu-server] check permissions on local bridge 2023-06-06 5:32 ` DERUMIER, Alexandre @ 2023-06-06 6:54 ` DERUMIER, Alexandre 2023-06-06 7:43 ` Fabian Grünbichler 2023-06-06 7:31 ` Fabian Grünbichler 1 sibling, 1 reply; 18+ messages in thread From: DERUMIER, Alexandre @ 2023-06-06 6:54 UTC (permalink / raw) To: pve-devel Le mardi 06 juin 2023 à 05:32 +0000, DERUMIER, Alexandre a écrit : > > to have at least the local bridge ACL path (for the zone, or for > > the > > zone and the bridges?) in the regular ACL selectors in 7.x as well, > > if > > we pull in something in pve-manager, than IMHO it should be that, > > not > > the full-flegded new panels. > I'll look to rewrok the selector, vnets are not yet displayed. (only > sdn zones, and localnetwork zone is also not displayed ) Looking at that, currently the pathselector is filled from cluster ressources. I really don't known if we want to add all vnets to the cluster ressources api. (as we don't really want to expose them in the tree anyway, like a disk from a datastore is not exposed. User could have a lot bridges, and the ressource json can be already big) User could still add manually the bridge in the path if needed. User could still use the new panel for easy add more granular permissions on bridge/vlan. ? ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [pve-devel] [PATCH-SERIE pve-access-control/pve-manager/qemu-server] check permissions on local bridge 2023-06-06 6:54 ` DERUMIER, Alexandre @ 2023-06-06 7:43 ` Fabian Grünbichler 0 siblings, 0 replies; 18+ messages in thread From: Fabian Grünbichler @ 2023-06-06 7:43 UTC (permalink / raw) To: Proxmox VE development discussion On June 6, 2023 8:54 am, DERUMIER, Alexandre wrote: > Le mardi 06 juin 2023 à 05:32 +0000, DERUMIER, Alexandre a écrit : >> > to have at least the local bridge ACL path (for the zone, or for >> > the >> > zone and the bridges?) in the regular ACL selectors in 7.x as well, >> > if >> > we pull in something in pve-manager, than IMHO it should be that, >> > not >> > the full-flegded new panels. >> I'll look to rewrok the selector, vnets are not yet displayed. (only >> sdn zones, and localnetwork zone is also not displayed ) > > Looking at that, > currently the pathselector is filled from cluster ressources. > > I really don't known if we want to add all vnets to the cluster > ressources api. (as we don't really want to expose them in the tree > anyway, like a disk from a datastore is not exposed. User could have a > lot bridges, and the ressource json can be already big) > > User could still add manually the bridge in the path if needed. > > User could still use the new panel for easy add more granular > permissions on bridge/vlan. I think for PVE 7, we mainly want to provide an easy way to stay compatible to the old behaviour, that would basically mean: pveum acl modify /sdn/zones/localnetwork --groups XXX --users YYY --tokens ZZZ --roles PVESDNUser rinse repeat for any SDN zones if you have any. for the GUI, the least invasive change would be to just add a hardcoded ACL selector entry for /sdn/zones/localnetwork (the rest can be done manually via the GUI or pveum). note that existing guests continue to work fine, it's just - creating new ones (from scratch, backup or via clone) - modifying any virtual nics on any guests that require the permissions. PVEAdmins and existing PVESDNAdmins would already have the required permissions anyway (Administrator as well). so this would mostly affect PVEVMAdmins and custom roles. ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [pve-devel] [PATCH-SERIE pve-access-control/pve-manager/qemu-server] check permissions on local bridge 2023-06-06 5:32 ` DERUMIER, Alexandre 2023-06-06 6:54 ` DERUMIER, Alexandre @ 2023-06-06 7:31 ` Fabian Grünbichler 1 sibling, 0 replies; 18+ messages in thread From: Fabian Grünbichler @ 2023-06-06 7:31 UTC (permalink / raw) To: Proxmox VE development discussion On June 6, 2023 7:32 am, DERUMIER, Alexandre wrote: > Le lundi 05 juin 2023 à 12:13 +0200, Fabian Grünbichler a écrit : >> On June 5, 2023 1:37 am, Alexandre Derumier wrote: >> > add vnet/localbridge permissions management >> > >> > Hi, >> > as we has discuted some weeks ago, >> > this patche serie introduce management of acl for vnets && local >> > bridges >> > >> > I have reuse current sdn permissions path, to have common paths >> > >> > /sdn/vnets/<zone>/<vnet> >> > >> > where the local vmbr are in a virtual "localnetwork" zone >> > >> > /sdn/vnets/local/<vnet> >> > >> > Vlans permissions are also handled with >> > /sdn/vnets/<zone>/<vnet>/<tag> >> >> these paths don't match the patches ;) >> >> if the paths were like this, then we could go one step further and >> admins could set propagate on the zone to hand out access to the full >> zone, including all vnets *and* vlan tags, and we could just check >> the >> vnet (or vnet+tag), and the zone would be implicitly checked as well >> (by >> virtue of traversing the ACL path). >> >> we'd need to check for consistency of zone+vnet when checking ACLs >> though, which is not required right now. > oh yes, I think it was my first try. > > currently the vnets id are unique (and possibly (at least in sdn) user > could move the vnet between zones. (not implemented, but technically, > it'll work, and ifreload is able to online replug the vnet with vm > guest running). > > I don't think it something that user want to do regulary, so maybe it's > not a problem to use /zone/vnet/tag and It's more secure if users need > to recheck the acl. I just wanted to mention it since it caught my eye, treating zones and vnets as independent also makes sense, it should just be consistent :) there are pros and cons for both approaches: - pro for current approach: -- vnets can be moved/converted between zones, ACLs stay valid -- no extra checks needed - pro for zone/vnet/.. approach: -- propagation from zone to vnet is possible without manually doing it at the check site -- binding between zone and vnet is enforced at the ACL level ^ permalink raw reply [flat|nested] 18+ messages in thread
end of thread, other threads:[~2023-06-06 12:37 UTC | newest] Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2023-06-04 23:37 [pve-devel] [PATCH-SERIE pve-access-control/pve-manager/qemu-server] check permissions on local bridge Alexandre Derumier 2023-06-04 23:37 ` [pve-devel] [PATCH pve-access-control 1/2] access control: add /sdn/vnets/<vnet>/<vlan> path Alexandre Derumier 2023-06-04 23:37 ` [pve-devel] [PATCH v2 pve-manager 1/3] add vnet permissions panel Alexandre Derumier 2023-06-04 23:37 ` [pve-devel] [PATCH v2 qemu-server 1/1] api2: add check_bridge_access for create/update vm Alexandre Derumier 2023-06-05 7:38 ` Thomas Lamprecht 2023-06-06 4:20 ` DERUMIER, Alexandre 2023-06-05 10:12 ` Fabian Grünbichler 2023-06-04 23:37 ` [pve-devel] [PATCH v2 pve-manager 2/3] add permissions management for "localnetwork" zone Alexandre Derumier 2023-06-04 23:37 ` [pve-devel] [PATCH pve-access-control 2/2] rpcenvironnment: add check_sdn_bridge Alexandre Derumier 2023-06-05 10:12 ` Fabian Grünbichler 2023-06-06 12:15 ` DERUMIER, Alexandre 2023-06-06 12:37 ` Fabian Grünbichler 2023-06-04 23:37 ` [pve-devel] [PATCH v2 pve-manager 3/3] api2: network: check permissions for local bridges Alexandre Derumier 2023-06-05 10:13 ` [pve-devel] [PATCH-SERIE pve-access-control/pve-manager/qemu-server] check permissions on local bridge Fabian Grünbichler 2023-06-06 5:32 ` DERUMIER, Alexandre 2023-06-06 6:54 ` DERUMIER, Alexandre 2023-06-06 7:43 ` Fabian Grünbichler 2023-06-06 7:31 ` Fabian Grünbichler
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox