KVM/Qemu VMs with a multi-screen Spice console – III – local access with remote-viewer via a Unix socket

In the last article of this series

KVM/Qemu VMs with a multi-screen Spice console – II – local access with remote-viewer via a network port
KVM/Qemu VMs with a multi-screen Spice console – I – Overview over local and remote access methods

I discussed “remote-viewer” – a tool to access the graphical Spice console of a virtual machine [VM] on a KVM/Qemu host. Although remote-viewer is thought to be used over network connections, you can also use it locally on the virtualization host itself, e.g. in a desktop virtualization scenario.

To get an overview we first had a brief look at some central libvirt and qemu configuration files which control the interaction of Spice clients with the libvirtd daemonand/or the Qemu-emulator. We then defined a network port (e.g. 20001) in the Spice related entry of the VM’s XML configuration file. This file is evaluated when you start a Qemu VM with virsh or virt-manager. Afterward we could access the Spice console of the VM by entering

spice://localhost:20001

on a terminal in a graphical desktop session on the KVM host. If the host had an IP like 192.168.2.22

spice://192.168.2.22:20001

would in principle work, too. But a successful outcome may, of course, depend on local firewall settings for your network devices.

We verified that remote-viewer supports a multi-screen presentation of any major graphical Linux desktop started on the VM. Present versions of KDE and Gnome on a Kali/Debian/Opensuse guest automatically adapt to changes of the user’s Spice client windows (on the host’s desktop). XFCE, however, requires a manual configuration of the virtual screens with tools of the guest OS.

I also demonstrated that a Spice console session corresponds to a fragile “one seat” situation: Other local or remote users can kick us out of our Spice session at any time. We could at least protect us against unauthorized session switches by defining a password for the Spice console. So far, so good.

But: Local access via a network port is certainly not the fastest method for local user interaction with a VM: Each transaction triggers operations of a TCP network stack. Can we get around this?

Yes, we can – by working with a Unix socket on the VM host. This is the subject of this article. While we prepare a Spice socket configuration for remote-viewer we also answer the question which sockets the libvirtd daemon offers for its client.

We use our test VM “debianx” again, which has a Kali OS installed together with multiple desktops to choose from (Gnome, KDE, XFCE). The KVM/Qemu host is a Opensuse Leap 15.2 system with a KDE desktop.

Documentation? Not really …

I did not find any hints in the Opensuse documentation on virtualization of how to use remote-viewer with a Unix socket. Neither the man pages, nor other user-friendly descriptions of remote-viewer gave me a clue. I got a socket based approach to work after an accidental view into two discussions on the Internet plus a bit of trial and error. These are links to the discussions I referred to:

https://www.linuxquestions.org/questions/linux-virtualization-and-cloud-90/remote-viewer-spice-qemu-and-unix-domain-socket-how-to-connect-4175571914/
https://bugzilla.redhat.com/show_bug.cgi?id=1335832

You may find a description of socket based configurations for Spice also in articles on Virgl3D based rendering – a local socket based configuration is essential there.

Spice access via a socket

The first article of this series contains a schematic drawing which shows various access methods to the Spice console of a VM. However, aside TCP ports I had not displayed any Unix sockets there. The following picture gives you an idea how such a local alternative could look like:

You should not take the direct connections to the Spice console too literally. Of course, the real interaction occurs between remote-viewer and the Qemu-emulator.

In the drawing I also indicated that libvirt-based tools (as virt-manager, virt-viewer), which do not directly interact with the qemu-emulator, use a specific socket which is automatically created at a standard location on Opensuse Leap 15.x systems.

Off topic: What sockets are used by virt-manager and virt-viewer?

Actually, libvirtd exposes multiple sockets to libvirt clients – each for a specific purpose; see
https://libvirt.org/manpages/libvirtd.html
and
https://libvirt.org/daemons.html
for details.

Virt-manager has its own graphical console window. Select a running VM and simply choose the menu-point “Open” to open a Spice client window on your host.

Note: In contrast to remote-viewer and also virt-viewer, virt-manager does not allow you to open multiple “screen”windows.

In a terminal window we ask “netstat” to inform us about relevant active sockets; just for interest we also look into related directories:

MySRV:~ # netstat | grep libv
unix  3      [ ]         STREAM     CONNECTED     554391   /run/libvirt/libvirt-sock
unix  3      [ ]         STREAM     CONNECTED     513499   /run/libvirt/libvirt-sock
unix  3      [ ]         STREAM     CONNECTED     554599   /run/libvirt/libvirt-sock
unix  3      [ ]         STREAM     CONNECTED     515826   /var/lib/libvirt/qemu/domain-1-debianx/monitor.sock
unix  3      [ ]         STREAM     CONNECTED     513581   /run/libvirt/libvirt-sock
MySRV:~ # 
MySRV:~ # la /run/libvirt/ | grep sock
srw-------  1 root root    0 Mar  9 17:48 libvirt-admin-sock
srw-rw-rw-  1 root root    0 Mar  9 17:48 libvirt-sock
srw-rw-rw-  1 root root    0 Mar  9 17:48 libvirt-sock-ro
srw-------  1 root root    0 Mar  9 17:48 virtlockd-sock
srw-------  1 root root    0 Mar  9 17:48 virtlogd-admin-sock
srw-------  1 root root    0 Mar  9 17:48 virtlogd-sock
MySRV:~ #
MySRV:~ # la /var/lib/libvirt/qemu/ 
total 44
drwxr-x--- 10 qemu qemu 4096 Mar  9 17:48 .
drwxr-xr-x 11 root root 4096 Oct 26 11:01 ..
drwxr-xr-x  3 qemu qemu 4096 Apr  2  2017 channel
drwxr-xr-x  2 qemu qemu 4096 Nov 16 17:56 checkpoint
drwxr-x---  2 qemu qemu 4096 Mar  9 17:48 domain-1-debianx
drwxr-xr-x  2 qemu qemu 4096 Apr  2  2017 dump
drwxr-xr-x  2 qemu qemu 4096 Apr  2  2017 nvram
drwxr-xr-x  3 qemu qemu 4096 Sep 10  2018 ram
drwxr-xr-x  2 qemu qemu 4096 Apr  2  2017 save
drwxr-xr-x  2 qemu qemu 4096 Apr  2  2017 snapshot
MySRV:~ #
MySRV:~ # la /var/lib/libvirt/qemu/domain-1-debianx/ 
total 20
drwxr-x---  2 qemu qemu 4096 Mar  9 17:48 .
ndrwxr-x--- 10 qemu qemu 4096 Mar  9 17:48 ..
-rw-------  1 qemu qemu   32 Mar  9 17:48 master-key.aes
srwxrwxr-x  1 root root    0 Mar  9 17:48 monitor.sock
MySRV:~ # 

By the way: A nice tool to list sockets is “ss“; try “ss -axeo | grep libv” or

ss -a –unix -p | grep virt

for instance.

Some sockets obviously have very restrictive rights settings. However, the rights situation seems to be totally relaxed for two of the sockets in “/run/libvirt”. As we shall see in a minute these sockets are the relevant ones for Spice clients using libvirt.

Readers of the last article may have guessed that we configure access rights to these sockets in the file “/etc/libvirt/libvirtd.conf”. Sorry, but on a standard Opensuse Leap system this is wrong. Instead the sockets are created by systemd during the start of the libvirtd.service. See the respective files libvirtd.service, libvirtd.socket, libvirtd-ro.socket in the folder “/usr/lib/systemd/system”:

MySRV:/usr/lib/systemd/system # cat libvirtd.service 
[Unit]
Description=Virtualization daemon
Requires=virtlogd.socket
Requires=virtlockd.socket
# Use Wants instead of Requires so that users
# can disable these three .socket units to revert
# to a traditional non-activation deployment setup
Wants=libvirtd.socket
Wants=libvirtd-ro.socket
Wants=libvirtd-admin.socket
Wants=systemd-machined.service
.....

and e.g.

MySRV:/usr/lib/systemd/system # cat libvirtd-ro.socket
[Unit]
Description=Libvirt local read-only socket
Before=libvirtd.service
BindsTo=libvirtd.socket
After=libvirtd.socket

[Socket]
# The directory must match the /etc/libvirt/libvirtd.conf unix_sock_dir setting
# when using systemd version < 227
ListenStream=/run/libvirt/libvirt-sock-ro
Service=libvirtd.service
SocketMode=0666

[Install]
WantedBy=sockets.target

A standard rights setting of “666” is used. You could change this in a special local file under “/etc/systemd/”. We shall return to respective settings in another article.

Virsh and virt-manager require a (rw) socket which allows for VM re-configuration, i.e. writing operations to the Qemu-emulator configuration data for a VM. This socket is “/run/libvirt/libvirt-sock“.

Regarding access to a Spice console, however, a so called “ro”-socket, namely “/run/libvirt/libvirt-sock-ro“, is sufficient. You can verify this by trying

virt-viewer -c qemu:///system?socket=/run/libvirt/libvirt-sock-ro

The “ro” refers to a denial of configuration writing and changes of Qemu-process parameters controlling the VM. It is NOT directly related to the Linux access rights of the socket itself. Actually, the socket is a “stream” socket; this already implies that the user needs write access to it. Which is given in an Opensuse Leap system. See the generous “rw-rw-rw-“-setting in the listings above!

This raises the question:
What restricts the access to these libvirt standard sockets at all on an Opensuse Leap system?

Answer:
Its a policy setting; see the Opensuse documentation in “Virtualization guide – Connecting and authorizing“. More on this topic in another article.

How would we specify an URI, which points to a Unix-socket, for remote-viewer?

To force remote-viewer to use a Unix socket we first have to find out how we specify an URI pointing to such a socket. Well, the first of the named articles above together with the man-pages for remote-viewer gives us an idea. The right form for a local access is:

remote-viewer -v spice+unix://Path-To-Socket

Note that a path down from the root ”
/” of the Linux directory tree will lead to three “///” !

You cannot use the libvirtd-sockets with remote-viewer!

Can we use the sockets provided by libvirtd with remote-viewer? The answer is: No. More precisely: I do not know how, if it should work against my expectations. We use the above recipe and try:

MySRV:~ # remote-viewer -v  spice+unix:///var/lib/libvirt/qemu/domain-1-debianx/monitor.sock
Guest (null) has a spice display
Opening connection to display at spice+unix:///var/lib/libvirt/qemu/domain-1-debianx/monitor.sock

With the result:

Something equally negative happens with

MySRV:~ # remote-viewer -v spice+unix:///run/libvirt/libvirt-sock
Guest (null) has a spice display
Opening connection to display at spice+unix:///run/libvirt/libvirt-sock

(remote-viewer:22055): GSpice-WARNING **: 19:29:01.691: incomplete link header (-104/16)

We are stuck. Well, it would have been too simple. And it would have been strange, too, because remote-viewer was made to directly access Qemu. So, the next logical question is:

How can we tell Qemu to provide a suitable Unix socket for the Spice console?

Required settings in the XML domain file for the VM => specify a socket for the Spice item

We can use the information provided in the Red Hat bug tracker mentioned above. We guess that we can change the Spice settings according to the following pattern in the VMs’ domain definition file “/etc/libvirt/qemu/debianx.xml”:

    
    <graphics type='spice' autoport='no' keymap='de' defaultMode='insecure'>
      <listen type='socket' socket='/tmp/spice.socket'/>
      <image compression='off'/>
      <gl enable='no'/>
    </graphics>

You see that I choose the “/tmp”-directory to create a socket. The directory must of course be writeable. For whom? And which access rights will our aspired socket get?

It is reasonable to assume that we will see the rights of the specific system user, which is used to run Qemu processes for VMs. We already saw in the last article that this is the user named “qemu” (single member of group “qemu”) on a standard Opensuse system.

OK, let us see whether we can start our “debianx” test VM with this new Spice item in its XML configuration.

No problem! To check whether the VM really is operational we start virt-manager’s integrated Spice console window and log into Kali’s KDE desktop:

No problem there either.
Note the settings for the Spice window – the last menu point must be checked to guarantee an automatic adaption of the VM’s desktop to the dimensions of the Spice console window.

