How to configure fine grained control of Virtual Machines in Cockpit
Environment
- Red Hat Enterprise Linux 8.x
- cockpit-machines-238.2-1.el8.noarch
- libvirt-6.0.0-35.module+el8.4.0+10230+7a9b21e4.x86_64
- libvirt-dbus-1.3.0-2.module+el8.3.0+6423+e4cb6418.x86_64
Issue
- We want to allow some administrative actions on VMs to users connecting through Cockpit.
- How to configure a read-only user in Cockpit who can view VM resources and access VM consoles, but cannot perform any mutating actions (e.g., stop, restart, delete, or create VMs)?
Resolution
-
To interact with the
org.libvirtD-Bus service, the user(s) must be members of thelibvirtgroup on the host. This permits the initial connection to the local libvirt daemon socket.$usermod -aG libvirt <username> -
Example1: To allow the members of the group
powerusersall VM actions except Shutdown and Power off, create the following DBUS policy file/etc/dbus-1/system.d/org.libvirt.conf:<?xml version="1.0"?> <!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd"> <busconfig> <policy group="powerusers"> <allow send_destination="org.libvirt"></allow> <deny send_destination="org.libvirt" send_interface="org.libvirt.Domain" send_member="Destroy"></deny> <deny send_destination="org.libvirt" send_interface="org.libvirt.Domain" send_member="Shutdown"></deny> </policy> </busconfig> -
Example2: To restrict a specific user (e.g.,
readonly_user) so they can only view VM status, metadata, and access the graphical console (denying all mutating actions), create the following custom policy file/etc/dbus-1/system.d/org.libvirt-custom.conf:<?xml version="1.0"?> <!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd"> <busconfig> <policy user="readonly_user"> <!-- default: deny all mutating Domain/Network/StoragePool/NodeDevice calls --> <deny send_destination="org.libvirt" send_interface="org.libvirt.Domain"/> <deny send_destination="org.libvirt" send_interface="org.libvirt.Network"/> <deny send_destination="org.libvirt" send_interface="org.libvirt.StoragePool"/> <deny send_destination="org.libvirt" send_interface="org.libvirt.NodeDevice"/> <!-- explicit allow: read-only + console access --> <allow send_destination="org.libvirt" send_interface="org.libvirt.Domain" send_member="GetXMLDesc"/> <allow send_destination="org.libvirt" send_interface="org.libvirt.Domain" send_member="GetInfo"/> <allow send_destination="org.libvirt" send_interface="org.libvirt.Domain" send_member="GetState"/> <allow send_destination="org.libvirt" send_interface="org.libvirt.Domain" send_member="GetStats"/> <allow send_destination="org.libvirt" send_interface="org.libvirt.Domain" send_member="OpenGraphics"/> <allow send_destination="org.libvirt" send_interface="org.libvirt.Domain" send_member="OpenConsole"/> </policy> </busconfig>
Note: To apply this rule to a group instead of a single user, replace <policy user="readonly_user"> with <policy group="readonly_group">.
-
After configuring either policy, reload the D-Bus service and terminate any active Cockpit bridges for the target user to apply the updated permissions:
$systemctl reload dbus $pkill -u <username> -f cockpit-bridge -
Have the user log out of Cockpit, clear their browser cache, and log back in.
Root Cause
- All actions performed by Cockpit are calls to libvirt's DBUS API.
- The default DBUS policy is defined in
/usr/share/dbus-1/system.d/org.libvirt.confand only allows access to root, the libvirt group and the libvirtdbus user (the helper program that exposes the DBUS API).
Diagnostic Steps
Use this command to monitor what DBUS calls Cockpit does:
# dbus-monitor --system destination='org.libvirt'
This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.