[libvirt] [Patch][RFC] Fine grained access control in libvirt by rbac (0/3)

The series of patches introduces a fine grained access control to libvirt. They enable libvirt to enforce users what operations to invoke in role-based way. Our team found that Konrad and Daniel have similar interest to ours. Comments and suggestions are very welcome. Patches: - Embedding hooks in libvirt (1/3) - Access control library (2/3) - Example policy files (3/3)

Yes, we're looking into adding similar form of access control in libvirt. The approach we're looking at is to inject AC as a module that intercepts calls from the libvirt core (libvirt.c) to the drivers. Reason: * AC module can be loaded/unloaded on the fly without need to recompile (can support several different AC-modules and load the appropriate one during "connect"). * Making use of (semi-stable) API between libvirt core and drivers (also hypervisor/storage/network driver independent) * Being in the call-path also enables AC-module to alter return values (such as filtering lists of VMs/NETs/Storages based on access rights) * Minimal code changes in existing libvirt code (basically a one-liner in libvirt.c to inject AC) What still is an issue is how to correctly get the identity of the user, especially over remote connection. I guess you have the same problem? (you're only allowing local usage for now). The best way would be to link some user-auth data with the virConnectPtr, but becomes a bit trickier when authentication is done prior (like in remote case) to virConnectOpen. You implemented your own RBAC language to describe the AC-policies. Have you looked at possibility to link with already existing RBAC mechanisms for Linux (like SELinux or maybe simpler AC-libs)? Freundliche Grüsse / Best regards Konrad Eriksson Trusted Computing / Security & Assurance Email: kon@zurich.ibm.com Phone: +41 (0)44 724 84 28 IBM Zurich Research Laboratory www.zurich.ibm.com Saeumerstrasse 4 8803 Rueschlikon Switzerland From: Syunsuke HAYASHI <syunsuke@jp.fujitsu.com> To: libvir-list@redhat.com Cc: Konrad Eriksson1 <KON@zurich.ibm.com>, berrange@redhat.com, Atsushi SAKAI <sakaia@jp.fujitsu.com>, INAKOSHI Hiroya <inakoshi.hiroya@jp.fujitsu.com> Date: 01/26/2009 11:25 AM Subject: [Patch][RFC] Fine grained access control in libvirt by rbac (0/3) The series of patches introduces a fine grained access control to libvirt. They enable libvirt to enforce users what operations to invoke in role-based way. Our team found that Konrad and Daniel have similar interest to ours. Comments and suggestions are very welcome. Patches: - Embedding hooks in libvirt (1/3) - Access control library (2/3) - Example policy files (3/3)

On Mon, Jan 26, 2009 at 04:19:14PM +0100, Konrad Eriksson1 wrote:
Yes, we're looking into adding similar form of access control in libvirt.
The approach we're looking at is to inject AC as a module that intercepts calls from the libvirt core (libvirt.c) to the drivers. Reason: * AC module can be loaded/unloaded on the fly without need to recompile (can support several different AC-modules and load the appropriate one during "connect"). * Making use of (semi-stable) API between libvirt core and drivers (also hypervisor/storage/network driver independent) * Being in the call-path also enables AC-module to alter return values (such as filtering lists of VMs/NETs/Storages based on access rights) * Minimal code changes in existing libvirt code (basically a one-liner in libvirt.c to inject AC)
What still is an issue is how to correctly get the identity of the user, especially over remote connection. I guess you have the same problem? (you're only allowing local usage for now).
There are lots of scenarios to consider - Direct local API usage. You have the PID, UID & GID of the process - Local usage via libvirtd + UNIX sockets. You can get the PID, UID & GID of the client end using the SCM_CREDENTIALS message. (see man 7 unix) - Remote usage via libvirtd + TCP sockets. Depending on the security & encryption settings you may have a SASL username, or a x509 certificate CNAME, or both, or neither. - Local usage via libvirtd + UNIX sockets + libvirt-qpid. The PID, UID & GID of the client end aren't particularly usage, since libvirt-qpid is just a demon running as root, which accepts calls on behalf of many remote apps. Does QPid provide any identifying info about the entity which put the message on the queue. - Remote usage with IPSec ? So there are multiple identifying credentials, in multiple formats, and need some way to associate this information with a connection. Applying RBAC to local (non-Daemon) API usage has clear limitations - if the user running virsh (or equiv) has direct access to the system, then they could trivially just replace the real virsh with their own virsh without RBAC. So RBAC usage in the non-Daemon context is only useful if the user does not have direct access to the ssytem (eg, virsh is being invoked on their behalf by another tool, or a constrained environment where its guarenteed they can't provide their own libraries/binaries.
The best way would be to link some user-auth data with the virConnectPtr, but becomes a bit trickier when authentication is done prior (like in remote case) to virConnectOpen.
The key question is do we need to pass the client/callers identity at the time we create the connection object, or is it sufficient to provide it after the fact with a call like virConnectAddSecParam(VIR_SECPARAM_UNIX_UID, getuid()); virConnectAddSecParam(VIR_SECPARAM_UNIX_GID, getgid()); virConnectAddSecParam(VIR_SECPARAM_USERNAME, saslUsername); virConnectAddSecParam(VIR_SECPARAM_X509_CNAME, saslUsername); Or do we need to provide this info via some form of callback mechanism, perhaps via the exiting virConnectCredential struct, which is curently not used on the server end of remote connections. Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

Hi, thanks for your analysis. Daniel P. Berrange wrote:
There are lots of scenarios to consider
- Direct local API usage. You have the PID, UID & GID of the process - Local usage via libvirtd + UNIX sockets. You can get the PID, UID & GID of the client end using the SCM_CREDENTIALS message. (see man 7 unix) - Remote usage via libvirtd + TCP sockets. Depending on the security & encryption settings you may have a SASL username, or a x509 certificate CNAME, or both, or neither. - Local usage via libvirtd + UNIX sockets + libvirt-qpid. The PID, UID & GID of the client end aren't particularly usage, since libvirt-qpid is just a demon running as root, which accepts calls on behalf of many remote apps. Does QPid provide any identifying info about the entity which put the message on the queue.
I'm not familier with Qpid. Could you explain its benefit or point me some documents about it? And how can I use it on libvirt?
- Remote usage with IPSec ?
I personally don't like IPSec because it's too rigid. And I don't know whether it is common. X509, SASL, or password authentication through secure connection seems simple and good enough.
So there are multiple identifying credentials, in multiple formats, and need some way to associate this information with a connection.
Applying RBAC to local (non-Daemon) API usage has clear limitations - if the user running virsh (or equiv) has direct access to the system, then they could trivially just replace the real virsh with their own virsh without RBAC. So RBAC usage in the non-Daemon context is only useful if the user does not have direct access to the ssytem (eg, virsh is being invoked on their behalf by another tool, or a constrained environment where its guarenteed they can't provide their own libraries/binaries.
That's true but, as I mentioned in the other e-mail, I'm now concentrating on AC itself assuming that user-auth has been established. I don't think user authentication and access control should be tied up with each other. I mean, it's nice if AC-module can always use uid as a part of the key for consulting policies, not depending on whether libvirt is running on a local or remote server.
The best way would be to link some user-auth data with the virConnectPtr, but becomes a bit trickier when authentication is done prior (like in remote case) to virConnectOpen.
The key question is do we need to pass the client/callers identity at the time we create the connection object, or is it sufficient to provide it after the fact with a call like
virConnectAddSecParam(VIR_SECPARAM_UNIX_UID, getuid()); virConnectAddSecParam(VIR_SECPARAM_UNIX_GID, getgid()); virConnectAddSecParam(VIR_SECPARAM_USERNAME, saslUsername); virConnectAddSecParam(VIR_SECPARAM_X509_CNAME, saslUsername);
A simple question. How do you identify what user the remote libvirt switches to? Do you look up some directory services? Hiroya
Or do we need to provide this info via some form of callback mechanism, perhaps via the exiting virConnectCredential struct, which is curently not used on the server end of remote connections.
Daniel

Hi, it seems that we share the interest. Konrad Eriksson1 wrote:
Yes, we're looking into adding similar form of access control in libvirt.
The approach we're looking at is to inject AC as a module that intercepts calls from the libvirt core (libvirt.c) to the drivers. Reason: * AC module can be loaded/unloaded on the fly without need to recompile (can support several different AC-modules and load the appropriate one during "connect"). * Making use of (semi-stable) API between libvirt core and drivers (also hypervisor/storage/network driver independent) * Being in the call-path also enables AC-module to alter return values (such as filtering lists of VMs/NETs/Storages based on access rights) * Minimal code changes in existing libvirt code (basically a one-liner in libvirt.c to inject AC)
Sounds reasonable. Injecting AC without embedding hooks at API entries is pretty cool. Do you have any implementation?
What still is an issue is how to correctly get the identity of the user, especially over remote connection. I guess you have the same problem? (you're only allowing local usage for now).
Yes, our AC takes effect only when it is invoked locally because uid is unavailable at a remote site.
The best way would be to link some user-auth data with the virConnectPtr, but becomes a bit trickier when authentication is done prior (like in remote case) to virConnectOpen.
I agree in that some user-auth mechanisms are necessary, but now I concentrate on AC-module itself assuming that user-auth is finished. Daniel gave a concrete idea on user authentication and I find it fine.
You implemented your own RBAC language to describe the AC-policies. Have you looked at possibility to link with already existing RBAC mechanisms for Linux (like SELinux or maybe simpler AC-libs)?
From security point of view, sVirt together with SElinux constraining
I have some coarse ideas where policies should be given as a SELinux's policy. It extends libvirt, like sVirt does, so that it calls SELinux API to make an authenticated user move to a qualified role (domain). Current sVirt is something different from AC itself though it employs SELinux. sVirt constrains qemu processes to use just allowed objects, while AC-module is aimed to constrain users to call just allowed sub commands on allowd VMs. libvirt is secure enough to me. So, I don't think it is mandatory that AC be realized by using SELinux. The main goal of AC in this context is to prevent differently authorized user from accidentally invoking unallowed operations. This seems a bit different from keeping the whole server untainted. So, proprietary implementations don't likely cause a serious security threat. Of cause, I understand that SELinux appears an attractive option. Regards, Hiroya
Freundliche Gru"sse / Best regards
*Konrad Eriksson* Trusted Computing / Security & Assurance
Email: _kon@zurich.ibm.com_ <mailto:kon@zurich.ibm.com> Phone: +41 (0)44 724 84 28 * IBM Zurich Research Laboratory*_ __www.zurich.ibm.com_ <http://www.zurich.ibm.com/> Saeumerstrasse 4 8803 Rueschlikon Switzerland
From: Syunsuke HAYASHI <syunsuke@jp.fujitsu.com> To: libvir-list@redhat.com Cc: Konrad Eriksson1 <KON@zurich.ibm.com>, berrange@redhat.com, Atsushi SAKAI <sakaia@jp.fujitsu.com>, INAKOSHI Hiroya <inakoshi.hiroya@jp.fujitsu.com> Date: 01/26/2009 11:25 AM Subject: [Patch][RFC] Fine grained access control in libvirt by rbac (0/3)
------------------------------------------------------------------------
The series of patches introduces a fine grained access control to libvirt. They enable libvirt to enforce users what operations to invoke in role-based way. Our team found that Konrad and Daniel have similar interest to ours. Comments and suggestions are very welcome.
Patches: - Embedding hooks in libvirt (1/3) - Access control library (2/3) - Example policy files (3/3)
participants (4)
-
Daniel P. Berrange
-
INAKOSHI Hiroya
-
Konrad Eriksson1
-
Syunsuke HAYASHI