If you now would use

virt-viewer -c qemu:///system?socket=/run/libvirt/libvirt-sock-ro

again, virt-manager’s Spice window would be closed (one seat!) and a virt-viewer window would open (NOT a remote-viewer window; see the top bar of the window below).


But all of this is no proof that a new socket has been created. virt-manager and virt-viewer use the sockets “/run/libvirt/libvirt-sock” and “/run/libvirt/libvirt-sock-ro” (to connect to libvirtd) – as we already know. But a look into the “/tmp”-folder

MySRV:~ # ls -lisa /tmp | grep spice
1452545    0 srwxrwxr-x   1 qemu  qemu        0 Mar 13 14:31 spice.socket
MySRV:~ # 

actually shows that we indeed have a new socket. We get an additional confirmation by netstat:

MySRV:~ # netstat -ax | grep spice
unix  2      [ ACC ]     STREAM     LISTENING     137989   /tmp/spice.socket
MySRV:~ # 

Remote-viewer with a local Unix socket

Let us use the prepared socket as user “uvma”. Unfortunately, a first trial with

remote-viewer spice+unix:///tmp/spice.socket

fails due to insufficient access rights. Obviously, the user “uvma” needs write rights on the specified “stream” socket.

The most simple solution for the moment is to add the user “uvma”, which we already put into a privileged group “libvirt” in the last article, to the group “qemu”, too. (This is probably not the best solution. We come back to security aspects later.) But for the time being we enter (as root)

usermod -a -G qemu uvma

As user “uvma” we afterward log out and in again to our desktop session on the host. In a terminal window we then enter (as user “uvma”)

remote-viewer spice+unix:///tmp/spice.socket

It works! A new Spice client window for remote-viewer is opened. I added one more “screen” and also started some applications to see, if we can really interact with the VM – which is indeed the case. Even sound works (if pulseaudio is used on the host):

Great!

Security considerations

Besides an improved performance, working with a Unix socket avoids opening a network port and related potential security issues. But, as we saw, we need some special rights for such a scenario. Which also has security implications ….

Regarding this point I do not think that putting a user into the “qemu”-group is a good idea. Well, you could argue that our user “uvma” is already privileged regarding VMs. Yes, true enough. But we may change this in the future and separate users which can use virt-manager from others which use remote-viewer for a specific VM: The user who gets the right to open the Spice console may be different from the special user which is allowed to start the VM.

Another problem is that a user being member of the qemu group has almost the same rights as the “qemu”-user itself. But, in contrast to the special user “qemu” on an Opensuse Leap system, a normal user as “uvma” has a login-shell:

MySRV:/etc/libvirt/qemu # cat /etc/passwd | grep qemu
qemu:x:484:483:qemu user::/sbin/nologin
MySRV:/etc/libvirt/qemu # cat /etc/passwd | grep uvma
uvma:x:1025:100:uvma:/home/uvma:/bin/bash

“uvma” needs a login-shell as
he/she shall work with remote-viewer in his/her desktop session on the host. So, if this user gets hacked (e.g. via a browser bug) this would have consequences for all VMs on the host.

We can at least confine a selected user’s impact to a specific VM. Let us take a user “uvmb”. We want to allow this user to access our test-VM “debianx” locally via a socket – but only this VM!

For this purpose we create a special group “spicex” and add both “qemu”, “uvma” and “uvmb” to this group.

usermod -a -G spicex uvmb
usermod -a -G spicex uvma
gpasswd -d uvma qemu

We also remove user “uvma” from the “qemu”-group.

Then we create a special directory “/var/spice/spicex“. You can, of course, choose a different path. We set the group of this folder to “spicex”. Then we set the “s”-flag on the group and use ACLs to enforce a default group for the user and the group with certain rights on an files created in this folder.

chown qemu.spicex /var/spice/spicex
chmod g+s /var/spice/spicex
setfacl -dm u:qemu:rwx,g:spicex:rwx,other::--- /var/spice/spicex

In addition we stop our VM and change its XML configuration to

    <graphics type='spice' autoport='no' keymap='de' defaultMode='insecure'>
      <listen type='socket' socket='/var/spice/spicex/spice.socket'/>
      <image compression='off'/>
      <gl enable='no'/>
    </graphics>

Afterward we restart the libvirtd-daemon. That’s it. Te next time, you start your VM by virt-manager as “uvma” you get something like

MySRV:/var/spice/spicex # la
total 12
drwxrws---+ 2 qemu spicex 4096 Mar 17 19:26 .
drwxr-xr-x  9 root root   4096 Mar 15 16:32 ..
srwxrwx---+ 1 qemu spicex    0 Mar 17 19:26 spice.socket

Now, you change to user “uvmb” by logging out and starting a new X-/KDE-session on the host or by just entering “su – uvmb” in a terminal. We login as “uvmb” and try

uvmb@MySRV:~> remote-viewer -v  spice+unix:///var/spicex/spice.socket

This should work; if you stayed in the KDE session of user “uvma” you probably get some error messages regarding audio and a denied pulseaudio access. But the Spice graphics should be OK. Similar precaution measures should be taken for other VMs. ACLs give you enough flexibility to control VM-specific access. Now, you could remove “uvma” from group spicex – and get some kind of tool access segregation. It would not make much sense however as long as uvma still is privileged by being a member of the libvirt group; uvma still can open the Spice console at any time via libvirtd and its special sockets. Regard “uvma” as a VM administrator.

Summary:
The configuration of a VM with a Unix socket has the advantage that we can control the Spice session access, and thereby a potential session switch to another user, a bit better. We restrict the access to libvirtd to selected members of an administrative group and the access to the socket to a selected user of the VM. Though it does not hurt to have a password in place in addition …

Off topic hint 1: Adjustment of Spice screen positions relative to each other on the guest system

When you open a second Spice windows with remote-viewer it is not guaranteed that the guest’s desktop system initially places these virtual Spice screens seamlessly side-a-side. But both KDE, Gnome and XFCE provide graphical tools to adjust the geometrical relation of multiple screens. With the help of these tools you can specify how relative corner positions of the virtual screens are handled. You only have to do this once, afterwards you can move your Spice windows around on the host’s desktop as you like :

Relative positioning of two virtual Spice screens with the monitor tool of the guest’s KDE desktop

Independent positions of the Spice windows on the KDE desktop of the KVM/Qemu host

Even resizing of the Spice windows won’t disturb the relative position definition of the virtual screen corners in the guest.

Off topic hint 2: Workaround for faulty Clipboard interaction between the KDE sessions on the host and in the Qemu guest VM

I noticed a strange dis-coupling between the functionality of the clipboard of KDE main session on the host and the clipboard of guest VM’s KDE session. Due to the spice-vdagent they should work seamlessly together. It looked OK in the beginning for the exchange of data between the host and the VM. However, when I tried to copy between two terminal windows on the host I got error message in the terminal from which I started the guest VM:

Spice-CRITICAL **: 14:46:03.424: clipboard_request: assertion 's->clipboard_by_guest[selection] == FALSE' failed

And no data were copied! This disappeared as soon as I activated the “system” tray in the control bar of the guest’s KDE desktop, activated the clipboard entry there and adjusted the clipboard settings there to those of the KDE session on the host.

Conclusion

Remote-viewer works very well with a local Unix socket instead of a TCP socket as the interface to the Qemu-emulator process of the VM. A socket based local access scenario to a Spice console can easily be configured via respective settings in the XML-definition file of a VM. However, to improve security you should avoid adding a standard user who wants to use remote-viewer to the “qemu” group. Involving ACL rights will help you to confine users to access the Spice console of specific VMs via placing a socket into a specific directory and controlling access to it and its contents.

Note by the way that using Unix sockets locally on the host also allows for a new remote-access scenario via SSH. Such a scenario could even be more efficient than a TLS encrypted standard connection over a network port in a LAN. Much to discover! Stay tuned. In the next article

KVM/Qemu VMs with a multi-screen Spice console – IV – remote access via SSH, remote-viewer and a Unix socket

I will show you how to use remote-viewer via SSH.

Links

The ss-command to list up sockets
https://www.networkworld.com/article/3327557/using-the-linux-ss-command-to-examine-network-and-socket-connections.html

lbvirt and authentication on Opensuse
https://documentation.suse.com/sles/15-SP1/html/SLES-all/cha-libvirt-connect.html

KVM/Qemu VMs with a multi-screen Spice console – II – local access with remote-viewer via a network port

In my first article in this series on local and remote connections to the Spice console of a KVM/Qemu virtual machine [VM] I have given you an overview over some major options. See the central drawing in

KVM/qemu with the graphical multi-screen Spice console – I – Overview over local and remote access methods

In this post we explore a part of the drawing’s left side – namely a local connection with the remote-viewer client over a network-port and the “lo”-device. Local means that we access the Spice console with a Spice client in a desktop session on the KVM/Qemu host.

You can find some basic information on “remote-viewer” here.

Note: “remote-viewer” supports VNC, too, but we ignore this ability in this series.

A local scenario with remote-viewer on a KVM/Qemu host corresponds to desktop virtualization – though done with a remote tool. Such an approach can become a bit improper, because setting up ports for potential remote network connections always has security implications. This is one of the reasons why I actually want to discuss two different local access methods which can be realized with remote-viewer:

  • Method 1: Access via a network port (TCP socket). This standard method is well documented on the Internet both regarding the VM’s setup (e.g. with virt-manager) and the usage of remote-viewer (see the man pages). The network based scenario is also depicted in my drawing.
  • Method 2: Access via a local Unix socket. This method is not documented so well – neither regarding the VM’s setup (e.g. with virt-manager) and not at all by the man pages for remote-viewer.

You may complain now that I never indicated anything in the above drawing about a pure Unix socket! Well, at the time of writing the first article I did not even know that remote-viewer worked over a pure Unix socket and how one can configure the VM for a Unix socket. I will discuss the more common “Method 1” in this present article first. “Method 2” will be the subject of the next post – and then I will provide an update of the drawing. Talking about sockets: When you think a bit about it – Unix sockets must already be an ingredient of the local interaction of libvirt-tools with qemu, too, ….

Below I will discuss a set up for “Method 1” which is totally insecure. But it can be realized in a very simple way and is directly supported by virt-manager for the VM setup. Thus, it will give us a first working example without major efforts for creating TLS certificates. But, you are/were warned:

Disclaimer:
The test-configurations I discuss in this and the next articles of this series may lead to major security risks. Such configurations should NOT be used in productive multi-user and/or network environments without carefully crafted protection methods (outside the qemu-configuration) – as local firewall protection, system policies, etc. I take no responsibility whatever for an improper usage of the ideas presented in this article
series.

