[libvirt-users] Libvirt access control drivers

Hello! According to the documentation access control drivers are not in really "good condition". There is a polkit, but it can distinguish users only according the pid. However, I have met some articles about more fine-grained control and about selinux drivers for libvirt? So, what is the status now? Should I implement something by myself if I want access based on login, are their instructions how to write these drivers or there is smth already?

On Wed, May 09, 2018 at 09:46:28AM +0300, Anastasiya Ruzhanskaya wrote:
Hello! According to the documentation access control drivers are not in really "good condition". There is a polkit, but it can distinguish users only according the pid. However, I have met some articles about more fine-grained control and about selinux drivers for libvirt? So, what is the status now? Should I implement something by myself if I want access based on login, are their instructions how to write these drivers or there is smth already?
The polkit access control driver is the only one we support, and it is not something that end users can replace as this is not a public plugin system. Any alternate impl would have to be part of libvirt core. I'm not sure what docs you are referring to, but the polkit driver is in perfectly good condition. It is not restricted to just checking PIDs, in fact PID is largely irrelevant - user name and group membership are the important things to check. Ther is an example in the source tree at examples/polkit/libvirt-acl.rules showing a simple RBAC approach to using polkit. Regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|

I read this page https://libvirt.org/aclpolkit.html And it is written :"At this point in time, the only attribute provided by libvirt to identify the user invoking the operation is the PID of the client program. This means that the polkit access control driver is only useful if connections to libvirt are restricted to its UNIX domain socket." 2018-05-09 11:00 GMT+03:00 Daniel P. Berrangé <berrange@redhat.com>:
Hello! According to the documentation access control drivers are not in really "good condition". There is a polkit, but it can distinguish users only according the pid. However, I have met some articles about more fine-grained control and about selinux drivers for libvirt? So, what is
On Wed, May 09, 2018 at 09:46:28AM +0300, Anastasiya Ruzhanskaya wrote: the
status now? Should I implement something by myself if I want access based on login, are their instructions how to write these drivers or there is smth already?
The polkit access control driver is the only one we support, and it is not something that end users can replace as this is not a public plugin system. Any alternate impl would have to be part of libvirt core.
I'm not sure what docs you are referring to, but the polkit driver is in perfectly good condition. It is not restricted to just checking PIDs, in fact PID is largely irrelevant - user name and group membership are the important things to check. Ther is an example in the source tree at examples/polkit/libvirt-acl.rules showing a simple RBAC approach to using polkit.
Regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/ dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/ dberrange :|

On Wed, May 09, 2018 at 11:13:01AM +0300, Anastasiya Ruzhanskaya wrote:
I read this page https://libvirt.org/aclpolkit.html And it is written :"At this point in time, the only attribute provided by libvirt to identify the user invoking the operation is the PID of the client program. This means that the polkit access control driver is only useful if connections to libvirt are restricted to its UNIX domain socket."
You're mis-interpreted what that means. Libvirt provides the PID to polkit (well actually pid + starttime), polkit uses this to identify the process and determine its username and group membership, which is then used to make access control decisions. Regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|

Ok, excuse me for misunderstanding, how it is possible then to set up access control when I use remote connection to KVM ( not in UNIX domain)? Is there any way within libvirt, maybe based on authentication or certificates? 2018-05-09 11:14 GMT+03:00 Daniel P. Berrangé <berrange@redhat.com>:
On Wed, May 09, 2018 at 11:13:01AM +0300, Anastasiya Ruzhanskaya wrote:
I read this page https://libvirt.org/aclpolkit.html And it is written :"At this point in time, the only attribute provided by libvirt to identify the user invoking the operation is the PID of the client program. This means that the polkit access control driver is only useful if connections to libvirt are restricted to its UNIX domain socket."
You're mis-interpreted what that means. Libvirt provides the PID to polkit (well actually pid + starttime), polkit uses this to identify the process and determine its username and group membership, which is then used to make access control decisions.
Regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/ dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/ dberrange :|

