8.2 Configuring Remote Connections

A major benefit of libvirt is the ability to manage VM Guests on different remote hosts from a central location. This section gives detailed instructions on how to configure server and client to allow remote connections.

8.2.1 Remote Tunnel over SSH (qemu+ssh)

Enabling a remote connection that is tunneled over SSH on the VM Host Server only requires the ability to accept SSH connections. Make sure the SSH daemon is started (rcsshd status) and that the ports for service SSH are opened in the firewall.

User authentication for SSH connections can be done using traditional file user/group ownership and permissions as described in Access Control for UNIX Sockets with Permissions and Group Ownership. Connecting as user tux (qemu+ssh://tuxsIVname;/system) works out of the box and does not require additional configuration on the libvirt side.

When connecting via SSH qemu+ssh://USER@SYSTEM you need to provide the password for USER. This can be avoided by copying your public key to ~USER/.ssh/authorized_keys on the VM Host Server as explained in Section 14.5.2, Copying an SSH Key, (↑Security Guide). Using an ssh-agent on the machine from which you are connecting adds even more convenience—see Section 14.5.3, Using the ssh-agent, (↑Security Guide) for instructions.

8.2.2 Remote TLS/SSL Connection with x509 Certificate (qemu+tls)

Using TCP connections with TLS/SSL encryption and authentication via x509 certificates is much more complicated to set up than SSH, but it is a lot more scalable. Use this method if you have to manage several VM Host Servers with a varying number of administrators.

Basic concept

Basically, TLS (Transport Layer Security) encrypts the communication between two computers by using certificates. The computer starting the connection is always considered as the client using a client certificate, while the receiving computer is always considered as the server, using a server certificate. This scenario applies, for example, if you manage your VM Host Servers from a central desktop.

If connections are initiated from both computers, each needs to have a client and a server certificate. This is the case, for example, if you migrate a VM Guest from one host to another.

Each x509 certificate has a matching private key file. Only the combination of certificate and private key file is able to identify itself correctly. In order to assure that a certificate was issued by the assumed owner, it is signed and issued by a central certificate called certificate authority (CA). Both the client and the server certificates must be issued by the same CA.

IMPORTANT: User Authentication

Using a remote TLS/SSL connection basically only ensures that two computers are allowed to communicate in a certain direction. Restricting access to certain users can indirectly be achieved on the client side by restricting access to the certificates. Refer to Restricting Access (Security Considerations) for details. libvirt also supports user authentication on the server with SASL. Read more in Central User Authentication with SASL for TLS Sockets.

Configuring the VM Host Server

The VM Host Server is the machine receiving connections. Therefore, the server certificates have to be installed. The CA certificate needs to be installed, as well. Once the certificates are in place, TLS support can be turned on for libvirt.

  1. Create the server certificate and export it together with the CA certificate as described in Section A.2, Generating x509 Client/Server Certificates.

  2. Create the following directories on the VM Host Server:

    mkdir -p /etc/pki/CA/ /etc/pki/libvirt/private/

    Install the certificates as follows:

    /etc/pki/CA/cacert.pem
    /etc/pki/libvirt/servercert.pem
    /etc/pki/libvirt/private/serverkey.pem

    IMPORTANT: Restrict Access to Certificates

    Make sure to restrict access to certificates as explained in Restricting Access (Security Considerations).

  3. Enable TLS support by editing /etc/libvirt/libvirtd.conf and setting listen_tls = 1. Restart libvirtd:

    rclibvirtd restart
  4. By default, libvirt uses the TCP port 16514 for accepting secure TLS connections. Open this port in the firewall.

IMPORTANT: Restarting libvirtd with TLS enabled

If you enable TLS for libvirt, the server certificates need to be in place, otherwise restarting libvirtd will fail. You also need to restart libvirtd in case you change the certificates.

Configuring the Client and Testing the Setup

The client is the machine initiating connections. Therefore the client certificates have to be installed. The CA certificate needs to be installed, as well.

  1. Create the client certificate and export it together with the CA certificate as described in Section A.2, Generating x509 Client/Server Certificates.

  2. Create the following directories on the client:

    mkdir -p /etc/pki/CA/ /etc/pki/libvirt/private/

    Install the certificates as follows:

    /etc/pki/CA/cacert.pem
    /etc/pki/libvirt/clientcert.pem
    /etc/pki/libvirt/private/clientkey.pem

    IMPORTANT: Restrict Access to Certificates

    Make sure to restrict access to certificates as explained in Restricting Access (Security Considerations).

  3. Test the client/server setup by issuing the following command. Replace mercury.example.com with the name of your VM Host Server. Specify the same full qualified hostname as used when creating the server certificate.

    virsh -c qemu+tls://mercury.example.com/system list --all

    If your setup is correct, you will see a list of all VM Guests registered with libvirt on the VM Host Server.

Enabling VNC for TLS/SSL connections

Currently, VNC communication over TLS is only supported by few tools. The widespread tightvnc or tigervnc viewer, for example, do not support TLS. Known to work are the Virtual Machine Manager (virt-manager), virt-viewer and the GNOME VNC viewer vinagre.

VNC over TLS/SSL: VM Host Server Configuration

In order to access the graphical console via VNC over TLS/SSL, you need to configure the VM Host Server as follows:

  1. Open ports for the service VNC in your firewall.

  2. Create a directory /etc/pki/libvirt-vnc and link the certificates into this directory as follows:

    mkdir -p /etc/pki/libvirt-vnc && cd /etc/pki/libvirt-vnc
    	ln -s /etc/pki/CA/cacert.pem ca-cert.pem
    	ln -s /etc/pki/libvirt/servercert.pem server-cert.pem
    	ln -s /etc/pki/libvirt/private/serverkey.pem server-key.pem
  3. Edit /etc/libvirt/qemu.conf and set the following parameters:

    vnc_listen = "0.0.0.0"
    	vnc_tls = 1
    	vnc_tls_x509_verify = 1
  4. Restart the libvirtd:

    rclibvirtd restart

    IMPORTANT: VM Guests Need to be Restarted

    The VNC TLS setting is only set when starting a VM Guest. Therefore, you need to restart all machines that have been running prior to making the configuration change.

VNC over TLS/SSL: Client Configuration

The only action needed on the client side is to place the x509 client certificates in a location recognized by the client of choice. Unfortunately, each supported client—Virtual Machine Manager, virt-viewer, and vinagre—expects the certificates in a different location. However, Virtual Machine Manager and vinagre can either read from a system-wide location applying to all users, or from a per user location.

Virtual Machine Manager (virt-manager)

In order to connect to the remote host, Virtual Machine Manager requires the setup explained in Configuring the Client and Testing the Setup. In order to be able to connect via VNC the client certificates also need to be placed in the following locations:

System wide location
  • /etc/pki/CA/cacert.pem
  • /etc/pki/libvirt-vnc/clientcert.pem
  • /etc/pki/libvirt-vnc/private/clientkey.pem
Per user location
  • /etc/pki/CA/cacert.pem
  • ~/.pki/libvirt-vnc/clientcert.pem
  • ~/.pki/libvirt-vnc/private/clientkey.pem
virt-viewer

virt-viewer only accepts certificates from a system wide location:

  • /etc/pki/CA/cacert.pem
  • /etc/pki/libvirt-vnc/clientcert.pem
  • /etc/pki/libvirt-vnc/private/clientkey.pem
vinagre
System wide location
  • /etc/pki/CA/cacert.pem
  • /etc/pki/vinagre/clientcert.pem
  • /etc/pki/vinagre/private/clientkey.pem
Per user location
  • $HOME/.pki/CA/cacert.pem
  • ~/.pki/vinagre/clientcert.pem
  • ~/.pki/vinagre/private/clientkey.pem

IMPORTANT: Restrict Access to Certificates

Make sure to restrict access to certificates as explained in Restricting Access (Security Considerations).

Restricting Access (Security Considerations)

Each x509 certificate consists of two pieces: the public certificate and a private key. A client can only authenticate using both pieces. Therefore, any user that has read access to the client certificate and its private key can access your VM Host Server. On the other hand, an arbitrary machine equipped with the full server certificate can pretend to be the VM Host Server. Since this is probably not desirable, access to at least the private key files needs to be restricted as much as possible. The easiest way to control access to a key file is to use access permissions.

Server Certificates

Server certificates need to be readable for QEMU processes. On SUSE Linux Enterprise Server QEMU processes started from libvirt tools are owned by root, so it is sufficient if root is able to read them certificates:

chmod 700 /etc/pki/libvirt/private/
chmod 600 /etc/pki/libvirt/private/serverkey.pem

If you change the ownership for QEMU processes in /etc/libvirt/qemu.conf, you also need to adjust the ownership of the key file.

System Wide Client Certificates

To control access to a key file that is available system wide, restrict read access a certain group, so that only members of that group can read the key file. In the following example, a group libvirt is created and the group ownership of the clientkey.pem and its parent directory is set to libvirt. Afterwards, the access permissions are restricted to owner and group. Finally the user tux is added to the group libvirt, so he will be able to access the key file.

CERTPATH="/etc/pki/libvirt/"
# create group libvirt
groupadd libvirt
# change ownership to user root and group libvirt
chown root.libvirt $CERTPATH/private $CERTPATH/clientkey.pem
# restrict permissions
chmod 750 $CERTPATH/private
chmod 640 $CERTPATH/private/clientkey.pem
# add user tux to group libvirt
usermod -A libvirt tux
Per User Certificates

User specific client certificates for accessing the graphical console of a VM Guest via VNC need to be placed in the users home directory in ~/.pki. Contrary to, for example, the VNC viewer using these certificates do not check the access permissions of the private key file. Therefore, it is solely on the user's responsibility to make sure the key file is not readable by others.

Restricting Access from the Server Side

By default, every client that is equipped with appropriate client certificates may connect to a VM Host Server accepting TLS connections. Therefore, it is possible to use additional server side authentication with SASL as described in Username and Password Authentication with SASL.

It is also possible to restrict access with a whitelist of DNs (distinguished names), so only clients with a certificate matching a DN from the list can connect.

Add a list of allowed DNs to tls_allowed_dn_list in /etc/libvirt/libvirtd.conf. This list may contain wild cards. Do not specify an empty list, since that would result in refusing all connections.

tls_allowed_dn_list = [
   "C=US,L=Provo,O=SUSE Linux Products GmbH,OU=*,CN=venus.example.com,EMAIL=*",
   "C=DE,L=Nuremberg,O=SUSE Linux Products GmbH,OU=Documentation,CN=*"]

Get the distinguished name of a certificate with the following command:

certtool -i --infile /etc/pki/libvirt/clientcert.pem | grep "Subject:"

Restart libvirtd after having changed the configuration:

rclibvirtd restart

Central User Authentication with SASL for TLS Sockets

A direct user authentication via TLS is not possible - this is handled indirectly on each client via the read permissions for the certificates as explained in Restricting Access (Security Considerations). However, if a central, server based user authentication is needed libvirt also allows to use SASL (Simple Authentication and Security Layer) on top of TLS for direct user authentication. See Username and Password Authentication with SASL for configuration details.

Troubleshooting

Virtual Machine Manager/virsh Cannot Connect to Server

Check the following in the given order:

  • Is it a firewall issue (TCP port 16514 needs to be open on the server)?
  • Is the client certificate (certificate and key) readable by the user that has started Virtual Machine Manager/virsh?
  • Has the same full qualified hostname as in the server certificate been specified with the connection?
  • Is TLS enabled on the server (listen_tls = 1)?
  • Has libvirtd been restarted on the server?
VNC Connection fails

Ensure that you can basically connect to the remote server using Virtual Machine Manager. If so, check whether the virtual machine on the server has been started with TLS support. The virtual machine's name in the following example is sles11.

ps ax | grep qemu | grep "\-name sles11" | awk -F" -vnc " '{ print FS $2 }'

If the output does not begin with a string similar to the following, the machine has not been started with TLS support and must be restarted.

 -vnc 0.0.0.0:0,tls,x509verify=/etc/pki/libvirt