Assumptions for test scenarios

  • The KVM/Qemu host in this article series is an Opensuse Leap 15.2 host. Most of the prescriptions discussed may work with some minor modifications also on other Linux distributions. But you must look up documentations and manuals …
  • I assume that you already have set up a KVM/Qemu based test-VM with virsh or virt-manager. Let us call the VM “debianx“. Actually, it is a Kali system in my case. (Most of the discussed measures will work on guests with a Debian OS, too.)
  • On our Opensuse KVM host we find a XML-definition file “debianx.xml” for a libvirt domain (i.e. a VM) below the directory “/etc/libvirt/qemu/“, i.e. “/etc/libvirt/qemu/debianx.xml”. It has a typical XML structure and can be edited directly if required.
  • The KVM host itself has a FQDN of “MySRV.mydomain.de“. (MySRV is partiall writtenin big letters to remind you that you have to replace it by your own domain.
  • The user on the KVM host, who invokes remote-viewer to access the VM, has a name “uvma“. We will later add him to a group “libvirt” which gets access rights to libvirt tools. We shall also work with a different user “uvmb” who is a member of the group “users”, only. Both users work on a graphical desktop on the KVM/Qemu host (!) – let us say a KDE desktop. These users open one or more Spice client windows on the host’s desktop to display graphical desktops of the KVM/Qemu guest VMs – as if the windows were screens of the VM.

We must carefully distinguish between the (KDE) desktop used by “uvma” on the KVM host and the desktop of the guest VM:

The Spice client windows on the KVM host’s (or later on independent remote systems) desktop present full graphical desktops (Gnome, XFCE, KDE …) of the VM and allow for interactive working with the VM. The desktop used on the host can, of course, be of a different type than the one used on the guest.

I will use this first practical article also

  • to have a brief look at two basic configuration files for libvirtd and qemu settings,
  • to discuss some basic setup options for a Qemu VM,
  • to check the multi-screen ability of remote-viewer
  • and to prove the “one-seat” situation for the Spice console.

I restrict my hints regarding the guest configuration to Kali/Debian or Opensuse Leap guest systems on the VM. I provide images for a Kali guest system, only. I do not have time for more …

Make backups

Before you start any experiments you should make a backup of the directories “/etc/libvirt” and “/etc/pki” of your host – and in doubt also of the disk-files (or real partitions) of your existing VMs. You should also experiment with a non-productive test VM, only.

Basic security considerations

(In-) Security is always a bit relative. Let us consider briefly, what we intend to do with respect to “Method 1”:

With the first method we define a network port for unencrypted connections without authentication.

In principle the port can be used by anyone having access to your network or anyone present on your PC. Such a configuration is therefore only reasonable for desktop virtualization

  • if you really are alone on your PC
  • AND if you have a local firewall preventing access to the port from any other system AND if there is a local policy restricting access to the Qemu-hypervisor or Spice-clients.

nOtherwise it opens a much too big attack surface. Remember: Anyone being able to use the network port can kick you off your Spice console session seat, remotely, locally and also when you are already logged into the guest OS. And:

All data transfer over any kind of network device (lo, ethernet, virtual devices on the host, …) occurs unencrypted. Other users on your machine (legal users, e.g. active via ssh, or attackers) may with some privilege escalation be able to read it.

Access to the Spice console itself can, however, be restricted to users who know a password. At the end of this article we will add such a simple password to our configuration to get at least some basic protection against kicking you out of a Spice console session.

Preparational step 1: Settings in “/etc/libvirt/qemu.conf” and the integration of Spice with Qemu

As mentioned in the last article, Spice is fully integrated with the Qemu-emulator. So, it will not surprise you that we can modify some general properties of connections to a VM’s Spice console by parameter settings in a configuration file for Qemu. The relevant file in the libvirt-dominated virtualization environment of Opensuse Leap 15.2 is

/etc/libvirt/qemu.conf“.

Readers of my last article may ask now: Why do we need to configure the Qemu-driver of libvirt at all, when we access the Spice console with remote-viewer directly via Qemu ? I.e., without passing a libvirt-layer? As depicted in the drawing?

Answer: Probably you and me start KVM/Qemu based VMs through “virsh” or “virt-manager“, i.e. libvirt components. Then libvirt drivers which are responsible to start the VMs according to its setting profile must know what we expect from the Qemu emulator. If you worked directly with the qemu-emulator (by calling “/usr/bin/qemu-x86_64”) you would have to specify a lot of options to control the outcome! Some sections below you will find an example. Libvirt-programs only automate this process.

“qemu.conf” allows for general default settings of a variety of qemu-parameters. Some of them can, however, be overwritten by VM-specific settings; see the next section. When you scroll through the file you come to a major section which contains Spice parameters. For an easy beginning of our experiments we set some selected parameters to the following values:

 
#spice_listen = "0.0.0.0" # just leave it as it is 
# .... 
spice_tls = 0  # This corresponds to a deactivation of TLS and a INSECURE configuration!
spice_tls_x509_cert_dir = "/etc/pki/libvirt-spice"
# .... 
# just leave the next settings as it is - it creates a socket at  "/var/lib/libvirt/qemu/domain-1-debianx/monitor.sock"
#spice_auto_unix_socket = 1  
spice_sasl = 0

Our first setting deactivates TLS. This is reasonable as long a we have not created valid TLS server certificates and encryption keys. But we can already define a default directory into which we later place such a certificate and key files. We also deactivate any SASL authentication support for the time being. (Actually, even if you left it at the default value of “1” it would not help you much – as on Opensuse systems a required file “/etc/sasl2/qemu.conf” is missing, yet. As standard SASL encryption methods are insecure today, SASL activation makes sense in combination with TLS only.

General security precautions in “/etc/libvirt/qemu.conf”
Talking about security: On an Opensuse system with activated “apparmor” you could/should set the following parameters in “/etc/libvirt/qemu.conf”:

 
security_driver = "apparmor"
security_default_confined = 1

to confine VMs.

Note: If “apparmor” is deactivated for some reason you will after these settings not be able to use virt-manager or virsh.
You can check the status of apparmor via “rcapparmor status” or systemctl status apparmor”.
(Off topic: Those interested in process separation should also have a look at cgroup-settings for the VMs. I would not change the basic settings, if you do not know exactly what you are doing. But folks trying to experiment with “virgl3D” may need to add “/dev/dri/renderD128” to the device list for ACLs.)

Preparational step A: A brief look a “/etc/libvirt/libvirtd.conf” – allow a selected standard user to use virt-manger or virsh

As we are within the folder “/etc/libvirt”, we take the chance to very briefly look at another configuration file, which will become more interesting in later articles:

/etc/libvirt/libvirtd.conf

Among other things this file contains a variety of parameters which control the access to libvirt tools via Unix sockets or TCP-sockets – with and without TLS and/or some form of authentication. This is of no direct importance for what we presently are doing with remote-viewer – as we access Spice console directly via qemu, i.e. without a libvirt-layer. However, for convenience reasons you should nevertheless be able to use virt-manager or virsh. If you do not want to work as root all the time you, i.e. he normal user “uvma”, need(s) special access rights to access Unix sockets which are automatically opened by libvirtd. How can this be achieved on an Opensuse Leap system?

You can configure a special user-group (e.g. a group named “libvirt”) to get access to virt-manager. You can do this in a section named “UNIX socket access controls”. The instructions in Opensuse’s documentation on virtualization (see: Connections and authorization and section 9.1.1.1 therein) will help you with this. Afterwards you must of course add your selected and trusted user (here: “uvma”) to the defined group.

Note: The libvirtd-process is nevertheless run by the user “root” and not with the rights of the standard user (here “uvma”). The group just allows for a kind of sudo execution. Note also that the central sockets by which libvirt-clients connect to the libvirtd-daemon are created by systemd.

By the way – who is the user for qemu-processes on an Opensuse Leap system?
On an Opensuse there is a special user “qemu” which is used to run the Qemu-emulator processes for VMs. We also find a related group “qemu”. User and group have special rights regarding aes-keys for potential credential encryption related to a VM. The user and its group also define the access right to special Unix sockets generated directly by the Qemu emulator and not by libvirtd. We shall request such a Unix socket from Qemu in the next article.

On other operative systems you may find a different pre-configured group for libvirt access rights. In addition the standard qemu-user may have a different name. For Debian and derivatives you find related information at the following links:
whats-the-purpose-of-kvm-libvirt-and-libvirt-qemu-groups-in-linux,
install-configure-kvm-debian-10-buster,
libvirt_qemu_kvm_debian .

Preparational step B: Restart libvirtd or reload its configuration after changes to qemu.conf, livirtd.conf or changes to XML-definition files for VMs

Changes of the file “/etc/libvirt/qemu.conf” or “/etc/libvirt/libvird.conf” require that the libvirtd daemon is restarted or forced to reload its configuration. The same is true for any changes of
XML-definition files for VMs located in “/etc/lbvirt/qemu/”. (We will change such files later on). According to the man page sending a SIGHUP signal to the daemon will enforce a reload of the configuration. You can indirectly achieve this by the commands

rclibvirtd reload [on Opensuse systems)
or
systemctl reload libvirtd [any system with systemd]

But: Any libvirt or qemu changes will NOT affect already running VMs. You have to stop them, then restart libvirtd, reload the daemon’s configuration and restart the VMs again.

Preparational step C: Configure the VM to use a Spice-console – and some other devices

Ok, let us prepare our VM for “Method 1”. As we are in a libvirt environment we could use virt-manager to perform the required Spice configuration (see the image in the first article) . But we can also directly edit the XML configuration file “/etc/libvirt/qemu/debianx.xml” – assuming that you already have a working configuration for your VM. You need to be root to edit the files directly. See the restrictive access rights of the domain definition files

-rw------- 1 root root   4758 Mar  8 13:33 debianx.xml

By the way: A detailed description of possible parameter settings is provided at https://libvirt.org/formatdomain.html. Search for Spice and qxl …..

Regarding “Method 1” I use the following settings. The listing below only gives you an excerpt of the XML domain file, but it contains the particularly relevant settings for “graphics” (can be looked upon as a display device) and “video” (an be interpreted as a kind of virtual graphics card):

Excerpts from a libvirt domain definition XML file

   
   <interface type='network'>
      <mac address='52:54:00:93:38:4c'/>
      <source network='os'/>
      <model type='virtio'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
    </interface>
   ...
   <graphics type='spice' port='20001' autoport='no' listen='0.0.0.0' keymap='de' >    
      <listen type='address' address='0.0.0.0'/>
      <image compression='off'/>
    </graphics>
   ... 
    <sound model='ich6'>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
    </sound>
    ...
    <video>
      <model type='qxl' ram='262144' vram='65536' vram64='2097152' vgamem='65536' heads='4' primary='yes'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
    </video>
...

Parameters which affect general qemu-related properties (as e.g. the “listen”-settings) will overwrite the settings in “qemu.conf”. The choice of the PCI slot numbers may be different for your guest.

You see that I defined a network (!) port for the VM by which we can access the Spice console data stream directly. I have changed this port from the default “5900” to “20001”.

You should be aware of the fact that this sets a real network port on the KVM host – i.e. a network stack is invoked when accessing the Spice console. As indicated above we can avoid the superfluous network operations by directly working with a Unix socket (Method 2), but this is the topic of the next forthcoming article.

Regarding network port definitions for a Spice console three rules apply:

  • Each of the VMs defined requires its own individual port !
  • Firewalls between the client and the VM have to be opened for this port. This includes local firewalls on the VM, on the KVM host (with rules that may apply to virtual bridges, on the client system and on any network
    components in between.
  • A TLS port has later to be configured in addition if you deactivated the “autoport” functionality – as we have done in the example above. I shall describe how to set the TLS port in a forthcoming article.)

The individual port definitions already imply the provision of a URI with port specification when starting remote-viewer (see below).

Let me briefly comment on the QXL-settings:

The QXL configuration shown above allows for 4 so called “heads” (or connectors) of the virtual graphics device. These heads support up to 4 virtual screens, if requested by the Spice-client. Note that the situation is different from real hardware consoles:
The (Spice) client (here remote-viewer) defines the number of screens attached to the VM’s console by a number of Spice client windows opened on the user’s desktop on the KVM host. The dimensions of these Spice client windows determine the dimensional capabilities of the virtual “screens”.

How the virtual screen resolution is handled afterwards may depend on the user’s own desktop resolution (on the KVM host or a remote system) AND the display settings of the VM’s guest system’s own tools for screen management. Today these are typically tools integrated into the guest’s graphical desktop (KDE, Gnome, XFCE) itself. Present Gnome and KDE5 desktops on the VM’s guest Linux system automatically adapt to the virtual display dimensions – i.e. the Spice window dimensions. But a XFCE desktop on the guest may behave differently; see below.

A short note also on the network settings for our test VM:
A virtual machine will normally be associated with a certain type of virtual network. At least if you want to use it for the provision of services or other network or Internet dependent tasks. You can configure virtual networks with virt-manager (menu “edit” >> “connection details”); but you must be root to do this:

In my case I prefer a separate virtual network for which we need routing on the KVM host. This allows us to configure restrictive firewall rules – e.g, with netfilter on the host. It even allows for the setup of virtual VLANs – a topic which I have extensively covered in other article series in this blog. And when required we just can stop routing on the host.

Guest requirements
Note that the QXL-configuration must also be supported on the VM guest itself: You need a qxl-video-driver there – and it is useful to also have the so called spice-vdagent active (see the my referenced series about a qxl-setup in the last article). On the guest system this requires

  • the installation of the “spice-vdagent” package and the activation of the “spice-vdagent.service” (both on Debian/Kali and Opensuse guest systems) ,
  • the installation of the packet “xserver-xorg-video-qxl” on a Debian/Kali-guest or “xf86-video-qxl” on an Opensuse guest

Present Debian, Kali or Opensuse operative system on the KVM/Qemu guest VM should afterward automatically recognize the QXL-video-device and load the correct driver (via systemd/udev).
Regarding the (virtual) network device on the VM itself you must use the guest system’s tools for the configuration of NICs and of routes.

Preparational step D: Starting the VM – and “Where do I find logs for my VM”?

I assume that you as user “uvma” are logged in to a graphical desktop session on your KVM host “MySRV”. If you are not
yet a member of the libvirt-privileged group, you may need to use sudo for the next step. On a terminal window you then enter “virt-manager &”, select our VM “debianx” and boot it.

If you look at the process list of your KVM host you may find something like:

qemu     17662  5.5  6.8 15477660 4486180 ?    Sl   18:11   2:29 /usr/bin/qemu-system-x86_64 -machine accel=kvm -name guest=debianx,debug-threads=on -S -object secret,id=masterKey0,format=raw,file=/var/lib/libvirt/qemu/domain-1-debianx/master-key.aes -machine pc-i440fx-2.9,accel=kvm,usb=off,vmport=off,dump-guest-core=off -cpu Skylake-Client -m 8192 -overcommit mem-lock=off -smp 3,sockets=3,cores=1,threads=1 -uuid 789498d2-e025-4f8e-b255-5a3ac0f9c965 -no-user-config -nodefaults -chardev socket,id=charmonitor,fd=33,server,nowait -mon chardev=charmonitor,id=monitor,mode=control -rtc base=utc,driftfix=slew -global kvm-pit.lost_tick_policy=delay -no-hpet -no-shutdown -global PIIX4_PM.disable_s3=1 -global PIIX4_PM.disable_s4=1 -boot strict=on -device ich9-usb-ehci1,id=usb,bus=pci.0,addr=0x5.0x7 -device ich9-usb-uhci1,masterbus=usb.0,firstport=0,bus=pci.0,multifunction=on,addr=0x5 -device ich9-usb-uhci2,masterbus=usb.0,firstport=2,bus=pci.0,addr=0x5.0x1 -device ich9-usb-uhci3,masterbus=usb.0,firstport=4,bus=pci.0,addr=0x5.0x2 -device virtio-serial-pci,id=virtio-serial0,bus=pci.0,addr=0x6 -blockdev {"driver":"file","filename":"/virt/debs/debianx.qcow2","node-name":"libvirt-2-storage","cache":{"direct":true,"no-flush":false},"auto-read-only":true,"discard":"unmap"} -blockdev {"node-name":"libvirt-2-format","read-only":false,"cache":{"direct":true,"no-flush":false},"driver":"qcow2","file":"libvirt-2-storage","backing":null} -device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x7,drive=libvirt-2-format,id=virtio-disk0,bootindex=1,write-cache=on -device ide-cd,bus=ide.0,unit=0,id=ide0-0-0 -netdev tap,fd=35,id=hostnet0,vhost=on,vhostfd=36 -device virtio-net-pci,netdev=hostnet0,id=net0,mac=52:54:00:93:38:4c,bus=pci.0,addr=0x3 -chardev pty,id=charserial0 -device isa-serial,chardev=charserial0,id=serial0 -chardev socket,id=charchannel0,fd=37,server,nowait -device virtserialport,bus=virtio-serial0.0,nr=1,chardev=charchannel0,id=channel0,name=org.qemu.guest_agent.0 -chardev spicevmc,id=charchannel1,name=vdagent -device virtserialport,bus=virtio-serial0.0,nr=2,chardev=charchannel1,id=channel1,name=com.redhat.spice.0 -device usb-tablet,id=input0,bus=usb.0,port=1 -spice port=20001,addr=0.0.0.0,disable-ticketing,plaintext-channel=default,image-compression=off,seamless-migration=on -k de -device qxl-vga,id=video0,ram_size=268435456,vram_size=67108864,vram64_size_mb=2048,vgamem_mb=64,max_outputs=4,bus=pci.0,addr=0x2 -device intel-hda,id=sound0,bus=pci.0,addr=0x4 -device hda-duplex,id=sound0-codec0,bus=sound0.0,cad=0 -chardev spicevmc,id=charredir0,name=usbredir -device usb-redir,chardev=charredir0,id=redir0,bus=usb.0,port=2 -chardev spicevmc,id=charredir1,name=usbredir -device usb-redir,chardev=charredir1,id=redir1,bus=usb.0,port=3 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x8 -object rng-random,id=objrng0,filename=/dev/urandom -device virtio-rng-pci,rng=objrng0,id=rng0,bus=pci.0,addr=0x9 -sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny -msg timestamp=on

 
You see that the user “qemu” started the qemu-process by calling “/usr/bin/qemu-system-x86_64” and adding a bunch of parameters. You may identify some parameters which stem from the settings in libvirt’s XML definition file for our special the VM (or “domain”).

Afterwards, have a look at connections with
netstat on the host; you should see that something (qemu) listens on the defined Spice port of the VM:

MySRV:/etc/libvirt/qemu # netstat -a -n | grep 20001
tcp        0      0 0.0.0.0:20001           0.0.0.0:*               LISTEN
...

Regarding logs of the VM for error analysis: You will find them in the directory ” /var/log/libvirt/qemu” (on an Opensuse Leap system).

Method 1: Local access to the Spice console with remote-viewer

Now, we are prepared to test a local access to the Spice console with remote-viewer. (As we work via a network port you may still need to open the Spice port on a local firewall – it depends of how you configured your firewall.) The format of the URI we have to specify for remote-viewer is

spice://FQDN_OR_IP:PORT_NR

with

  • FQDN_OR_IP: You have to present a host address which can be resolved by DNS or a directly an IP-address.
  • PORT_NR: The port for the Spice service – here “20001”.

For our setup this translates to

spice://localhost:20001

and thus the command

remote-viewer spice://localhost:20001

As user “uvma” we enter this command in another terminal window of our graphical desktop on the KVM host :

uvma@MySrv:~> remote-viewer spice://localhost:20001

(remote-viewer:22866): GSpice-WARNING **: 12:43:58.150: Warning no automount-inhibiting implementation available

Just ignore the warning. Then you should get a window with a graphical display of some login-screen on the VM. Details depend of course on the configuration of your VM’s operative system. In my case, I get the “gdm3”-login-screen of my virtualized Kali system:

The desktop-manager may be a different one on your system. After a login to a Gnome desktop I use remote-viewer‘s menu to open a 2nd screen:

and get two resizeable screen-windows :

As expected! When we change the dimensions the desktop of the VM adapts to the new virtual screen sizes. Just try it out.

Will this work with a KDE desktop on the Kali guest, too? Yes, it does. KDE5 and Gnome3 can very well coexist on a Kali, Debian or Opensuse Leap15.2 (guest) system! For a Kali system you find information how to install multiple graphical desktop environments e.g. at the following links:
install-kali-linux,
kde-environment-configuring-in-kali,
kali switching-desktop-environments.

The next image shows the transparency effect of a moving terminal window on a KDE desktop of the same Kali VM – again with 2 Spice screens requested by remote-viewer:

Such effects, which can also be configured on Gnome, require an active compositor on the guest’s desktop. At least when working locally on a KVM host I never got any problems with the performance of QXL/Spice and remote-viewer with an active compositor on the guest’s Gnome, KDE, and XFCE-desktops (without OpenGL acceleration). This is a bit different on a remote system and using remote-viewer over a LAN connection; see the next articles.

KDE and Gnome desktops on the VM automatically adapt to the sizes of the virtual screens. XFCE does not … XFCE is the present default desktop on Kali; so I installed after a distribution upgrade. Here some remote-viewer hints for XFCE fans on a VM with Kali/Debian and XFCE:

  • Set the number of screens in remote-viewer to 1. After installing XFCE with ” sudo apt update && sudo apt install -y kali-desktop-xfce” and a reboot we can choose “XFCE-Session” on a button of the gdm3-screen (after having entered the username). It will the boot into a XFCE session.
  • Then with the setting tool you can configure fixed resolutions for the screen displays (see below).
  • Or: Just deactivate a virtual display, resize the respective window on your host’s desktop and reactivate the virtual display again in your XFCE guest. XFCE then automatically recognizes the new screen size and adapts.
  • When logging out choose an option to save the desktop.

Unfortunately, XFCE has no seamless coexistence with KDE or Gome on Kali, yet. The following sequence of steps may fail:
1) Log out of a XFCE desktop-session, 2) choose a KDE or Gnome session afterwards /(this works without rebooting via the gdm menu), 3) log out of KDE/Gnome again and 4) try to restart a XFCE desktop.
On my Kali guest (on an Opensuse KVM host) I always have to reboot the guest to get a working XFCE session again, even if I did not change the screen dimensions during the KDE/Gnome session .. 🙁