On Wed, May 09, 2018 at 11:21:22AM +0300, Anastasiya Ruzhanskaya wrote:
Ok, excuse me for misunderstanding, how it is possible then to set up access control when I use remote connection to KVM ( not in UNIX domain)? Is there any way within libvirt, maybe based on authentication or certificates?
Unfortunately we don't have a solution for fine grained access control when using remote TCP access. We had a feature request against polkit to allow passing it identity information such as certificate distinguished name, but that was rejected :-( Regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|

Here https://libvirt.org/acl.html is stated that you designed this access control system as pluggable. Are there any options ( even with modifying libvirt code) to plug in any custom driver? I just need to take a try and design something that will support remote access control. I am not sure if sVirt is the right thing I should look at. 2018-05-09 11:27 GMT+03:00 Daniel P. Berrangé <berrange@redhat.com>:
On Wed, May 09, 2018 at 11:21:22AM +0300, Anastasiya Ruzhanskaya wrote:
Ok, excuse me for misunderstanding, how it is possible then to set up access control when I use remote connection to KVM ( not in UNIX domain)? Is there any way within libvirt, maybe based on authentication or certificates?
Unfortunately we don't have a solution for fine grained access control when using remote TCP access. We had a feature request against polkit to allow passing it identity information such as certificate distinguished name, but that was rejected :-(
Regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/ dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/ dberrange :|

On Wed, May 09, 2018 at 11:50:33AM +0300, Anastasiya Ruzhanskaya wrote:
Here https://libvirt.org/acl.html is stated that you designed this access control system as pluggable. Are there any options ( even with modifying libvirt code) to plug in any custom driver? I just need to take a try and design something that will support remote access control. I am not sure if sVirt is the right thing I should look at.
It is pluggable in the sense that we can write more backends for it without having to refactor the rest of libvirt codebase. It isn't pluggable from POV of an end user wishing to change it - it needs contribution to libvirt code to add more options. I did look at creating an SELinux plugin many years ago, but the number of new SELinux AVs to be defined was huge and I wasn't sure the complexity of policy would be practical to handle in real world. Also, SELinux with TCP adds an extra level of complexity as you now need to figure out IPSec setup to pass SELinux labels across the network from the client. Probably what we would more usefully add is a simple RBAC based module natively in libvirt.
2018-05-09 11:27 GMT+03:00 Daniel P. Berrangé <berrange@redhat.com>:
On Wed, May 09, 2018 at 11:21:22AM +0300, Anastasiya Ruzhanskaya wrote:
Ok, excuse me for misunderstanding, how it is possible then to set up access control when I use remote connection to KVM ( not in UNIX domain)? Is there any way within libvirt, maybe based on authentication or certificates?
Unfortunately we don't have a solution for fine grained access control when using remote TCP access. We had a feature request against polkit to allow passing it identity information such as certificate distinguished name, but that was rejected :-(
Regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/ dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/ dberrange :|
Regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|

On Wed, May 09, 2018 at 10:00:19AM +0100, Daniel P. Berrangé wrote:
On Wed, May 09, 2018 at 11:50:33AM +0300, Anastasiya Ruzhanskaya wrote:
Here https://libvirt.org/acl.html is stated that you designed this access control system as pluggable. Are there any options ( even with modifying libvirt code) to plug in any custom driver? I just need to take a try and design something that will support remote access control. I am not sure if sVirt is the right thing I should look at.
It is pluggable in the sense that we can write more backends for it without having to refactor the rest of libvirt codebase. It isn't pluggable from POV of an end user wishing to change it - it needs contribution to libvirt code to add more options.
I did look at creating an SELinux plugin many years ago, but the number of new SELinux AVs to be defined was huge and I wasn't sure the complexity of policy would be practical to handle in real world. Also, SELinux with TCP adds an extra level of complexity as you now need to figure out IPSec setup to pass SELinux labels across the network from the client.
Probably what we would more usefully add is a simple RBAC based module natively in libvirt.
I forgot to say that if you want to look at writing a new impl the code is kept in $GIT/src/access/. The current polkit impl is viraccessdriverpolkit.c. Implementing a new driver involves creating a new source file with a virAccessDriver struct that contains pointers to the methods that implement the desired logic. Regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|

