Spice basics
Basic Definitions
Host Host is a machine running an instance of qemu-kvm.
Guest Guest is a virtual machine hosted on the host which will be accessed with a spice client.
Client Client is referring to a system running the spice client (the recommended one is virt-viewer).
Launching qemu I'll use qemu-kvm as a name for the executable. If you're using a manually built qemu or a qemu without kvm then just replace qemu-kvm with your own binary. I'll use host# client# guest# shell prompt notations to distinguish where the command should be the command. See section Basic Definitions to be sure that you know difference between the host, client and guest. You can ignore the difference between guest, client and host if they are all running on the same machine. The first important thing to do is to create a guest image. You can use any raw device such as a clean logical volume, or an iSCSI lun. You may also use a file as the disk image for the guest. I'll use a file created by qemu-img as a demonstration. The following command will allocate a 10GB file. See qemu-img man page for further information. host# qemu-img create /path/to/xp.img 10G Now that we created an image, we can now start with image population. I assume that you have a locally stored ISO of your favourite operating system so you can use it for installation. host# sudo qemu-kvm -boot order=dc -vga qxl \ -spice port=3001,disable-ticketing -soundhw ac97 \ -device virtio-serial -chardev spicevmc,id=vdagent,debug=0,name=vdagent \ -device virtserialport,chardev=vdagent,name=com.redhat.spice.0 \ -cdrom /path/to/your.iso /path/to/your.img Let's take a brief look at the qemu options that were used. The option -boot order=dc specifies that the guest system should try to boot from the first cdrom and then fallback to the first disk, -vga qxl specifies that qemu should emulate the qxl device adapter. The Spice port option defines what port will be used for communication with the client. The Spice option disable-ticketing is telling us that ticketing (simple authentication method) is not used. The virtio and chardev devices are required by the guest agent.
Adding Spice support to an existing virtual machine This section will assume that you already have a running QEMU virtual machine, and that you are running it either through virt-manager, libvirt or through direct QEMU use, and that you want to enable Spice support for this virtual machine.
Using virt-manager Double-click on the virtual machine you are interested in, go to View/Details. If the left pane has a "Display Spice" entry, then the virtual machine already has Spice support, and you can check the connection details (port number) by clicking on it. If it has no Spice entry, click on "Add Hardware", and add a "Graphics" element of type "Spice server". If the host and the client are not the same machine, you should check the "Listen on all public network interfaces" checkbox, otherwise you don't need to make any changes. You should also add a QXL video device. It can be done by double-clicking on a virtual machine, then by going to View/Details, and by clicking on "Add Hardware" if the virtual machine does not have a "Video QXL" item in its left pane. From the "Add hardware" dialog, you should then create a "Video" device whose model is "QXL". After stopping and restarting the virtual machine, it should be accessible with a Spice client. You can remove non-Spice display entries and non-QXL video entries from the virtual machine configuration. If you go to Edit/Preferences/VM Details in the main virt-manager window, you can set Spice graphics type as the default setting for new virtual machines.
Using libvirt All libvirt examples will assume that the virtual machine to modify is $vmname and that virsh is using the correct libvirt connection by default. To add Spice support to an existing virtual machine managed by libvirt, you need to edit it: host# virsh edit $vmname and then add a Spice graphics element: <graphics type='spice'/> You should also add a QXL video device <video> <model type='qxl'> </video> After stopping and restarting the virtual machine $vmname, it should be accessible through Spice. You can check the connection parameters with: host# virsh domdisplay $vmname
Using QEMU To enable Spice support to your virtual machine, you only need to append the following to your QEMU command line: -spice port=3001,disable-ticketing This will setup a Spice session listening on port 3001 exporting your virtual machine display. You can also add a QXL device by appending this to the command line: -vga qxl
Connecting to guest The following section will show you basic usage of the Spice client. The example connection will be related to the qemu instance started in the previous section. Be aware that the port used for spice communication (port 3001 in our case) should not be blocked by firewall. Host myhost is referring to the machine which is running our qemu instance. client# remote-viewer spice://myhost:3001
Established connection to Windows 2008 guest
Ticketing Spice does not currently support multiple connections to the same qemu instance. So anybody who will connect to the same host and port can simply take over your session. You can eliminate this problem by using ticketing or SSL. Ticketing is a simple authentication system which enables you to set simple tickets to a vm. Client has to authentificate before the connection can be established. See the spice option password in the following example.
Using virt-manager To set a Spice password for a virtual machine, go to this machine details in virt-manager, and then click on the "Display Spice" item in the left pane, and enter the ticket you want to use in the "Password" field.
Using libvirt All you need to do is to append a passwd attribute to the Spice graphics node for your virtual machine: <graphics type='spice' passwd='mysecretpassword'/>
Using QEMU Adding a ticket with QEMU involves a slight modification of the -spice parameter used when running QEMU: -spice port=3001,password=mysecretpassword
Client When you start the client as usual, if ticketing was enabled on the host, remote-viewer will pop up a window asking for a password before starting the Spice session. It won't be established if an incorrect ticket was passed to the client. You might have figured out that passing tickets as a commandline option isn't very safe. It's not safe as everybody with access to the host can read it from the output of ps(1). To prevent this, the ticket can be also set by using the qemu console command spice._set_ticket.
Agent Agent support allows better integration with the guest. For example, it allows copy and paste between the guest and the host OSes, dynamic resolution changes when the client window is resized/fullscreened, file transfers through drag and drop, ... The agent is a daemon/service running in the guest OS so it must be installed if it was not installed by default during the guest OS installation. It also relies on a virtio-serial PCI device and a dedicated spicevmc char device to achieve communication between the guest and the host. These devices must be added to the virtual machine if we want to agent to work properly in the guest.
Using virt-manager The needed devices can be added from the virtual machine details. Click on "Add hardware" and then add a "Channel" device with type "Spice agent (spicevmc)". This will automatically add the needed virtio-serial device in addition to the spicevmc channel.
Using libvirt Two distinct devices must be added: a virtio serial device a spicevmc channel <devices> <controller type='virtio-serial' index='0'/> <channel type='spicevmc'> <target type='virtio' name='com.redhat.spice.0'/> </channel> </devices>
Using QEMU Adding the following parameters to your QEMU command line will enable the needed devices for agent support in the guest OS: -device virtio-serial \ -chardev spicevmc,id=vdagent,debug=0,name=vdagent \ -device virtserialport,chardev=vdagent,name=com.redhat.spice.0 \
USB redirection With USB redirection, USB devices plugged into the client machine can be transparently redirected to the guest OS. This redirection can either be automatic (all newly plugged devices are redirected), or manual (the user selects which devices (s)he wants to redirect). For redirection to work, the virtual machine must have an USB2 EHCI controller (this implies 3 additional UHCI controllers). It also needs to have Spice channels for USB redirection. The number of such channels correspond to the number of USB devices that it will be possible to redirect at the same time.
Using virt-manager Virtual machines created with virt-manager should have a USB controller by default. In the virtual machine details, select "Controller USB" in the left pane, and make sure its model is set to USB2. You can then click on "Add Hardware" and add as many "USB Redirection" items as the number of USB devices you want to be able to redirect simultaneously.
Using libvirt You need to add the needed USB controllers to the libvirt XML (make sure there is no pre-existing USB controller in your virtual machine XML before doing this), as well as one Spice USB redirection channel per device you want to redirect simultaneously. <controller type='usb' index='0' model='ich9-ehci1'/> <controller type='usb' index='0' model='ich9-uhci1'> <master startport='0'/> </controller> <controller type='usb' index='0' model='ich9-uhci2'> <master startport='2'/> </controller> <controller type='usb' index='0' model='ich9-uhci3'> <master startport='4'/> </controller> <redirdev bus='usb' type='spicevmc'/> <redirdev bus='usb' type='spicevmc'/> <redirdev bus='usb' type='spicevmc'/> <redirdev bus='usb' type='spicevmc'/>
Using QEMU Similarly to libvirt, we need to add EHCI/UHCI controllers to QEMU command line, and we also need to add one Spice redirection channel per device we want to redirect simultaneously. -device ich9-usb-ehci1,id=usb \ -device ich9-usb-uhci1,masterbus=usb.0,firstport=0,multifunction=on \ -device ich9-usb-uhci2,masterbus=usb.0,firstport=2 \ -device ich9-usb-uhci3,masterbus=usb.0,firstport=4 \ -chardev spicevmc,name=usbredir,id=usbredirchardev1 \ -device usb-redir,chardev=usbredirchardev1,id=usbredirdev1 \ -chardev spicevmc,name=usbredir,id=usbredirchardev2 \ -device usb-redir,chardev=usbredirchardev2,id=usbredirdev2 \ -chardev spicevmc,name=usbredir,id=usbredirchardev3 \ -device usb-redir,chardev=usbredirchardev3,id=usbredirdev3
Client The client needs to have support for USB redirection. In remote-viewer, you can select which USB devices to redirect in File/USB device selection once the Spice connection is established. There are also various command line redirection options which are described when running remote-viewer with --help-spice.
Multiple monitor support When using Spice, it's possible to use multiple monitors. For that, the guest must have multiple QXL devices (for Windows guests), or a single QXL device configured to support multiple heads (for Linux guests). Before following the instructions in this section, make sure your virtual machine already has a QXL device. If that is not the case, refer to this section. Your guest OS will also need to have the QXL driver installed or multiple monitor support will not work. Once your virtual machine is using a QXL device, you don't need to make any other change to get multiple heads in a Linux guest. The following paragraph will deal with adding multiple QXL devices to get multiple monitors in a Windows guest.
Using virt-manager To add an additional QXL device for Windows guests, simply go to your virtual machine details. Check that you already have a "Video QXL" device, if notclick on "Add Hardware", and add a "Video" device with model "QXL". This can also work with Linux guests if your are willing to configure X.Org to use Xinerama (instead of XRandR). If you are using a new enough distribution (for example Fedora 19), and if your virtual machine already has a QXL device, you should not need to make any changes in virt-manager. If you are using an older distribution, you can't do the required changes from virt-manager, you'll need to edit libvirt XML as described on this blog post.
Using libvirt To add an additional QXL device to your virtual machine managed by libvirt, you simply need to append a new video node whose model is QXL: <video> <model type='qxl'> </video> <video> <model type='qxl'> </video>
Using QEMU To get a second QXL device in your virtual machine, you need to append -device qxl to your QEMU command line in addition to the -vga qxl that is already there: -vga qxl -device qxl
Client You can enable additional displays either from the Display/Displays menu in remote-viewer, or from your guest OS display configuration tool.
TLS TLS support allows to encrypt all/some of the channels Spice uses for its communication. A separate port is used for the encrypted channels. When connecting through a TLS channel, the Spice client will verify the certificate sent by the host. It will check that this certificate matches the hostname it's connecting, and that this certificate is signed by a known certificate authority (CA). This can be achieved by either getting the host certificate signed by an official CA, or by passing to the client the certificate of the authority which signed the host certificate. The latter allows the use of self-signed certificates.
Using virt-manager It's not possible to define the CA certificate/host certificate to use for the TLS connection using virt-manager, see the next section for how to enable this using libvirt.
Using libvirt The certificate must be specified in libvirtd configuration file in /etc/libvirt/qemu.conf (or in ~/.config/libvirt/qemu.conf if you are using a session libvirt). See the documentation in this file reproduced below: # Enable use of TLS encryption on the SPICE server. # # It is necessary to setup CA and issue a server certificate # before enabling this. # spice_tls = 1 # Use of TLS requires that x509 certificates be issued. The # default it to keep them in /etc/pki/libvirt-spice. This directory # must contain # # ca-cert.pem - the CA master certificate # server-cert.pem - the server certificate signed with ca-cert.pem # server-key.pem - the server private key # # This option allows the certificate directory to be changed. # spice_tls_x509_cert_dir = "/etc/pki/libvirt-spice" Once the above is done, when the domain is running, you should get something like what is below if you are leaving Spice port allocation up to libvirt: host# virsh domdisplay spice://127.0.0.1?tls-port=5901 This means that the connection is possible both through TLS and without any encryption. You can edit the libvirt graphics node if you want to change that behaviour and only allow connections through TLS: <graphics type='spice' autoport='yes' defaultMode='secure'/>
Using QEMU QEMU expects the certificates to be named the same way as what libvirt expects in the previous paragraph. The directory where these certificates can be found is specified as options to the -spice command line parameters: -spice port=5900,tls-port=5901,disable-ticketing,x509-dir=/etc/pki/libvirt-spice
Client We need to change 2 things when starting the client: specify the tls port to use specify the CA certificate to use when verifying the host certificate With remote-viewer, this is done this way: client# remote-viewer --spice-ca-file=/etc/pki/libvirt-spice/ca-cert.ca spice://myhost?tls-port=5901
Generating self-signed certificates for use with Spice The following script can be used to create the various certificates needed to use a TLS Spice connection. Make sure to substitute the hostname of your Spice host in the subject of the certificate signing request. SERVER_KEY=server-key.pem # creating a key for our ca if [ ! -e ca-key.pem ]; then openssl genrsa -des3 -out ca-key.pem 1024 fi # creating a ca if [ ! -e ca-cert.pem ]; then openssl req -new -x509 -days 1095 -key ca-key.pem -out ca-cert.pem -utf8 -subj "/C=IL/L=Raanana/O=Red Hat/CN=my CA" fi # create server key if [ ! -e $SERVER_KEY ]; then openssl genrsa -out $SERVER_KEY 1024 fi # create a certificate signing request (csr) if [ ! -e server-key.csr ]; then openssl req -new -key $SERVER_KEY -out server-key.csr -utf8 -subj "/C=IL/L=Raanana/O=Red Hat/CN=myhostname.example.com" fi # signing our server certificate with this ca if [ ! -e server-cert.pem ]; then openssl x509 -req -days 1095 -in server-key.csr -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out server-cert.pem fi # now create a key that doesn't require a passphrase openssl rsa -in $SERVER_KEY -out $SERVER_KEY.insecure mv $SERVER_KEY $SERVER_KEY.secure mv $SERVER_KEY.insecure $SERVER_KEY # show the results (no other effect) openssl rsa -noout -text -in $SERVER_KEY openssl rsa -noout -text -in ca-key.pem openssl req -noout -text -in server-key.csr openssl x509 -noout -text -in server-cert.pem openssl x509 -noout -text -in ca-cert.pem
SASL Spice server and client have support for SASL authentication. When using QEMU, /etc/sasl2/qemu.conf will be used as a configuration file. For testing, you can use the digest-md5 mechanism, and populate a test database using 'saslpasswd2 -f /etc/qemu/passwd.db -c foo'. These files have to be readable by the qemu process that will handle your VM. To troubleshoot SASL issues, running strace -e open on the QEMU process can be a useful first step.
Using virt-manager It's currently not possible to enable SASL from virt-manager.
Using libvirt SASL support for SPICE has been added to libvirt mid-October 2013 so you need a libvirt version that was released after this date. To enable SASL, you need to add spice_sasl = 1 in /etc/libvirt/qemu.conf for the system libvirtd instance, and to ~/.config/libvirt/qemu.conf for the session libvirtd instance.
Using QEMU Using SASL with QEMU involves a slight modification of the -spice parameter used when running QEMU: -spice port=3001,sasl
Client When you start the client as usual, if SASL was enabled on the host, remote-viewer will pop up a window asking for a password before starting the Spice session. It won't be established if an incorrect ticket was passed to the client.