Netstat reveals multiple connections corresponding to Spice channels

Using remote-viewer with a netowrk port is a really simple exercise. Most of the text above was spend on looking at the general virtualization environment. But, actually, the situation behind the scenes is not so simple. When we use netstat again, we get the following:

  
MySRV:/etc/libvirt/qemu # netstat -a -n | grep 20001
tcp        0      0 0.0.0.0:20001           0.0.0.0:*               LISTEN     
tcp        0      0 127.0.0.1:20001         127.0.0.1:46738         ESTABLISHED
tcp        0      0 127.0.0.1:20001         127.0.0.1:46750         ESTABLISHED
tcp        0      0 127.0.0.1:46734         127.0.0.1:20001         ESTABLISHED
tcp        0      0 127.0.0.1:46750         127.0.0.1:20001         ESTABLISHED
tcp        0      0 127.0.0.1:20001         127.0.0.1:46742         ESTABLISHED
tcp        0      0 127.0.0.1:46738         127.0.0.1:20001         ESTABLISHED
tcp        0      0 127.0.0.1:46740         127.0.0.1:20001         ESTABLISHED
tcp        0      0 127.0.0.1:46748         127.0.0.1:20001       
  ESTABLISHED
tcp        0      0 127.0.0.1:20001         127.0.0.1:46740         ESTABLISHED
tcp        0      0 127.0.0.1:20001         127.0.0.1:46734         ESTABLISHED
tcp        0      0 127.0.0.1:20001         127.0.0.1:46728         ESTABLISHED
tcp        0      0 127.0.0.1:20001         127.0.0.1:46744         ESTABLISHED
tcp        0      0 127.0.0.1:46728         127.0.0.1:20001         ESTABLISHED
tcp        0      0 127.0.0.1:46742         127.0.0.1:20001         ESTABLISHED
tcp        0      0 127.0.0.1:20001         127.0.0.1:46748         ESTABLISHED
tcp        0      0 127.0.0.1:46744         127.0.0.1:20001         ESTABLISHED

We find many, namely eight (8), active established connections. What do these connections correspond to? Well, they correspond to individual data exchange channels; I quote from
https://libvirt.org/formatdomain.html#video-devices:

“When SPICE has both a normal and TLS secured TCP port configured, it can be desirable to restrict what channels can be run on each port. This is achieved by adding one or more elements inside the main element and setting the mode attribute to either secure or insecure. Setting the mode attribute overrides the default value as set by the defaultMode attribute. (Note that specifying any as mode discards the entry as the channel would inherit the default mode anyways.) Valid channel names include main, display, inputs, cursor, playback, record (all since 0.8.6 ); smartcard ( since 0.8.8 ); and usbredir ( since 0.9.12 ).”

See also: spice_for_newbies.pdf

Theoretically, one should be able to use remote-viewer itself to activate or deactivate channels by setting up a “target file” for the connection; see the man-pages for more details. But on my machines it does not work neither locally not remotely. 🙁 I did not look into the details of this problem, yet ….

Testing the “one seat situation” at a Spice console

