10 Connecting and Authorizing #
Managing several VM Host Servers, each hosting multiple VM Guests, quickly
becomes difficult. One benefit of libvirt
is the ability to connect to
several VM Host Servers at once, providing a single interface to manage all
VM Guests and to connect to their graphical console.
To ensure only authorized users can connect, libvirt
offers
several connection types (via TLS, SSH, Unix sockets, and TCP) that can be
combined with different authorization mechanisms (socket, Polkit, SASL
and Kerberos).
10.1 Authentication #
The power to manage VM Guests and to access their graphical console is something that should be restricted to a well defined circle of persons. To achieve this goal, you can use the following authentication techniques on the VM Host Server:
Access control for Unix sockets with permissions and group ownership. This method is available for
libvirtd
connections only.Access control for Unix sockets with Polkit. This method is available for local
libvirtd
connections only.User name and password authentication with SASL (Simple Authentication and Security Layer). This method is available for both,
libvirtd
and VNC connections. Using SASL does not require real user accounts on the server, since it uses its own database to store user names and passwords. Connections authenticated with SASL are encrypted.Kerberos authentication. This method, available for
libvirtd
connections only, is not covered in this manual. Refer to https://libvirt.org/auth.html#ACL_server_kerberos for details.Single password authentication. This method is available for VNC connections only.
libvirtd
and VNC need to be configured separately
Access to the VM Guest's management functions (via libvirtd
) on
the one hand, and to its graphical console on the other hand, always
needs to be configured separately. When restricting access to the
management tools, these restrictions do not
automatically apply to VNC connections!
When accessing VM Guests from remote via TLS/SSL connections, access can be indirectly controlled on each client by restricting read permissions to the certificate's key file to a certain group. See Section 10.3.2.5, “Restricting Access (Security Considerations)” for details.
10.1.1 libvirtd
Authentication #
libvirtd
authentication is configured in
/etc/libvirt/libvirtd.conf
. The configuration made
here applies to all libvirt
tools such as the Virtual Machine Manager or
virsh
.
libvirt
offers two sockets: a read-only socket for monitoring
purposes and a read-write socket to be used for management operations.
Access to both sockets can be configured independently. By default, both
sockets are owned by root.root
. Default access
permissions on the read-write socket are restricted to the user
root
(0700
) and fully open on the read-only
socket (0777
).
In the following instructions, you will learn how to configure access permissions for the read-write socket. The same instructions also apply to the read-only socket. All configuration steps need to be carried out on the VM Host Server.
The default authentication method on SUSE Linux Enterprise Server is access control
for Unix sockets. Only the user root
may authenticate. When
accessing the libvirt
tools as a non-root user directly on the
VM Host Server, you need to provide the root
password through
Polkit once. You are then granted access for the current and for future
sessions.
Alternatively, you can configure libvirt
to allow
“system” access to non-privileged users. See
Section 10.2.1, ““system” Access for Non-Privileged Users” for details.
- Local Connections
Section 10.1.1.2, “Local Access Control for Unix Sockets with Polkit” Section 10.1.1.1, “Access Control for Unix Sockets with Permissions and Group Ownership” - Remote Tunnel over SSH
Section 10.1.1.1, “Access Control for Unix Sockets with Permissions and Group Ownership” - Remote TLS/SSL Connection
Section 10.1.1.3, “User name and Password Authentication with SASL” none (access controlled on the client side by restricting access to the certificates)
10.1.1.1 Access Control for Unix Sockets with Permissions and Group Ownership #
To grant access for non-root
accounts, configure the
sockets to be owned and accessible by a certain group
(libvirt
in the following
example). This authentication method can be used for local and remote
SSH connections.
In case it does not exist, create the group that should own the socket:
>
sudo
groupadd libvirtImportant: Group Needs to ExistThe group must exist prior to restarting
libvirtd
. If not, the restart will fail.Add the desired users to the group:
>
sudo
usermod --append --groups libvirt tuxChange the configuration in
/etc/libvirt/libvirtd.conf
as follows:unix_sock_group = "libvirt"1 unix_sock_rw_perms = "0770"2 auth_unix_rw = "none"3
Restart
libvirtd
:>
sudo
systemctl start libvirtd
10.1.1.2 Local Access Control for Unix Sockets with Polkit #
Access control for Unix sockets with Polkit is the default
authentication method on SUSE Linux Enterprise Server for non-remote connections.
Therefore, no libvirt
configuration changes are needed. With
Polkit authorization enabled, permissions on both sockets default to
0777
and each application trying to access a socket
needs to authenticate via Polkit.
Authentication with Polkit can only be used for local connections on the VM Host Server itself, since Polkit does not handle remote authentication.
Two policies for accessing libvirt
's sockets exist:
org.libvirt.unix.monitor: accessing the read-only socket
org.libvirt.unix.manage: accessing the read-write socket
By default, the policy for accessing the read-write socket is to
authenticate with the root
password once and grant the
privilege for the current and for future sessions.
To grant users access to a socket without having to provide
the root
password, you need to create a rule in
/etc/polkit-1/rules.d
. Create the file
/etc/polkit-1/rules.d/10-grant-libvirt
with the
following content to grant access to the read-write socket to all
members of the group
libvirt
:
polkit.addRule(function(action, subject) { if (action.id == "org.libvirt.unix.manage" && subject.isInGroup("libvirt")) { return polkit.Result.YES; } });
10.1.1.3 User name and Password Authentication with SASL #
SASL provides user name and password authentication and data encryption (digest-md5, by default). Since SASL maintains its own user database, the users do not need to exist on the VM Host Server. SASL is required by TCP connections and on top of TLS/SSL connections.
Using digest-md5 encryption on an otherwise not encrypted TCP connection does not provide enough security for production environments. It is recommended to only use it in testing environments.
Access from remote TLS/SSL connections can be indirectly controlled on the client side by restricting access to the certificate's key file. However, this might prove error-prone when dealing with many clients. Using SASL with TLS adds security by additionally controlling access on the server side.
To configure SASL authentication, proceed as follows:
Change the configuration in
/etc/libvirt/libvirtd.conf
as follows:To enable SASL for TCP connections:
auth_tcp = "sasl"
To enable SASL for TLS/SSL connections:
auth_tls = "sasl"
Restart
libvirtd
:>
sudo
systemctl restart libvirtdThe libvirt SASL configuration file is located at
/etc/sasl2/libvirtd.conf
. Normally, there is no need to change the defaults. However, if using SASL on top of TLS, you may turn off session encryption to avoid additional overhead (TLS connections are already encrypted) by commenting the line setting themech_list
parameter. Only do this for TLS/SASL, for TCP connections this parameter must be set to digest-md5.#mech_list: digest-md5
By default, no SASL users are configured, so no logins are possible. Use the following commands to manage users:
- Add the user
tux
saslpasswd2 -a libvirt tux
- Delete the user
tux
saslpasswd2 -a libvirt -d tux
- List existing users
sasldblistusers2 -f /etc/libvirt/passwd.db
- Add the user
virsh
and SASL Authentication
When using SASL authentication, you will be prompted for a user name
and password every time you issue a virsh
command.
Avoid this by using virsh
in shell mode.
10.1.2 VNC Authentication #
Since access to the graphical console of a VM Guest is not
controlled by libvirt
, but rather by the specific hypervisor, it is
always necessary to additionally configure VNC authentication. The main
configuration file is
/etc/libvirt/<hypervisor>.conf
. This
section describes the QEMU/KVM hypervisor, so the target
configuration file is /etc/libvirt/qemu.conf
.
In contrast to KVM and LXC, Xen does not yet offer more
sophisticated VNC authentication than setting a password on a per VM
basis. See the <graphics type='vnc'...
libvirt
configuration option below.
Two authentication types are available: SASL and single password
authentication. If you are using SASL for libvirt
authentication,
it is strongly recommended to use it for VNC authentication as
well—it is possible to share the same database.
A third method to restrict access to the VM Guest is to enable the use of TLS encryption on the VNC server. This requires the VNC clients to have access to x509 client certificates. By restricting access to these certificates, access can indirectly be controlled on the client side. Refer to Section 10.3.2.4.2, “VNC over TLS/SSL: Client Configuration” for details.
10.1.2.1 User name and Password Authentication with SASL #
SASL provides user name and password authentication and data
encryption. Since SASL maintains its own user database, the users do
not need to exist on the VM Host Server. As with SASL authentication for
libvirt
, you may use SASL on top of TLS/SSL connections. Refer to
Section 10.3.2.4.2, “VNC over TLS/SSL: Client Configuration” for details
on configuring these connections.
To configure SASL authentication for VNC, proceed as follows:
Create a SASL configuration file. It is recommended to use the existing
libvirt
file. If you have already configured SASL forlibvirt
and are planning to use the same settings including the same user name and password database, a simple link is suitable:>
sudo
ln -s /etc/sasl2/libvirt.conf /etc/sasl2/qemu.confIf are setting up SASL for VNC only or you are planning to use a different configuration than for
libvirt
, copy the existing file to use as a template:>
sudo
cp /etc/sasl2/libvirt.conf /etc/sasl2/qemu.confThen edit it according to your needs.
Change the configuration in
/etc/libvirt/qemu.conf
as follows:vnc_listen = "0.0.0.0" vnc_sasl = 1 sasldb_path: /etc/libvirt/qemu_passwd.db
The first parameter enables VNC to listen on all public interfaces (rather than to the local host only), and the second parameter enables SASL authentication.
By default, no SASL users are configured, so no logins are possible. Use the following commands to manage users:
- Add the user
tux
>
saslpasswd2 -f /etc/libvirt/qemu_passwd.db -a qemu tux- Delete the user
tux
>
saslpasswd2 -f /etc/libvirt/qemu_passwd.db -a qemu -d tux- List existing users
>
sasldblistusers2 -f /etc/libvirt/qemu_passwd.db
- Add the user
Restart
libvirtd
:>
sudo
systemctl restart libvirtdRestart all VM Guests that have been running prior to changing the configuration. VM Guests that have not been restarted will not use SASL authentication for VNC connects.
SASL authentication is currently supported by Virtual Machine Manager and
virt-viewer
.
Both of these viewers also support TLS/SSL connections.
10.1.2.2 Single Password Authentication #
Access to the VNC server may also be controlled by setting a VNC password. You can either set a global password for all VM Guests or set individual passwords for each guest. The latter requires to edit the VM Guest's configuration files.
If you are using single password authentication, it is good practice to set a global password even if setting passwords for each VM Guest. This will always leave your virtual machines protected with a “fallback” password if you forget to set a per-machine password. The global password will only be used if no other password is set for the machine.
Change the configuration in
/etc/libvirt/qemu.conf
as follows:vnc_listen = "0.0.0.0" vnc_password = "PASSWORD"
The first parameter enables VNC to listen on all public interfaces (rather than to the local host only), and the second parameter sets the password. The maximum length of the password is eight characters.
Restart
libvirtd
:>
sudo
systemctl restart libvirtdRestart all VM Guests that have been running prior to changing the configuration. VM Guests that have not been restarted will not use password authentication for VNC connects.
Change the configuration in
/etc/libvirt/qemu.conf
as follows to enable VNC to listen on all public interfaces (rather than to the local host only).vnc_listen = "0.0.0.0"
Open the VM Guest's XML configuration file in an editor. Replace VM_NAME in the following example with the name of the VM Guest. The editor that is used defaults to
$EDITOR
. If that variable is not set,vi
is used.>
virsh edit VM_NAMESearch for the element
<graphics>
with the attributetype='vnc'
, for example:<graphics type='vnc' port='-1' autoport='yes'/>
Add the
passwd=PASSWORD
attribute, save the file and exit the editor. The maximum length of the password is eight characters.<graphics type='vnc' port='-1' autoport='yes' passwd='PASSWORD'/>
Restart
libvirtd
:>
sudo
systemctl restart libvirtdRestart all VM Guests that have been running prior to changing the configuration. VM Guests that have not been restarted will not use password authentication for VNC connects.
The VNC protocol is not considered to be safe. Although the password is
sent encrypted, it might be vulnerable when an attacker can sniff both the
encrypted password and the encryption key. Therefore, it is recommended to
use VNC with TLS/SSL or tunneled over SSH.
virt-viewer
, Virtual Machine Manager and Remmina (refer to Section 10.2, “Remmina: Remote-Desktop-Client”) support both methods.
10.2 Connecting to a VM Host Server #
To connect to a hypervisor with libvirt
, you need to
specify a uniform resource identifier (URI). This URI is needed with
virsh
and virt-viewer
(except when
working as root
on the VM Host Server) and is optional for the
Virtual Machine Manager. Although the latter can be called with a connection parameter
(for example, virt-manager -c qemu:///system
), it also
offers a graphical interface to create connection URIs. See
Section 10.2.2, “Managing Connections with Virtual Machine Manager” for details.
HYPERVISOR1+PROTOCOL2://USER@REMOTE3/CONNECTION_TYPE4
Specify the hypervisor. SUSE Linux Enterprise Server currently supports the
following hypervisors: | |
When connecting to a remote host, specify the protocol here. It can be
one of: | |
When connecting to a remote host, specify the user name and the remote host
name. If no user name is specified, the user name that has called the
command ( | |
When connecting to the |
test:///default
Connect to the local dummy hypervisor. Useful for testing.
qemu:///system
orxen:///system
Connect to the QEMU/Xen hypervisor on the local host having full access (type system).
qemu+ssh://tux@mercury.example.com/system
orxen+ssh://tux@mercury.example.com/system
Connect to the QEMU/Xen hypervisor on the remote host mercury.example.com. The connection is established via an SSH tunnel.
qemu+tls://saturn.example.com/system
orxen+tls://saturn.example.com/system
Connect to the QEMU/Xen hypervisor on the remote host mercury.example.com. The connection is established using TLS/SSL.
For more details and examples, refer to the libvirt
documentation at
https://libvirt.org/uri.html.
A user name needs to be specified when using Unix socket authentication (regardless of whether using the user/password authentication scheme or Polkit). This applies to all SSH and local connections.
There is no need to specify a user name when using SASL authentication (for TCP or TLS connections) or when doing no additional server-side authentication for TLS connections. With SASL the user name will not be evaluated—you will be prompted for an SASL user/password combination in any case.
10.2.1 “system” Access for Non-Privileged Users #
As mentioned above, a connection to the QEMU hypervisor can be
established using two different protocols: session
and system
. A “session” connection is
spawned with the same privileges as the client program. Such a
connection is intended for desktop virtualization, since it is
restricted (for example no USB/PCI device assignments, no virtual
network setup, limited remote access to libvirtd
).
The “system” connection intended for server virtualization
has no functional restrictions but is, by default, only accessible by
root
. However, with the addition of the DAC (Discretionary
Access Control) driver to libvirt
it is now possible to grant
non-privileged users “system” access. To grant
“system” access to the user tux
, proceed as
follows:
Enable access via Unix sockets as described in Section 10.1.1.1, “Access Control for Unix Sockets with Permissions and Group Ownership”. In that example access to libvirt is granted to all members of the group
libvirt
andtux
made a member of this group. This ensures thattux
can connect usingvirsh
or Virtual Machine Manager.Edit
/etc/libvirt/qemu.conf
and change the configuration as follows:user = "tux" group = "libvirt" dynamic_ownership = 1
This ensures that the VM Guests are started by
tux
and that resources bound to the guest (for example virtual disks) can be accessed and modified bytux
.Make
tux
a member of the groupkvm
:>
sudo
usermod --append --groups kvm tuxThis step is needed to grant access to
/dev/kvm
, which is required to start VM Guests.Restart
libvirtd
:>
sudo
systemctl restart libvirtd
10.2.2 Managing Connections with Virtual Machine Manager #
The Virtual Machine Manager uses a Connection
for every VM Host Server
it manages. Each connection contains all VM Guests on the respective
host. By default, a connection to the local host is already configured
and connected.
All configured connections are displayed in the Virtual Machine Manager main window. Active connections are marked with a small triangle, which you can click to fold or unfold the list of VM Guests for this connection.
Inactive connections are listed gray and are marked with Not
Connected
. Either double-click or right-click it and choose
from the context menu. You can also
an existing connection from this menu.
It is not possible to edit an existing connection. To change a connection, create a new one with the desired parameters and delete the “old” one.
To add a new connection in the Virtual Machine Manager, proceed as follows:
Choose
›Choose the host's
( or )(Optional) To set up a remote connection, choose . For more information, see Section 10.3, “Configuring Remote Connections”.
In case of a remote connection, specify the
of the remote machine in the formatUSERNAME@REMOTE _HOST
.Important: Specifying a User NameThere is no need to specify a user name for TCP and TLS connections: In these cases, it will not be evaluated. However, in the case of SSH connections, specifying a user name is necessary when you want to connect as a user other than
root
.If you do not want the connection to be automatically started when starting the Virtual Machine Manager, deactivate
.Finish the configuration by clicking
.
10.3 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.
10.3.1 Remote Tunnel over SSH (qemu+ssh
or xen+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 (systemctl status
sshd
) 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
Section 10.1.1.1, “Access Control for Unix Sockets with Permissions and Group Ownership”.
Connecting as user tux
(qemu+ssh://tuxsIVname;/system
or
xen+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
or
xen+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 22.6, “Public key authentication”. Using
gnome-keyring
on the
machine from which you are connecting adds even more
convenience. For more information, see
Section 22.9, “Automated public key logins with gnome-keyring”.
10.3.2 Remote TLS/SSL Connection with x509 Certificate (qemu+tls
or xen+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 need to manage several VM Host Servers with a varying number of administrators.
10.3.2.1 Basic Concept #
TLS (Transport Layer Security) encrypts the communication between two computers by using certificates. The computer starting the connection is always considered the “client”, using a “client certificate”, while the receiving computer is always considered 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 can identify itself correctly. 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.
Using a remote TLS/SSL connection 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. For more information, see Section 10.3.2.5, “Restricting Access (Security Considerations)”.
libvirt
also supports user authentication on the server with
SASL. For more information, see
Section 10.3.2.6, “Central User Authentication with SASL for TLS Sockets”.
10.3.2.2 Configuring the VM Host Server #
The VM Host Server is the machine receiving connections. Therefore, the
server certificates need to be installed. The CA
certificate needs to be installed, too. When the certificates are
in place, TLS support can be turned on for libvirt
.
Create the server certificate and export it together with the respective CA certificate.
Create the following directories on the VM Host Server:
>
sudo
mkdir -p /etc/pki/CA/ /etc/pki/libvirt/private/Install the certificates as follows:
>
sudo
/etc/pki/CA/cacert.pem>
sudo
/etc/pki/libvirt/servercert.pem>
sudo
/etc/pki/libvirt/private/serverkey.pemImportant: Restrict Access to CertificatesMake sure to restrict access to certificates as explained in Section 10.3.2.5, “Restricting Access (Security Considerations)”.
Enable TLS support by enabling the relevant socket and restarting
libvirtd
:>
sudo
systemctl stop libvirtd.service>
sudo
systemctl enable --now libvirtd-tls.socket>
sudo
systemctl start libvirtd.serviceBy default,
libvirt
uses the TCP port 16514 for accepting secure TLS connections. Open this port in the firewall.
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.
10.3.2.3 Configuring the Client and Testing the Setup #
The client is the machine initiating connections. Therefore the client certificates need to be installed. The CA certificate needs to be installed, too.
Create the client certificate and export it together with the respective CA certificate.
Create the following directories on the client:
>
sudo
mkdir -p /etc/pki/CA/ /etc/pki/libvirt/private/Install the certificates as follows:
>
sudo
/etc/pki/CA/cacert.pem>
sudo
/etc/pki/libvirt/clientcert.pem>
sudo
/etc/pki/libvirt/private/clientkey.pemImportant: Restrict Access to CertificatesMake sure to restrict access to certificates as explained in Section 10.3.2.5, “Restricting Access (Security Considerations)”.
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 fully qualified host name as used when creating the server certificate.
#QEMU/KVM virsh -c qemu+tls://mercury.example.com/system list --all #Xen virsh -c xen+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.
10.3.2.4 Enabling VNC for TLS/SSL connections #
Currently, VNC communication over TLS is only supported by a few tools.
Common VNC viewers such as tightvnc
or
tigervnc
do not support TLS/SSL. The only supported
alternative to Virtual Machine Manager and virt-viewer
is
remmina
(refer to Section 10.2, “Remmina: Remote-Desktop-Client”).
10.3.2.4.1 VNC over TLS/SSL: VM Host Server Configuration #
To access the graphical console via VNC over TLS/SSL, you need to configure the VM Host Server as follows:
Open ports for the service
VNC
in your firewall.Create a directory
/etc/pki/libvirt-vnc
and link the certificates into this directory as follows:>
sudo
mkdir -p /etc/pki/libvirt-vnc && cd /etc/pki/libvirt-vnc>
sudo
ln -s /etc/pki/CA/cacert.pem ca-cert.pem>
sudo
ln -s /etc/pki/libvirt/servercert.pem server-cert.pem>
sudo
ln -s /etc/pki/libvirt/private/serverkey.pem server-key.pemEdit
/etc/libvirt/qemu.conf
and set the following parameters:vnc_listen = "0.0.0.0" vnc_tls = 1 vnc_tls_x509_verify = 1
Restart the
libvirtd
:>
sudo
systemctl restart libvirtdImportant: VM Guests Need to be RestartedThe 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.
10.3.2.4.2 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, Virtual Machine Manager and virt-viewer
expect the
certificates in a different location. Virtual Machine Manager can either read from a
system-wide location applying to all users, or from a per-user location.
Remmina (refer to Section 10.2, “Remmina: Remote-Desktop-Client”) asks for the location of
certificates when initializing the connection to the remote VNC session.
-
Virtual Machine Manager (
virt-manager
) To connect to the remote host, Virtual Machine Manager requires the setup explained in Section 10.3.2.3, “Configuring the Client and Testing the Setup”. 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
Make sure to restrict access to certificates as explained in Section 10.3.2.5, “Restricting Access (Security Considerations)”.
10.3.2.5 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 byroot
, so it is sufficient if theroot
can read the certificates:>
chmod 700 /etc/pki/libvirt/private/>
chmod 600 /etc/pki/libvirt/private/serverkey.pemIf 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 to 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 group ownership of theclientkey.pem
file and its parent directory is set tolibvirt
. Afterward, the access permissions are restricted to owner and group. Finally the usertux
is added to the grouplibvirt
, and thus can 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 --append --groups 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 user's home directory in
~/.pki
. Contrary to SSH, for example, the VNC viewer using these certificates do not check the access permissions of the private key file. Therefore, it is solely the user's responsibility to make sure the key file is not readable by others.
10.3.2.5.1 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 Section 10.1.1.3, “User name 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:
>
sudo
systemctl restart libvirtd
10.3.2.6 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
Section 10.3.2.5, “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
Section 10.1.1.3, “User name and Password Authentication with SASL” for
configuration details.
10.3.2.7 Troubleshooting #
10.3.2.7.1 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 host name 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? |
10.3.2.7.2 VNC Connection fails #
Ensure that you can 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 sles
.
>
ps ax | grep qemu | grep "\-name sles" | 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