Great, thanks for pointing this out. I will certainly look at it. 2018-05-09 14:41 GMT+03:00 Daniel P. Berrangé <berrange@redhat.com>:
On Wed, May 09, 2018 at 10:00:19AM +0100, Daniel P. Berrangé wrote:
On Wed, May 09, 2018 at 11:50:33AM +0300, Anastasiya Ruzhanskaya wrote:
Here https://libvirt.org/acl.html is stated that you designed this access control system as pluggable. Are there any options ( even with modifying libvirt code) to plug in any custom driver? I just need to take a try and design something that will support remote access control. I am not sure if sVirt is the right thing I should look at.
It is pluggable in the sense that we can write more backends for it without having to refactor the rest of libvirt codebase. It isn't pluggable from POV of an end user wishing to change it - it needs contribution to libvirt code to add more options.
I did look at creating an SELinux plugin many years ago, but the number of new SELinux AVs to be defined was huge and I wasn't sure the complexity of policy would be practical to handle in real world. Also, SELinux with TCP adds an extra level of complexity as you now need to figure out IPSec setup to pass SELinux labels across the network from the client.
Probably what we would more usefully add is a simple RBAC based module natively in libvirt.
I forgot to say that if you want to look at writing a new impl the code is kept in $GIT/src/access/.
The current polkit impl is viraccessdriverpolkit.c. Implementing a new driver involves creating a new source file with a virAccessDriver struct that contains pointers to the methods that implement the desired logic.
Regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/ dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/ dberrange :|

Excuse me for renewing this discussion, but I am curious if you would add new module, which will be able to process users not based on unix processes, from where do you plan to get usernames? I mean, virt-manager could give them, as there is authentication in GUI, but for example when using oVirt, none of the usernames reach libvirt through the communication between server and nodes. 2018-05-09 14:46 GMT+03:00 Anastasiya Ruzhanskaya < anastasiya.ruzhanskaya@frtk.ru>:
Great, thanks for pointing this out. I will certainly look at it.
2018-05-09 14:41 GMT+03:00 Daniel P. Berrangé <berrange@redhat.com>:
On Wed, May 09, 2018 at 10:00:19AM +0100, Daniel P. Berrangé wrote:
On Wed, May 09, 2018 at 11:50:33AM +0300, Anastasiya Ruzhanskaya wrote:
Here https://libvirt.org/acl.html is stated that you designed this access control system as pluggable. Are there any options ( even with modifying libvirt code) to plug in any custom driver? I just need to take a try and design something that will support remote access control. I am not sure if sVirt is the right thing I should look at.
It is pluggable in the sense that we can write more backends for it without having to refactor the rest of libvirt codebase. It isn't pluggable from POV of an end user wishing to change it - it needs contribution to libvirt code to add more options.
I did look at creating an SELinux plugin many years ago, but the number of new SELinux AVs to be defined was huge and I wasn't sure the complexity of policy would be practical to handle in real world. Also, SELinux with TCP adds an extra level of complexity as you now need to figure out IPSec setup to pass SELinux labels across the network from the client.
Probably what we would more usefully add is a simple RBAC based module natively in libvirt.
I forgot to say that if you want to look at writing a new impl the code is kept in $GIT/src/access/.
The current polkit impl is viraccessdriverpolkit.c. Implementing a new driver involves creating a new source file with a virAccessDriver struct that contains pointers to the methods that implement the desired logic.
Regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/ dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dber range :|