Now its time to test what I claimed in the last article: The Spice console can be accessed only by one user at a time. Let us assume, that user “uvma” is a member of the libvirt-group. Let us in addition create another user “uvmb” which is member of the group “users” on the host, only. I assume that “uvma” has opened a graphical desktop session on the KVM host (MySRV). E.g. a KDE session.

Step 1: As user “uvma” start virt-manager and boot your VM “debianx”. On a terminal window (A) use remote-viewer to open the Spice console of the VM with 2 screens. Log into a graphical desktop of the VM.

Terminal A:

uvma@MySRV:~> remote-viewer -v  spice://localhost:20001
Guest (null) has a spice display
Opening connection to display at spice://localhost:20001

(remote-viewer:20735): GSpice-WARNING **: 18:21:31.344: Warning no automount-inhibiting implementation available

Step 2: On your host-desktop open another terminal window (N) and login via “su – uvmb” as the other user. As “uvmb” now enter “remote-viewer spice://localhost:20001“.

uvma@MySRV:~> su - uvmb
Passwort: 
uvmb@MySRV:~> remote-viewer -v  spice://localhost:20001

This will at once close the open two Spice windows and after a blink of a second open up one or two new Spice windows again. The effect is clearly visible.

On terminal A we get:

Guest debianx display has disconnected, shutting down
uvma@MySRV:~> 

On terminal B we get a lot of warnings – but still the spice windows open in exactly the same status as we left them.

n

uvmb@MySRV:~> remote-viewer -v  spice://localhost:20001

(remote-viewer:20903): dbind-WARNING **: 18:25:40.853: Couldn't register with accessibility bus: Did not receive a reply. Possible causes include: the remote application did not send a reply, the message bus security policy blocked the reply, the reply timeout expired, or the network connection was broken.
Guest (null) has a spice display
Opening connection to display at spice://localhost:20001

(remote-viewer:20903): GSpice-WARNING **: 18:25:40.936: PulseAudio context failed Verbindung verweigert

(remote-viewer:20903): GSpice-WARNING **: 18:25:40.936: pa_context_connect() failed: Verbindung verweigert
Cannot connect to server socket err = Datei oder Verzeichnis nicht gefunden
Cannot connect to server request channel
jack server is not running or cannot be started
JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
AL lib: (EE) ALCplaybackAlsa_open: Could not open playback device 'default': Keine Berechtigung

(remote-viewer:20903): GLib-GObject-WARNING **: 18:25:40.962: g_object_get_is_valid_property: object class 'GstAutoAudioSink' has no property named 'volume'
AL lib: (EE) ALCplaybackAlsa_open: Could not open playback device 'default': Keine Berechtigung

(remote-viewer:20903): GLib-GObject-WARNING **: 18:25:40.964: g_object_get_is_valid_property: object class 'GstAutoAudioSrc' has no property named 'volume'
AL lib: (EE) ALCplaybackAlsa_open: Could not open playback device 'default': Keine Berechtigung
AL lib: (EE) ALCcaptureAlsa_open: Could not open capture device 'default': Keine Berechtigung

(remote-viewer:20903): GSpice-WARNING **: 18:25:41.015: record: ignoring volume change on audiosrc

(remote-viewer:20903): GSpice-WARNING **: 18:25:41.018: record: ignoring mute change on audiosrc

(remote-viewer:20903): GSpice-WARNING **: 18:25:41.021: Warning no automount-inhibiting implementation available

(remote-viewer:20903): GSpice-WARNING **: 18:25:41.052: playback: ignoring volume change on audiosink

(remote-viewer:20903): GSpice-WARNING **: 18:25:41.052: playback: ignoring mute change on audiosink

 
The warnings are mainly due to the fact that user “uvmb” has no rights to access the Pulseaudio context of the desktop of user “uvma”. (I take care of Pulseaudio in one of the next articles …) At the first switch between the users you may only get one Spice window as “uvmb”. Choose two screens then. Afterwards you can switch multiple times between the users uvma and uvmb. Two windows get closed for the user with present Spice console session, two windows are opened for the requesting user, and so on.

Conclusion: “uvmb” and “uvma” can steal each other the Spice console with remote-viewer as and when they like.

By the way: A Spice console can be left regularly by a user by just closing the Spice client window(s). Note that this will not change the status of your desktop session on the host! This is left open – with all consequences.

Restricting access by setting a password

Let us prevent being thrown of the “seat” in front of our Spice console. As root change the <graphics> definition in VM’s definition file to

...
 <graphics type='spice' port='20001' autoport='no' listen='0.0.0.0' keymap='de' passwd='spicemeandonlyme' defaultMode='insecure'>
      <listen type='address' address='0.0.0.0'/>
      <image compression='off'/>
      <gl enable='no'/>
    </graphics>
   ... 

If you haven’t noticed: The relevant difference is the “passwd” attribute. You could have added this setting via virt-manager, too. Try it out.

Shut down and restart your VM. Any user that now wants to access the Spice console using “remote-viewer spice://
localhost:20001” will be asked for a password. You yourself, too, if you close the console and try to reopen it.

Regarding security: The password transfer will to my understanding be AES encrypted. See Daniel P. Berrangé’s blog https://www.berrange.com/posts/2016/04/01/improving-qemu-security-part-3-securely-passing-in-credentials/. But as long as the rest of the data exchange with the VM is not encrypted, this precaution measure won’t help too much against ambitioned attackers.

Conclusion

Using remote-viewer locally on a KVM host in combination with a network port to access a VM’s graphical Spice console is easy and convenient. It requires a minimum of settings. In addition it offers up to four virtual screens which you can open via a menu.
However, using a network port implies security risks. You should think about proper counter-measures first if you want to lean on “remote-viewer”. Once configured in the way described above there is no libvirt-layer or anything else which may hinder ambitious attackers to analyze the unencrypted data flow between the Spice client and the VM through the host’s network port.

In the next article

KVM/Qemu VMs with a multi-screen Spice console – III – local access with remote-viewer via a Unix socket

I want to show you how one can configure the VM such that remote-viewer can access the Spice console via a local Unix port. A network port is not opened in this approach. Security is none the less hampered a bit as we have to give a standard user some rights which normally only the “qemu” group has. But we shall take care of this aspect by using ACLs.

Links

Virtualization on Opensuse
https://doc.opensuse.org/ documentation/ leap/ virtualization/ single-html/ book.virt/index.html

Libvirtd daemon
https://www.systutorials.com/docs/linux/man/8-libvirtd/

Libvirt connection URIs
https://libvirt.org/uri.html

Find the Spice URI to use
https://access.redhat.com/ documentation/ en-us/ red_hat_enterprise_linux/7/ html/ virtualization_deployment_and_ administration_guide/ sect-Domain_Commands- Displaying_a_URI_ for_connection_to_a_graphical_display

TLS disabled
https://unix.stackexchange.com/ questions/ 148794/ how-to-create-kvm-guest-with-spice-graphics-but-tls-disabled-using-virt-install

General Kali installation
https://www.cyberpratibha.com/blog/how-to-update-and-upgrade-kali-linux-to-latest-version/

KDE, XFCE on Kali
https://technicalnavigator.in/kde-vs-xfce-which-one-is-better/

KVM/Qemu VMs with a multi-screen Spice console – I – Overview over local and remote access methods

KVM/Qemu based virtual machines [VMs] are a nice and comfortable part of my life with Linux. I use them both as dedicated entities for various services on a server host and as experimental test or work environments on my Linux workstation. Whereas the access to server VMs was dominated by SSH connections and CLI interaction so far, working with VMs on my PC was and is is characterized by graphical user-interfaces.

In the latter case we speak of desktop-virtualization: Connections to the virtual guests are set up locally via sockets (or via a network port over device “lo”) on the very same PC or workstation which also serves as KVM host. Supported by a client/server model for graphics, KVM/Qemu provides multiple capable methods for the local display of the graphical output of a VM. And by graphical output I mean a desktop environment as KDE, XFCE or Gnome.

For KVM/Qemu the combination of the so called

  • Spice display” and the Spice protocol
  • with drivers for potent virtual video devices (as QXL or Virtio)

offers a very convenient solution for the presentation of a VM’s graphical desktop with high performance – which, in my experience, is considerably faster than most VNC variants.

In addition:
With the help of certain Spice clients one can access a local VM via a desktop display which extents over up to four “screens“. All of these “screens” are displayed within scalable windows of your preferred basic desktop environment on your Linux machine – e.g. KDE, LXDE. This means that you can graphically work with a full fletched KDE desktop of the VM displayed in multiple windows within a KDE or Gnome environment on your local KVM/Qemu host (e.g your Linux workstation).

Can we get this comfort also with remote connections over a LAN? With encryption tunnels? The answer is yes – and related Qemu and Libvirt configurations are the main topics of this article series.

Why do I write about these subjects, at all? Recently, I needed to work with a KVM/Qemu guest remotely on an Opensuse Leap 15.2 server. I wanted to use a SSH tunneled connection with password authentication for a special graphical Spice client, namely “virt-viewer“. Being a bit naive, I ran into some major trouble. This in turn forced me to look closer at different possibilities for remote connections to KVM/Qemu based VM. Unfortunately, I found Opensuse’s documentation on Spice sparse – to say the best. But Spice gets especially interesting and somewhat complex with remote access methods, encryption and authorization.

In this article series I discuss some of the multiple configuration options I have experimented with. I restrict myself to Spice based solutions with the clients “virt-viewer“, “remote-viewer” and also “virt-manager“. In combination with SSH, TLS. I hope my experiences help other Opensuse Leap users to set up convenient remote solutions.

After giving some documentation links, I start with an overview over some selected remote access scenarios which are available. They are the most important ones and are all based on network ports. But, in the coming posts I will cover local access scenarios based on Unix sockets, too. And their combination with SSH.

Limitations

Unfortunately, I have to reduce expectations of readers who are out for “multi-user remote desktop solutions”. This is not what the present Spice solutions with the named clients will offer you. See below.

A topic which I will not address in the forthcoming articles is the setup of a local VM with OpenGL acceleration on the graphics device of the KVM host. With Nvidia cards and drivers this is
unfortunately a mess – and it is Nvidia’s fault, in my opinion. Very similar, by the way, to Nvidia’s EGL-based solution attempt for Wayland. All of this because of their own OpenGL handling and their declined support for GBM. So, let us not go there to avoid frustration …

Basic preparations of a KVM/Qemu VM: Documentation and guides?

I assume that you are already familiar with the basic set up and configuration of a KVM/Qemu based virtual machine – e.g. with virsh or virt-manager. If not, you will find valuable hints for Opensuse Leap systems in SuSE’s “Virtualization Guide

However, as said above, Opensuse’s documentation on virtualization does not give you much information about Spice. We only get a glimpse of it at the sections on “virsh” and “Qemu“. The information is rather spurious there; one doesn’t get a broader context. You may get a better understanding by reading introductory pages on the site “https://www.spice-space.org/“, especially the user manual
https://www.spice-space.org/spice-user-manual.html.
Regarding special configuration settings of a VM, see https://libvirt.org/formatdomain.html.

Spice with multiple screens requires a non default configuration of the VM’s QXL device

For a basic Spice setup there is not too much to do; “just” choose Spice for the display-settings of your VM and configure the VM’s QXL graphics device. Such a device corresponds to something like a virtual graphics card. Well, it sounds easy, but when I tried it myself, I had to experiment. To help others a bit: I have already discussed in depth how we can configure a KVM/Qemu guest and its QXL device such that it supports multiple scalable high-resolution screens for Spice clients. See the following articles:

KVM/qemu mit QXL – hohe Auflösungen und virtuelle Monitore im Gastsystem definieren und nutzen – I
KVM/qemu mit QXL – hohe Auflösungen und virtuelle Monitore im Gastsystem definieren und nutzen – II
KVM/qemu mit QXL – hohe Auflösungen und virtuelle Monitore im Gastsystem definieren und nutzen – III
KVM/qemu mit QXL – hohe Auflösungen und virtuelle Monitore im Gastsystem definieren und nutzen – IV

