Single sign-on into virtual machines on Linux
This weekend I looked into making possible a single sign-on into Fedora 24 guests running on libvirt/KVM. Suppose you have a libvirt-based server where a number VMs is deployed with VMs presenting graphical workstations. This is not far from what ovirt.org does (RHEV product). You want to have both your virtualization infrastructure and OS environments in VMs to be enrolled into FreeIPA and thus accessible with single sign-on from an external client.
There are several layers of single sign-on here. Once you signed into your external client, supposedly you have valid Kerberos credentials that can be used to obtain service tickets to other services in the realm.
Second layer is the connectivity to your virtualization infrastructure. This is possible already with libvirtd/Qemu as they both support SASL authentication. It is matter of setting appropriate configuration variables in /etc/libvirt/libvirtd.conf and /etc/libvirt/qemu.conf, and tuning /etc/sasl2/libvirt.conf and /etc/sasl2/qemu.conf to allow SASL GSSAPI authentication. You also need to create appropriate services in FreeIPA (libvirt/hostname, vnc/hostname, and spice/hostname) and obtain actual keys with ipa-getkeytab. This is all described relatively well in the FreeIPA libvirt howto.
Once configured, one can authenticate with SASL GSSAPI to VNC server using virt-manager UI or other VNC clients in GNOME that use gtk-vnc library. This works pretty well but only gives you access to the actual screen of the VM, not single sign-on into an operating system in the VM.
SPICE, on other hand, does not work with SASL GSSAPI. While SPICE server embedded into Qemu can be configured easily to listen for SASL GSSAPI, SPICE client libraries in GNOME don’t actually support SASL GSSAPI. In fact, the code is there, it is copied from gtk-vnc, but it does not work.
SPICE client code lacks actual sequence to obtain Kerberos identity out of existing ticket in a default credentials cache. As result, instead of authenticating with SASL GSSAPI, a user is left with a request to enter ‘server password’ which is a concept built around existing SPICE authentication approach where both client and server share a single password.
After I fixed this problem by inquiring a Kerberos principal from the default ccache, SPICE is now working well in a way similar to VNC. I’ll submit patch to upstream once I have time for that.
This still doesn’t give any chance to actually log-in to the VM because both VNC and SPICE servers only represent fancy screens/input devices for the VMs. There is no existing way to pass through authentication via SPICE or VNC so that a software running in the VM would accept Kerberos ticket and authenticate a user based on that.
Here a concept of guest agent is introduced. Qemu has its own guest agent (here) which only supports a minimal set of commands needed to make virtualization management working. OVirt/RHEV have their own guest agent here that supports much more than QEmu’s version and has own protocol. Finally, SPICE has own agent, vdagent, that supports even more operations related to use of graphical resources within the VM.
The idea behind these agents is to have a separate trusted channel into VM that can be used to query/execute something inside the VM. OVirt guest agent supports logon into the VM by plugging into PAM stack and into graphical greeters. When user asks OVirt portal to logon into a console of a VM, a login request can also be sent to the guest agent. This request doesn’t really present a single sign-on, as user have to enter actual credentials and then guest agent injects them into GDM, KDM, or console via D-Bus.
SPICE vdagent can inject both keyboard and mouse events, and even has systemd-login integration that allows it to query sessions to know which X session is used by which user so that mouse/keyboard events are properly injected. It doesn’t though, have a way to force GNOME GDM to create a new session automatically based on the credentials authenticated by the SPICE server.
It would, perhaps, be a good path forward to hack both SPICE server and vdagent to make possible use of delegated GSSAPI credentials to perform a logon into GDM. This would require support from GDM too but as OVirt experience shows, it is possible to create a GDM plugin to help with the task. The goal is to have such logon triggered on opening of the SPICE session if GDM is running and no session is available yet. As result of such logon, valid Kerberos credentials would need to appear in the system so that further use of them would be possible. This means delegation of the credentials – something that SPICE or VNC doesn’t support either (but SASL GSSAPI allows to achieve, it is a single flag change and a policy at KDC to define).
There is another technology to remotely access other systems – RDesktop protocol. XFreeRDP project has experimental patches to support GSSAPI. They don’t work yet, but I have good progress on them to make SSO possible.
So in the end, current implementations don’t allow actual single sign-on in a way that would allow using Kerberos credentials in and out of VMs. To make that possible, more work is needed. It looks like extending vdagent to be able to pass Kerberos ccache content to SSSD via PAM sessiona and trigger that from the greeter plugins as developed in OVirt we could actually reach the point with less effort than creating something from scratch.