On Fri, May 11, 2018 at 04:26:36PM +0300, Anastasiya Ruzhanskaya wrote:
Excuse me for renewing this discussion, but I am curious if you would add new module, which will be able to process users not based on unix processes, from where do you plan to get usernames? I mean, virt-manager could give them, as there is authentication in GUI, but for example when using oVirt, none of the usernames reach libvirt through the communication between server and nodes.
The identity attributes would have to use information that libvirt acquires from its authentication modules. When using TLS, if client certificates are requested by libvirtd, then we can check the x509 cert distinguished name field. When using SASL, if the SASL mechanism returns a username, we can check that. NB, we would *not* be trying to check the end user that oVirt knows about, rather we are authenticating oVirt itself. To check end users defined by the higher level mgmt app would require an extra set of functionality in the public API, to allow oVirt to do user impersonation with libvirt. eg libvirt would first authenticate ovirt, ovirt would then sya it wants to impersonate "fred" and from there all APIs get checked against "fred". This gets pretty difficult though, because oVirt and most similar mgmt apps generally only have a single connection to libvirt but are doing work for 100's of different users on it. So in reality it is not very practical for libvirt to try to validate ovirt's users. Regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|

I see. I also know OpenStack uses libvirt, nova-compute has a driver for communication. I have briefly looked through these 10 thousand lines of code in overall on github for openstack's libvirt driver and didn't notice any user info as well. To make the picture full don't you know is there the same scheme there: some high level openstack api with user information and passing only actions to libvirt? Or nova-compute may carry some user info to libvirt though it's interfaces ( which you then could use in your future role-based module)? 2018-05-11 16:37 GMT+03:00 Daniel P. Berrangé <berrange@redhat.com>:
On Fri, May 11, 2018 at 04:26:36PM +0300, Anastasiya Ruzhanskaya wrote:
Excuse me for renewing this discussion, but I am curious if you would add new module, which will be able to process users not based on unix processes, from where do you plan to get usernames? I mean, virt-manager could give them, as there is authentication in GUI, but for example when using oVirt, none of the usernames reach libvirt through the communication between server and nodes.
The identity attributes would have to use information that libvirt acquires from its authentication modules. When using TLS, if client certificates are requested by libvirtd, then we can check the x509 cert distinguished name field. When using SASL, if the SASL mechanism returns a username, we can check that.
NB, we would *not* be trying to check the end user that oVirt knows about, rather we are authenticating oVirt itself.
To check end users defined by the higher level mgmt app would require an extra set of functionality in the public API, to allow oVirt to do user impersonation with libvirt. eg libvirt would first authenticate ovirt, ovirt would then sya it wants to impersonate "fred" and from there all APIs get checked against "fred".
This gets pretty difficult though, because oVirt and most similar mgmt apps generally only have a single connection to libvirt but are doing work for 100's of different users on it. So in reality it is not very practical for libvirt to try to validate ovirt's users.
Regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/ dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/ dberrange :|

On Fri, May 11, 2018 at 05:25:25PM +0300, Anastasiya Ruzhanskaya wrote:
I see. I also know OpenStack uses libvirt, nova-compute has a driver for communication. I have briefly looked through these 10 thousand lines of code in overall on github for openstack's libvirt driver and didn't notice any user info as well. To make the picture full don't you know is there the same scheme there: some high level openstack api with user information and passing only actions to libvirt? Or nova-compute may carry some user info to libvirt though it's interfaces ( which you then could use in your future role-based module)?
OpenStack has user information associated with VMs it is running, but it would be hard to pass this to libvirt because a single connection is used to manager many different users' VMs. Regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|

I actually didn't quite catch,why oVirt can't just pass user information and you could check against it? This may require to create some configuration files for libvirt about end users. What is a advantage of authenticating oVirt, and then impersonation for end user? 2018-05-11 16:37 GMT+03:00 Daniel P. Berrangé <berrange@redhat.com>:
On Fri, May 11, 2018 at 04:26:36PM +0300, Anastasiya Ruzhanskaya wrote:
Excuse me for renewing this discussion, but I am curious if you would add new module, which will be able to process users not based on unix processes, from where do you plan to get usernames? I mean, virt-manager could give them, as there is authentication in GUI, but for example when using oVirt, none of the usernames reach libvirt through the communication between server and nodes.
The identity attributes would have to use information that libvirt acquires from its authentication modules. When using TLS, if client certificates are requested by libvirtd, then we can check the x509 cert distinguished name field. When using SASL, if the SASL mechanism returns a username, we can check that.
NB, we would *not* be trying to check the end user that oVirt knows about, rather we are authenticating oVirt itself.
To check end users defined by the higher level mgmt app would require an extra set of functionality in the public API, to allow oVirt to do user impersonation with libvirt. eg libvirt would first authenticate ovirt, ovirt would then sya it wants to impersonate "fred" and from there all APIs get checked against "fred".
This gets pretty difficult though, because oVirt and most similar mgmt apps generally only have a single connection to libvirt but are doing work for 100's of different users on it. So in reality it is not very practical for libvirt to try to validate ovirt's users.
Regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/ dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/ dberrange :|