These posts were written in German; but with a little bit of goodwill one can understand the configuration settings and related commands.

An alternative today is to use a “virtio” video device in the VM’s configuration. I shall come back to this point in a later article.

What I did not cover in my previous posts on Spice was the broader spectrum of access options to a KVM/Qemu-based VM with libvirt/Space clients – both regarding local and remote connections. I only discussed how to use the “remote-viewer” client locally – despite the fact that its name already indicates something else. What I also disregarded in my articles in 2017 is the fact that
there are various (remote) access methods – direct ones and some through a libvirt-layer on the KVM-host. As always with Linux there are multiple ways to achieve your objectives :-).

However, when we use Spice instead of VNC we speak about a “one person” or a “one seat” solution.

Spice and libvirt => multiple methods to access exactly one graphical console of a KVM/Qemu based VM

What you should be aware of when you think of using Spice for a graphical access to a KVM/Qemu VM is the following:

1. The Spice protocol and the Spice display for KVM/QEMU based VMs do NOT provide a multi-user service for graphical remote terminals or remote desktop displays – at least not in their default configuration.

According to what I have read, anything in this direction still seems to be experimental. Instead:

2. We access a data stream describing the graphical contents of one or multiple screens of a console which is virtually “attached” to the VM.

Let us call this device a multi-screen Spice console of the VM.

The Spice console solution is fully integrated into the QEMU-emulator. The console screen data and related sound can, however, also be displayed and played on a remote Linux system. And here we face a point which makes the user’s life both convenient and complex at the same time :

3. The Spice console of a VM can be accessed by various protocols or protocol combinations. The Spice console is fully integrated with Qemu and directly accessible there via a (network) socket, but it is in addition accessible via libvirt components. This leads to a variety of connectivity options.

These aspects can be underestimated: Remote access for multiple screen requires sufficient band-width of the network. The second point excludes the application of Spice for multi-user scenarios. The third point opens up a range of local and remote access possibilities – some are more complicated to configure, some are more secure than others. Some options are deactivated in a default libvirt installation (not only on Opensuse Leap systems).

The most important connection options for standard libvirt/spice clients are summarized in the following schematic drawing.

The Spice console of a KVM/Qemu VM

The graphics shows a Linux KVM host at its center. KVM supports the VM emulator QEMU in the Linux kernel – thus making QEMU fast. Two virtual machines VM1 and VM2 are shown. VM1’s configuration includes a Spice (console) display – e.g. set up according to the following excerpt of a configuration example for a VM (done with virt-manager):

Note that the configuration item is called “display” in virt-manager (and “graphics” in the XML-configuration of a VM). I think that in the case of Spice “Console” would have been a better name. I should also warn you that the displayed configuration may lead to security risks – if not accompanied by protective measures.

Note also that “virt-manager” does not allow for a detailed QXL-configuration required for multiple screens on the displayed dialog. But you can edit the XML-files of the VM for this purpose via the second tab (or an editor;
you find the XML-files for VMs in the directory “/etc/libvirt/qemu” on Opensuse Leap systems):

The QXL configuration displayed here is an example – you may choose other parameters. (Or test out a “virtio” device; see a later article).

“One seat” console
In the lower right part of the first sketch above I have tried to express that a graphical Spice console corresponds to a “one console with one seat” situation. The console is only available for exactly one (authorized) user at a time. Note:

Any user having sufficient access rights may any time claim the console and throw you off the seat in front of the graphical console screen, if you do not secure the access to the console by a password (or other measures)!

We did not do this in the configuration example above; see the empty field for the password. I quote from the documentation:

“Spice does not support multiple connections to the same QEMU instance by default. So anybody who will connect to the same host and port can simply take over your session. You can solve this problem by using ticketing.” (see: https://www.spice-space.org/spice-user-manual.html)

“Ticketing” means setting a password to access the VMs console screen; but still anyone knowing the password could claim the console – a password is no real solution for a multi-user situation. To say it clearly:

If your objective is to establish something like a multi-user graphical access to a KVM/QEMU-based virtual machine with a full desktop display for each user (i.e. a “remote desktop solution”), then think about something like a headless graphical server configuration of the KVM guest. On a Linux VM, you can achieve this by either implementing a X2GO server, a commercial NoMachine server, a VNC server-variant or even XRDP. Some of these solutions can easily be combined with SSH.
And do not forget: In a LAN with sufficient bandwidth “ssh -X” may already serve most practical purposes.

But in many cases a local or remote “one seat situation” with a full graphical desktop may be sufficient. Now, let us look at the other parts of the drawing.

Different access options to the Spice console of a KVM/Qemu-based VM

There is a multitude of options to connect to the Spice console (https://www.spice-space.org/spice-for-newbies.html). We shall describe them briefly in this first article. In forthcoming articles we shall have a closer look at each of them.

Option 1: Simple connection with “remote-viewer” via a Spice (network) port

The Qemu-emulator is able to handle requests over the Spice protocol on its own, i.e. without the invocation of special libvirt-support. The Spice solution offers connections to the console either on the basis of a pure Unix socket (local solution) or a network port (remote solution).

A network oriented solution, which can be realized with the Spice client “remote-viewer” is depicted on the left side of our central sketch:

You access the Spice console of a specific VM directly via a specific network port. Spice ports have to be configured independently for each of the VMs. I.e., if you have 2 VMs whose Spice consoles you want to access independently then you need to define two different ports for the Spice consoles. Actually, you won’t be able to start a VM which has the same port associated with its Spice console as another already running VM.

nProperties of a remote-viewer connection over a network port:

  • Default port? The standard Spice port is 5900 (which is also the port used by VNC). In the example displayed above I instead used port 20001. (Do not forget to open your firewalls for your chosen ports!)
  • Security by encryption? The connection to the port is not secured by any encryption. However, it is possible to define an additional specific TLS-secured port. We shall cover spice + TLS protocol combinations in another article.
  • User authentication on the KVM server host? Can optionally be achieved via SASL.
  • Preferred Spice client? The Spice client which uses the Spice protocol directly and without libvirt is “remote-viewer“.
  • Works locally and/or remotely? Both.

Some additional hints:

In some old articles or posts on the Internet you may find descriptions of “virt-viewer” together with URIs like “spice://host:5900”. This does not work any more – at least on my systems.

By setting proper attributes to the VM, we can in addition enforce that it only accepts secured connections. For those who are eager to experiment already: Where do we learn something about such machine specific settings in XML-format? The answer is:
https://libvirt.org/formatdomain.html

Option 2: Connection with “virt-viewer” or “virt-manager” via libvirtd and a defined TCP port

Besides “remote-viewer” there is another Spice client called “virt-viewer“. This client is of special use when you work on a KVM host with multiple VMs. What some admins do not know is that it can be used via a simple socket with a specific TCP-port. You do not need SSH or TLS, if you can disregard security. This corresponds pretty much to what we got with remote-viewer and a Spice port. The difference is that we access the socket via the mediation of libvirtd components:

virt-viewer requires URIs which specify the target hypervisor for the libvirtd daemon – in our case “qemu”. Such URIs differ from URIs used for remote-viewer as they always contain a two fold protocol definition.

We shall apply such URIs in a later article. In addition this access method requires a special (non-default) configuration of the libvirt-daemon. Among other things, you, of course, have to define the port. The ability to listen to an insecure TCP port is normally deactivated in the libvirtd configuration; we have to activate it manually. This is something we shall have a closer look at.

Unencrypted access to the Spice console via a special libvirtd port may be a useful solution for KVM guests sitting in a secured physical LAN-segment or behind a virtual bridge/firewall in a virtualized LAN-segment of the KVM host.

Properties of a virt-viewer connection via a TCP port

  • Default port? 16509.
  • Security by encryption? The connection to the port is not secured by any encryption. However, we have other options for virt-viewer to connect to the VM via SSH or TLS secured connections. See below.
  • Preferred Spice client?: virt-viewer (You cannot provide a valid URI to remote-viewer this way). However, this connection option also works with “virt-manager” (and its included graphical access to the Spice console).
  • User authentication? Can be achieved via SASL.
  • Works
    locally and/or remotely?
    Both.

on the KVM host.
Note that the access to libvirtd must be allowed for the user invoking the connection! This can be configured on Opensuse Leap systems by some policy and/or libvirtd settings.

Option 3: Connection with “virt-viewer” or “virt-manager” via SSH and libvirtd

A very convenient method to get a secure connection with Linux is to use SSH encryption. Therefore, we are not astonished to find that “virt-viewer” can be combined with SSH. This connection method also requires a special URI-format. And again: access to libvirtd must be allowed for the user using this type of connection.

Properties of a virt-viewer connection via a SHH port:

  • Default port? 22 or otherwise the defined SSH-port on your system.
  • Security by encryption? SSH.
  • Preferred Spice client?: virt-viewer (You cannot provide a valid URI to remote-viewer this way). However, this connection option also works with “virt-manager” (and its included graphical access to the Spice console).
  • User authentication? Via SSH (preferably public-key authentication)
  • Works locally and/or remotely? Both.

Both options 2 and 3 work with virt-manager, too. However, virt-manager does not provide you with a multi-screen access to the Spice console.

Note that a combination of SSH and remote-viewer is also possible; but then you would open a “SSH -X” connection first and run remote-viewer on the KVM/Qemu host and not on the network client system. I will present such a solution in a later article, too.

Conclusion

The Spice console of KVM/Qemu offers access to a graphical desktop of a virtual machine guest. Spice clients as “remote-viewer”, “virt-viewer” and “virt-manager” can be used locally and remotely. The first two clients offer multiple screens – but all clients provide a one seat solution, only. This may, however, be sufficient for many use cases. There is a variety of local and remote access methods. Connections can be secured by TLS or SSH encryption.

In the next article

KVM/Qemu VMs with a multi-screen Spice console – II – local access with remote-viewer via a network port

I shall have a closer look at a local connection from the “remote-viewer” client to the Spice console of a VM.

Links

Spice console and Spice protocol
https://linuxhint.com/ configure_ spice_server_ debian_10/
https://www.spice-space.org/ spice-user-manual.html
https://www.spice-space.org/ spice-for-newbies.html

Activate spice
https://www.linux-kvm.org/page/SPICE
https://linux-blog.anracom.com/2017/08/15/kvmqemu-mit-qxl-hohe-aufloesungen-und-virtuelle-monitore-im-gastsystem-definieren-und-nutzen-iv/
https://octetz.com/docs/2020/2020-05-06-linux-hypervisor-setup/

Nvidia 🙁
https://www.phoronix.com/scan.php?page=news_item&px=XDC2016-Device-Memory-API

Further
articles in this series

KVM/Qemu VMs with a multi-screen Spice console – VIII – VM and user specific restrictions for remote-viewer connections – iptables and sudo
KVM/Qemu VMs with a multi-screen Spice console – VII – remote-viewer, qemu and SASL authentication
KVM/Qemu VMs with a multi-screen Spice console – VI – remote access with remote-viewer and TLS encryption
KVM/Qemu VMs with a multi-screen Spice console – V – remote access via remote-viewer, a network port and a SSH-tunnel
KVM/Qemu VMs with a multi-screen Spice console – IV – remote access via SSH, remote-viewer and a Unix socket
KVM/Qemu VMs with a multi-screen Spice console – III – local access with remote-viewer via a Unix socket
KVM/Qemu VMs with a multi-screen Spice console – II – local access with remote-viewer via a network port

Opensuse Leap, KVM/QEMU-guests, KMS – problems with QXL/Spice after upgrade to Leap 15

Many services in my LAN are provided by virtual KVM/QEMU-guests of a dedicated KVM-server-host. More special services are provided by local KVM-guests on Workstations. All my virtualized systems get normally equipped with a qxl/spice-combination to provide a graphical interface – which can be used on the KVM-host or by remote spice clients. A direct graphical access via a spice client is required only seldomly (besides ssh connections) – but in some cases or situations it is useful, if not mandatory.

Recently, I upgraded both the central KVM-Server, its guests and also guests on workstations from Opensuse Leap 42.3 to Leap 15.0. Unfortunately, after the upgrade no graphical access was possible any longer to my guest-systems via spice-clients (as virt-viewer or the graphical spice-console of virt-manager).

After some tests I found out that this was due to missing KMS on the guest systems – present qxl-modules, however, do require KMS. But, if you update/install from an ISO image “KMS” may not be compatible with the graphical SuSE installer. And due to previous configurations “nomodeset” may be a kernel parameter used in the installation before the upgrade. Here is the story …

The problem: Unreadable, freezing interfaces on spice-clients

Normally, I upgrade by a 5-step sequence: 1) Update all packets, 2) reduce repositories to the Update- and OSS-repository, 3) switch to the repositories of the new distribution, 4) “zypper dup –download-only”, 5) “zypper –no-refresh dup” (see e.g. how-to-upgrade-from-opensuse-leap-422-to-423/).

The KVM server-host itself gave me no major problem during its upgrade. Also the KVM-guests – with their server-services – seemed to work well. Most often, I access the KVM-guest-systems via ssh to perform regular administration tasks. So, I did not even notice for a while that something was wrong with the qxl/spice-configuration. But when I used “virt-manager” in an “ssh -X” session from my workstation to the KVM-server and tried to open the graphical console for a guest there, I got an unreadable virtual screen, which froze instantly and did no longer react to any input – special commands sent via “virt-manager” to switch to a non-graphical console terminal were ignored. The same happened with “virt-viewer” and/or when I executed virt-manager directly on the graphical screen of the KVM-server.

Independent test with a new installation of a “Leap 15”-guest-system

To find out more I tested a new installation of Leap 15 on my Leap 15 workstation as a KVM-server. I chose a guest system configuration with standard equipment – among other things qxl/spice-components. The installation was started via the “virt-installer” component of virt-manager. I used an ISO-image of the Leap 15 installation image.

First thing I stumbled across was that I had to use a “No KMS” for the text console setting on the first screen of the Opensuse installer (see the options for the graphical setup there; F3-key). Otherwise the installer froze during the first “udev” checks. I knew this effect already from installations on some physical systems. Note that the choice of “No KMS” leads to an kernel parameter entry “nomodeset” in the command line for the kernel call in the Grub2 configuration (see the file /etc/default/grub).

Such a full new installation lead into a void. SuSE’s graphical installer itself worked perfectly with high resolution. However, after a restart of the freshly installed guest-system the switch to the graphical screen lead to a flickering virtual screen and the graphical display of the SDDM login manager never appeared.

Still and luckily, it was possible to login as root and execute a “init 3” command – which brought me to a working, non-flickering ASCII console interface (TTY1).

I had experienced this
type of behavior before, too, on some real physical systems. I recommend Leap users to be prepared: activate ssh-services during installation and open the firewall for ssh-ports! The SuSE-installer allows for such settings on its summary screen for the installation configuration. This gives you a chance to switch to a working text console (init 3) from a remote SSH-command line – if the graphical console does not allow for any input.

Tests 2: Upgrade to latest KVM / QEMU / libvirt – versions of the “Virtualization” repository

An installation of the cutting edge versions of KVM/QEMU and spice sever and client software did not change anything – neither on my dedicated KVM-server-system and its upgraded guests nor on my workstation with the fresh Leap 15 test-guest.

Repair of the older upgraded guest-systems

The emulated “hardware” of my older (upgraded) guest-systems, which stem from an OS 13.2 era, is a bit different from the equipment of the newest test guest. On these older systems I still had the choice to use a cirrus, vga or vmwvga graphics. Interestingly, these drivers do not provide the performance of qxl – but they worked at least with the virtual spice client displays.

One central question was whether the QXL driver – more precisely the corresponding kernel module “qxl” – was loaded at all. Answer for the guests on the central KVM-server: No, it was not.

So, on the first guest I simply tried “modprobe qxl” – and hey – the module loaded. An “init 5” then gave me the aspired graphical screen.

Later I checked that actually no “nomodeset” parameter was set in these guests. So, something went “wrong” with the system’s startup-configuration during the upgrade procedure. I have no real clue why – as the qxl-module was loaded without problems on the previous Leap 42.3 installations.

For Opensuse Leap the wrapper-script “mkinitrd” transfers a running configuration with its loaded kernel modules via “dracut” into a suitable and permanent initramfs/initrd- and systemd-startup configuration. So, issue “mkinitrd” after a successful test of a qxl/spice-interface.

Repair of the freshly installed Leap 15 guest-system

On the freshly installed Leap 15 guest client on my workstation things were slightly different: The qxl-module did not load there. A “modinfo qxl” shows you parameters you can apply. The right thing to do there was to try

modprobe qxl modeset=1

This worked! Then I eliminated the “nomodeset”-parameter from the “GRUB_CMDLINE_LINUX_DEFAULT”-entry in the file “/etc/default/grub” and started “mkinitrd” to get a stable permanent startup-configuration (via dracut) which booted the guest into graphical mode afterwards.

Adjustment of the TTYs and KDE

As soon as you have a reasonable configuration, you may want to adjust the screen dimensions of the text consoles tty1 to tty6, the sddm-login-screen and the KDE or Gnome screen. These are topics for separate articles. See, however, previous articles in this blog on KVM guests for some hints.

For the text console TTYs try reasonable settings for the following entries in the “/etc/default/grub” – below e.g. for a resolution of “1680×1050”:

GRUB_CMDLINE_LINUX_DEFAULT=” …. OTHER PARAMETERS …… video=1680×1050″
GRUB_GFXMODE=”1680×1050″
GRUB_GFXPAYLOAD=keep