On Sat, May 12, 2018 at 11:36:08AM +0300, Anastasiya Ruzhanskaya wrote:
I actually didn't quite catch,why oVirt can't just pass user information and you could check against it? This may require to create some configuration files for libvirt about end users. What is a advantage of authenticating oVirt, and then impersonation for end user?
Libvirt authentication happens when a connection is opened - oVirt doesn't open a connection for each user. So you have to have a way to authenticate the initial connection, and then authorize individual APIs made on it. Regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|

Hello! I still want to clarify one question. Instead of making authentication of oVirt and then impersonation of each user, oVirt can just pass user information inside messages and libvirt at the end can read this user information inside rpc messages (perhaps user login could be written in one of string fields in RPC message, simply login = <...> inside message). Why this (assume that it is possible to implement this for everyone) will not work? 2018-05-14 12:25 GMT+03:00 Daniel P. Berrangé <berrange@redhat.com>:
On Sat, May 12, 2018 at 11:36:08AM +0300, Anastasiya Ruzhanskaya wrote:
I actually didn't quite catch,why oVirt can't just pass user information and you could check against it? This may require to create some configuration files for libvirt about end users. What is a advantage of authenticating oVirt, and then impersonation for end user?
Libvirt authentication happens when a connection is opened - oVirt doesn't open a connection for each user. So you have to have a way to authenticate the initial connection, and then authorize individual APIs made on it.
Regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/ dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/ dberrange :|

On Sun, May 27, 2018 at 08:03:28PM +0300, Anastasiya Ruzhanskaya wrote:
Hello! I still want to clarify one question. Instead of making authentication of oVirt and then impersonation of each user, oVirt can just pass user information inside messages and libvirt at the end can read this user
Bypassing libvirt API and sending RPC messages to libvirtd is strongly discouraged and oVirt wouldn't do that, besides, when the libvirtd deserializes the RPC message it will eventually call the same public API entry point that was used on the client side, but delegating it to a different driver (remote vs qemu for example). Knowing that, how would you pass this extra information to the existing API without changing it?
information inside rpc messages (perhaps user login could be written in one of string fields in RPC message, simply login = <...> inside message). Why
Changes to the RPC protocol would result in backwards incompatibility. Erik
this (assume that it is possible to implement this for everyone) will not work?

Hello! Excuse me for renewing this discussion. You mentioned that you can't send identity information over the remote channel in libvirt. In virt-manager, which directly uses libvirt remote functionality, there are such fields (attached, "username"). What they are used for? Are they used somehow in the sent packets? ср, 9 мая 2018 г. в 11:27, Daniel P. Berrangé <berrange@redhat.com>:
On Wed, May 09, 2018 at 11:21:22AM +0300, Anastasiya Ruzhanskaya wrote:
Ok, excuse me for misunderstanding, how it is possible then to set up access control when I use remote connection to KVM ( not in UNIX domain)? Is there any way within libvirt, maybe based on authentication or certificates?
Unfortunately we don't have a solution for fine grained access control when using remote TCP access. We had a feature request against polkit to allow passing it identity information such as certificate distinguished name, but that was rejected :-(
Regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
participants (3)
-
Anastasiya Ruzhanskaya
-
Daniel P. Berrangé
-
Erik Skultety