(see https://www.suse.com/de-de/support/kb/doc/?id=7017979)

Do not forget to execute “mkinitrd” again afterwards!

For KDE adjustments a user can use the command “systemsettings5” and then specify screen resolutions in the dialog for “display and monitors”.

Conclusion

The graphical installer of Opensuse, but also upgrade-procedures on working virtual KVM/QEMU guests with qxl/spice can lead to situations where KMS is or
must be deactivated both for physical and virtual systems. As a consequence the “qxl-module” may not be loadable automatically afterwards. This can lead to failures during the start of a graphical qxl/spice-interface for local and remote spice-clients.

The remedy is to remove any “nomodeset”-parameter which may be a part of the entry for “GRUB_CMDLINE_LINUX_DEFAULT” in the file “/etc/default/grub”.

For tests of the qxl-driver try loading the qxl-module with “modprobe qxl modeset=1”. After a successful start of a graphical interface use the command “mkinitrd” (whilst the qxl-module is loaded!) to establish a permanent configuration which loads “qxl” during system start.

KVM/qemu mit QXL – hohe Auflösungen und virtuelle Monitore im Gastsystem definieren und nutzen – IV

Will man auf einer Linux-Workstation den Desktop eines virtualisierten KVM/QEMU-Gastsystems [VM] nutzen, so wird man typischerweise auf die Kombination QXL und Spice-Client-Fenster setzen. Der Desktop des virtualisierten Gastsystems wird dann im Spice-Fenster auf dem normalen Desktop der Workstation dargestellt. In den letzten Artikeln dieser Serie hatten wir uns mit Konfigurationsmöglichkeiten zur Nutzung hoher Auflösungen auseinandergesetzt. Der erste Artikel

KVM/qemu mit QXL – hohe Auflösungen und virtuelle Monitore im Gastsystem definieren und nutzen – I

befasste sich mit Konfigurationsmöglichkeiten des QXL-Devices (memory, heads), die sich nicht direkt über das Tool “virt-manager” beeinflussen lassen. Ich hatte u.a. für die Memory-Dimensionierung Formeln angegeben; die resultierenden Daten kann man in die Konfigurationsdateien der virtuellen “Domäne” (also der VM) einbringen. Im zweiten Artikel

KVM/qemu mit QXL – hohe Auflösungen und virtuelle Monitore im Gastsystem definieren und nutzen – II

hatte ich dann den Einsatz von “xrandr” für hohe Auflösungen des “Desktops auf dem Betrachtersystem” und des darzustellenden “Desktops des QEMU-Gastes” vertieft. Dabei waren wir auch auf den QXL-Treiber und die Bedeutung des “spice-vdagents” (bzw. des zugehörigen Services) im Gastsystem eingegangen. Der letzte Artikel

KVM/qemu mit QXL – hohe Auflösungen und virtuelle Monitore im Gastsystem definieren und nutzen – III

zeigte dann, dass man für den Desktop des QEMU-Gastes auch Auflösungen und Vertikalfrequenzen anfordern kann, die durch den Monitor auf dem Betrachtersystem mit seinen Spice-Clients physikalisch nicht unterstützt werden. Anschließend wurden Möglichkeiten diskutiert, gewünschte Modline- und xrandr-Einstellungen im jeweiligen Linux-System persistent zu verankern.

Wir hatten ferner gesehen, dass man Spice-Fenster auch mit einer speziellen Option „Auto resize VM with window“ benutzen kann. Diese Option sorgt dafür, dass sich die Auflösung des Gast-Desktops automatisch an die Größe des Spice-Fensters anpasst. Das ist u.a. nützlich für den Einsatz von ausgedehnten Spice-Clients auf einem Multi-Monitor-System des Betrachters. Voraussetzung ist für sehr hohe Auflösungen eine hinreichende Ausstattung des QXL-Devices mit Video RAM.

Gibt es Defizite für die Praxis? Ja …

Der Desktop des virtualisierten Systems lässt sich nämlich mit den bisher diskutierten Verfahren nicht angemessen in mehrere Darstellungsflächen unterteilen. Natürlich stehen unter dem Desktop des Linux-Gastes alle Optionen für virtuelle Arbeitsflächen und Aktivitäten innerhalb dieses Desktops zur Verfügung. Aber:

Man kann das Spice-Fenster in der bisher benutzten grafischen “spice-console” des “virt-managers” nicht in mehrere unabhängig positionierbare Fenster auf dem Desktop des Betrachters unterteilen.

So ist es mit der Spice-Konsole nicht möglich, z.B. 2 verschiedene Applikationen des virtualisierten Systems unabhängig voneinander und jede in einer bestimmten Fenstergröße auf dem Desktop des Betrachters (z.B. auf der Workstation) anzuordnen. Wäre das möglich, dann könnte man als Nutzer gleichzeitig etwas in Richtung einer sog. “seamless integration” unternehmen.

Hinweis: Einen echten “Seamless Mode” wie ihn etwa VMware oder Virtual Box anbieten, gibt es zur Zeit nicht. Aber man arbeitet wohl daran: https://www.spinics.net/lists/spice-devel/msg30180.html

Jedenfalls ist es aus prinzipiellen Gründen und wegen einer verbesserten Ergonomie im Umgang mit virtualisierten Systemen interessant, sich den Desktop eines QEMU-Gastes unter Spice und QXL mal mit mehreren “virtuellen Monitoren” anzusehen. In der Spice-Terminologie ist hier von virtuellen “Displays” die Rede. Die sind Thema dieses Artikels.

Voraussetzung 1 der Nutzung mehrere virtueller Displays: Mehrere Heads, hinreichender Speicher des QXL-Devices und aktiver vdagent-Service

Als ich das erste Mal versucht habe, mehrere virtuelle Monitore auszuprobieren, funktionierte überhaupt nichts. Ursache:

Die Standardeinstellungen für das QXL-Device sind so, dass nur 1 Head aktiv ist. Zudem sind die Standardeinstellungen für den QXCL Video RAM unzureichend.

Beides ist zu ändern. Wir hatten die entsprechenden Einstellungen und Formeln für das QXL-Memory bereits im ersten Beitrag der Serie diskutiert. “virt-manager” bietet entsprechende Einstellungsoptionen zum QXL-Device aber nicht an. Man muss also zuerst mal die Domän-Datei “NAME.xml” im Verzeichnis “etc/libvirt/qemu” anpassen. “NAME” ist dabei der Name der virtuellen Maschine [VM]. Typische Memory-Werte für 4 Heads hatte ich bereits im ersten Artikel angegeben; s. dort für die notwendigen Schritte.

Das Gute an Linux-Gastsystemen ist, dass man danach außer der Aktivierung des QXL-Treibers und des “vdagents” (bzw. des zugehörigen Services) nichts anderes tun muss, um eine Unterstützung von bis zu 4 virtuellen Displays unter KVM/QEMU/Spice zu bekommen.

In gewisser Weise und im Gegensatz zu Tools wie X2GO arbeitet das Gastsystem hier keineswegs “headless”. Der Treiber des virtuellen QXL-Devices gaukelt dem Linux-System des Gastes vielmehr vor, dass das dortige QXL-Grafik-Device tatsächlich mehrere Ausgänge besitzt, die ein geeigneter Spice-Client dann (in Kooperation mit dem vdagent und dem QXL-Treiber) dynamisch mit angeschlossenen “Displays” belegt. Für deren Inhalt ist die Desktop-Umgebung des Gastes selbst verantwortlich. Spice übernimmt “nur” den Datenaustausch mit fenstern zur Darstellung dieses Desktops im Betrachtersystem.

Ich setze nachfolgend voraus, dass die QXL-Einstellungen entsprechend den Vorgaben des ersten Artikels für 4 Heads des QXL-Devices vorgenommen wurden. Getestet habe ich konkret mit folgenden QXL-Einstellungen:

    <video>
      <model type='qxl' ram='262144' vram64='2097152' vgamem='65536' heads='4' primary='yes'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
    </video>

 
Dem “Debian 9-Gastsystem” selbst hatte ich großzügigerweise 4GB RAM (Hauptspeicher) spendiert.

Voraussetzung 2 für mehrere virtuelle Displays: Nutzung des “remote-viewers”

Die grafische “spice-console” des “virt-managers” unterstützt meines Wissens keine Darstellung des Gastdesktops in mehreren “Displays”. Ein passender Client hierfür ist dagegen der sog. “remote-viewer“.

Man kann den “remote-viewer” von einem Terminalfesnter starten, nachdem man die virtuelle Maschine per “virt-manager” gestartet hat. Wir betrachten hier den Aufruf auf einer Linux-Workstation, die gleichzeitig als KVM-Host dient (Aufrufe über Netz werden Thema eines eigenen Artikels):

myself@mytux:~> remote-viewer spice://localhost:5900 &

Die Portnummer muss man ggf. anpassen, wenn man hierfür eine abweichende Einstellungen vorgenommen hat.

Hinweis: Unter Opensuse und Debian muss man ggf. Mitglied der Gruppe “libvirt” sein, um den remote-viewer erfolgreich ausführen
zu können; unter Ubuntu Mitglied der Gruppe “libvirtd”.

Sollte man vorher bereits einen anderen Spice-Client zur Darstellung des Gast-Desktops gestartet haben, wird diese frühere Spice-Sitzung unvermittelt und ohne Warnung abgebrochen.

Aktivierung zusätzlicher Bildschirme

Ein Blick auf die verfügbaren Menüpunkte zeigt schnell Unterschiede zur “spice-console”. So bietet der Menüpunkt “Ansicht >> Displays” Checkboxen für 4 Monitore (entsprechend den 4 Heads unseres QXL-Devices).

Man sieht, dass ich hier drei (virtuelle) “Displays” aktiviert habe. Der nachfolgende Screenshot zeigt diese “Displays” für die Darstellung des Desktops eines Debian 9-Gast-Systems auf einem von 3 physikalischen Monitoren einer Linux-Workstation, auf der selbst ein KDE-Desktop aktiv ist.

Zusätzliche virtuelle Displays erst nach dem Login aktivieren!

Der nächste Hinweis hat vielleicht nur Gültigkeit für einen Debian-Gast mit gdm3, aber mindestens mal da erweist sich der Tipp als nützlich:

Öffnet man im “remote-viewer” mehrere Displays, wenn noch die primäre Login-Maske von gdm3 angezeigt wird, so verschwindet die bei mir dann nach dem Aktivieren weiterer Displays – bzw. passte sich nicht mehr automatisch an den Fensterrahmen des ersten Displays an. Das ist wirklich unangenehm, weil man sich dann nicht mehr so ohne weiteres einloggen kann und zwischenzeitlich wieder auf die Spice-Konsole von virt-manager ausweichen muss. Also:

Erst einloggen, dann weitere virtuelle Displays aktivieren.

Automatische Auflösungsanpassung an die Größe der virtuellen Displays

Im “remote-viewer” gibt es keinen Menüpunkt zum Aktivieren/Deaktivieren einer automatischen Auflösungsanpassung an die Größe der aktivierten Displays. Das wird automatisch gemacht – unabhängig davon, was man vorher ggf. in der spice-console von virt-manager eingestellt haben sollte. Bei mir führte eine Veränderung der Größe irgendeines der geöffneten Displays zu einem Flackern aller virtuellen Displays, bis sich die neue Desktop-Darstellung aufgebaut hatte. Aber immerhin – die Anpassung funktioniert. Dabei gilt:

Die Spice-Fenster für die virtuellen Displays können völlig unterschiedliche Größen haben. Der Desktop des Gastes passt sich daran an!

Nahtloser Übergang zwischen den Displays

Es ist möglich, Applikationen nahtlos zwischen den verschiedenen Displays hin und her zu schieben. Dabei legt Spice in Abhängigkeit von verschiedenen Faktoren in sehr sinnvoller Weise fest, welches Display sich links oder rechts vom aktuellen Display befindet. Relevant ist dabei zum einen die Positionierung, die bei der letzten Größenänderung eines der Displays gegeben war:

Befand sich etwa “Display 3” bei der letzten links vom “Display 1”, so kann man eine Anwendung nach links aus dem “Display 1” in das “Display 3” bewegen – egal wo Display drei gerade ist.

Ein weiterer Faktor ist aber auch die Position der Maus – kommt die beim Ziehen in ein anderes Display (desselben Gastes), bewegt sich auch die Applikation dorthin.

Quasi-seamless Mode?

Wie gesagt, einen echten “Seamless Mode” bietet Spice noch nicht an. Aber: Wir können zumindest bis zu 4 Applikationen den Rahmen jeweils eines der 4 möglichen virtuellen Displays vollständig
füllen lassen – und auf dem Desktop der Workstation verteilen.

Das Schöne ist: Bei einer Größenänderung des jeweiligen virtuellen Displays passt sich die dort enthaltene Applikation dann automatisch an die Rahmengröße an.

Das nachfolgende Bild zeigt hoffentlich, was ich meine:

Hier sieht man von links nach rechts:

  • 1 virtuelles QXL/Spice-Display eines KVM/QEMU-Debian 9-Gastes mit Gnome, in dem VLC eine aktuelle ARD-Sendung abspielt.
  • 2 Clementine-Fenster, die dem KDE-Desktop der Workstation originär zugehören.
  • 1 virtuelles QXL/Spice-Display des KVM/QEMU-Debian 9-Gastes, in dem Libreoffice Draw geöffnet ist.
  • 1 Libreoffice Draw-Fenster, dass originär im KDE-Desktop der Workstation gestartet wurden.

Auf den ersten Blick sind die verschiedenen “Fenster” aber nicht als originale Fenster des KDE-Desktops der Workstation oder als Spice-Displays für die Darstellung des Gastdesktops einzuordnen. Das ist fast seamless und damit kann ich gut leben …

Multi-Monitor-Support im Gnome-Desktop des Gastes

Obwohl spezifisch für Gäste mit Gnome3-Desktop, hier ein kleiner Hinweis zur Multimonitor-Unterstützung: Man sollte sich hierfür unedingt ein paar aktuelle “Gnome-Extensions” installieren.

Die aktuellste Version von “Dash to dock” etwa erlaubt etwa die Auswahl des Spice-Displays, auf dem das Dock-Panel angezeigt werden soll. Und dann gibt es auch noch die sehr nützliche Erweiterung “Multi-Monitors AddOn”; sie erlaubt es verschiedene Informationsleisten etc. auf allen Displays anzeigen zu lassen:

Off-Topic: Was ist eigentlich mit Sound?

Nachdem ich oben in einer Abbildung einen Fernsehstream in einem Linux-Gast laufen ließ: Ist eigentlich eine Übertragung von Sound aus dem virtualisierten Gast in die Workstation möglich? Ich gehe auf diesen Punkt nur kurz ein, da dieser eigentlich nicht Thema dieser Artikelserie ist. Mir sind zudem auch noch nicht alle Zusammenhänge für den Soundtransfer klar. Es scheint jedoch so zu sein, dass das weniger ein Spice- als vielmehr ein QEMU-Thema ist.

Tja, und dann stolpern wir bei Internet-Recherchen erwartungsgemäß mal wieder über das Thema “Pulseaudio“. Vermutlich muss QEMU nämlich das Sound-Backend des KVM-Hosts unterstützen. Die Unterstützung verschiedener Soundsysteme ist aber etwas, was man bereits bei der Kompilierung von QEMU einstellen muss. In den meisten Distributionen (hier Opensuse) ist das QEMU-Paket aber lediglich mit Pulseaudio- und nicht mit reiner Alsa/Gstreamer-Unterstützung erstellt worden. Ergebnis:

Mit dem Standardpaket von QEMU unter Opensuse habe ich auf einem KVM-Host nur eine problemfreie Soundübertragung hinbekommen, wenn sowohl im Gastsystem als auch im Hostsystem Pulseaudio aktiv waren. Pures Alsa auf einer Linux-Workstation und KVM/QEMU-Virtualisierung sind zusammen wohl nicht ohne experimentellen Aufwand zu haben.

Mit Pulseaudio klappt die Soundübertragung aber gut – soweit Pulseaudio halt selbst mit den Gegebenheiten der Arbeitsstation (Soundkarten, Anwendungen) vernünftig umgehen kann. Und da gibt es nach wie vor Zipperleins. Immerhin kann man den Sound der virtuellen Maschine über Spice dann auch durch den systemweiten Ladspa-Equalizer von PA auf dem Betrachtersystem – hier also der Workstation
selbst – jagen. Das sieht dann etwa so aus:

Man beachte den “Remote Viewer”-Kanal im Lautstärke-Regler und dessen Verlinkung mit dem Ladspa-Equalizer! Das Bild dient nur der Illustration – Clementine würde ich normalerweise direkt auf das Device “Simultaneous Output” abbilden und den in Clementine eingebauten Equalizer nutzen. Der ist nämlich für mein Gefühl in den Übergängen zwischen den verschiedenen Frequenzbereichen besser und sanfter abgestimmt.

Aber PA ist ja ein Thema für sich – auch wenn sich langsam das eine oder andere bessert und die Zahl der Ungereimtheiten im praktischen Betrieb wenigstens ein wenig zurück gegangen ist.

Ausblick

Es gibt zwei Themen, die bisher nur stiefmütterlich behandelt wurden:

  • Die Netzwerkfähigkeit von libvirt und Spice.
  • Der “virtio”-Grafiktreiber, der alternativ zum qxl-Treiber auf Workstations benutzt werden kann, die gleichzeitig als KVM-Host und Client zur Nutzung der VM dienen.

Beide Punkte werde ich in kommenden Artikeln behandeln, sobald ich Zeit dazu finde. In der Zwischenzeit wünsche ich dem Leser viel Spaß beim Einsatz von KVM, QXL, Spice und virtuellen Displays.

Links

Spice-Clients
http://www.datacenter-insider.de/die-besten-spice-clients-zur-erhoehung-der-netzwerk-und-festplatten-performance-a-468322/

virt-viewer
https://access.redhat.com/ documentation/ en-US/ Red_Hat-_Enterprise-_Linux/6/html/Virtualization-_Administration-_Guide/chap-virt-tools.html#sect-virt-viewer

remote-viewer
https://access.redhat.com/ documentation/ en-US/ Red_Hat-_Enterprise-_Linux/6/html/ Virtualization-_Administration-_Guide/sect-Graphic-_User-_Interface-_tools-_for-_guest-_virtual-_machine-_management–remote_viewer.html

In die Links wurden Minus-Zeichen eingefügt, um einen Umbruch zu erreichen. Die korrekte URL muss man sich über einen Rechtsklick besorgen.