mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-11-02 11:21:12 +00:00
cc4447b68a
* docs/remote.html.in
903 lines
30 KiB
XML
903 lines
30 KiB
XML
<?xml version="1.0"?>
|
|
<html>
|
|
<body>
|
|
<h1 >Remote support</h1>
|
|
<p>
|
|
Libvirt allows you to access hypervisors running on remote
|
|
machines through authenticated and encrypted connections.
|
|
</p>
|
|
<ul>
|
|
<li>
|
|
<a href="#Remote_basic_usage">Basic usage</a>
|
|
</li>
|
|
<li>
|
|
<a href="#Remote_transports">Transports</a>
|
|
</li>
|
|
<li>
|
|
<a href="#Remote_URI_reference">Remote URIs</a>
|
|
<ul>
|
|
<li>
|
|
<a href="#Remote_URI_parameters">Extra parameters</a>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li>
|
|
<a href="#Remote_certificates">Generating TLS certificates</a>
|
|
<ul>
|
|
<li>
|
|
<a href="#Remote_PKI">Public Key Infrastructure set up</a>
|
|
</li>
|
|
<li>
|
|
<a href="#Remote_TLS_background">Background to TLS certificates</a>
|
|
</li>
|
|
<li>
|
|
<a href="#Remote_TLS_CA">Setting up a Certificate Authority (CA)</a>
|
|
</li>
|
|
<li>
|
|
<a href="#Remote_TLS_server_certificates">Issuing server certificates</a>
|
|
</li>
|
|
<li>
|
|
<a href="#Remote_TLS_client_certificates">Issuing client certificates</a>
|
|
</li>
|
|
<li>
|
|
<a href="#Remote_TLS_troubleshooting">Troubleshooting TLS certificate problems</a>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li>
|
|
<a href="#Remote_libvirtd_configuration">libvirtd configuration file</a>
|
|
</li>
|
|
<li>
|
|
<a href="#Remote_IPv6">IPv6 support</a>
|
|
</li>
|
|
<li>
|
|
<a href="#Remote_limitations">Limitations</a>
|
|
</li>
|
|
<li>
|
|
<a href="#Remote_implementation_notes">Implementation notes</a>
|
|
</li>
|
|
</ul>
|
|
<h3>
|
|
<a name="Remote_basic_usage">Basic usage</a>
|
|
</h3>
|
|
<p>
|
|
On the remote machine, <code>libvirtd</code> should be running in general.
|
|
See <a href="#Remote_libvirtd_configuration">the section
|
|
on configuring libvirtd</a> for more information.
|
|
</p>
|
|
<p>
|
|
Not all hypervisors supported by libvirt require a running
|
|
<code>libvirtd</code>. If you want to connect to a VMware ESX/ESXi or
|
|
GSX server then <code>libvirtd</code> is not necessary. See the
|
|
<a href="drvesx.html">VMware ESX page</a> for details.
|
|
</p>
|
|
<p>
|
|
To tell libvirt that you want to access a remote resource,
|
|
you should supply a hostname in the normal <a href="uri.html">URI</a> that is passed
|
|
to <code>virConnectOpen</code> (or <code>virsh -c ...</code>).
|
|
For example, if you normally use <code>qemu:///system</code>
|
|
to access the system-wide QEMU daemon, then to access
|
|
the system-wide QEMU daemon on a remote machine called
|
|
<code>oirase</code> you would use <code>qemu://oirase/system</code>.
|
|
</p>
|
|
<p>
|
|
The <a href="#Remote_URI_reference">section on remote URIs</a>
|
|
describes in more detail these remote URIs.
|
|
</p>
|
|
<p>
|
|
From an API point of view, apart from the change in URI, the
|
|
API should behave the same. For example, ordinary calls
|
|
are routed over the remote connection transparently, and
|
|
values or errors from the remote side are returned to you
|
|
as if they happened locally. Some differences you may notice:
|
|
</p>
|
|
<ul>
|
|
<li> Additional errors can be generated, specifically ones
|
|
relating to failures in the remote transport itself. </li>
|
|
<li> Remote calls are handled synchronously, so they will be
|
|
much slower than, say, direct hypervisor calls. </li>
|
|
</ul>
|
|
<h3>
|
|
<a name="Remote_transports">Transports</a>
|
|
</h3>
|
|
<p>
|
|
Remote libvirt supports a range of transports:
|
|
</p>
|
|
<dl>
|
|
<dt> tls </dt>
|
|
<dd><a href="http://en.wikipedia.org/wiki/Transport_Layer_Security" title="Transport Layer Security">TLS</a>
|
|
1.0 (SSL 3.1) authenticated and encrypted TCP/IP socket, usually
|
|
listening on a public port number. To use this you will need to
|
|
<a href="#Remote_certificates" title="Generating TLS certificates">generate client and
|
|
server certificates</a>.
|
|
The standard port is 16514.
|
|
</dd>
|
|
<dt> unix </dt>
|
|
<dd> Unix domain socket. Since this is only accessible on the
|
|
local machine, it is not encrypted, and uses Unix permissions or
|
|
SELinux for authentication.
|
|
The standard socket names are
|
|
<code>/var/run/libvirt/libvirt-sock</code> and
|
|
<code>/var/run/libvirt/libvirt-sock-ro</code> (the latter
|
|
for read-only connections).
|
|
</dd>
|
|
<dt> ssh </dt>
|
|
<dd> Transported over an ordinary
|
|
<a href="http://www.openssh.com/" title="OpenSSH homepage">ssh
|
|
(secure shell)</a> connection.
|
|
Requires <a href="http://netcat.sourceforge.net/">Netcat (nc)</a>
|
|
installed and libvirtd should be running
|
|
on the remote machine. You should use some sort of
|
|
ssh key management (eg.
|
|
<a href="http://mah.everybody.org/docs/ssh" title="Using ssh-agent with ssh">ssh-agent</a>)
|
|
otherwise programs which use
|
|
this transport will stop to ask for a password. </dd>
|
|
<dt> ext </dt>
|
|
<dd> Any external program which can make a connection to the
|
|
remote machine by means outside the scope of libvirt. </dd>
|
|
<dt> tcp </dt>
|
|
<dd> Unencrypted TCP/IP socket. Not recommended for production
|
|
use, this is normally disabled, but an administrator can enable
|
|
it for testing or use over a trusted network.
|
|
The standard port is 16509.
|
|
</dd>
|
|
</dl>
|
|
<p>
|
|
The default transport, if no other is specified, is <code>tls</code>.
|
|
</p>
|
|
<h3>
|
|
<a name="Remote_URI_reference">Remote URIs</a>
|
|
</h3>
|
|
<p>
|
|
See also: <a href="uri.html">documentation on ordinary ("local") URIs</a>.
|
|
</p>
|
|
<p>
|
|
Remote URIs have the general form ("[...]" meaning an optional part):
|
|
</p>
|
|
<p><code>driver</code>[<code>+transport</code>]<code>://</code>[<code>username@</code>][<code>hostname</code>][<code>:port</code>]<code>/</code>[<code>path</code>][<code>?extraparameters</code>]
|
|
</p>
|
|
<p>
|
|
Either the transport or the hostname must be given in order
|
|
to distinguish this from a local URI.
|
|
</p>
|
|
<p>
|
|
Some examples:
|
|
</p>
|
|
<ul>
|
|
<li><code>xen+ssh://rjones@towada/</code><br/> — Connect to a
|
|
remote Xen hypervisor on host <code>towada</code> using ssh transport and ssh
|
|
username <code>rjones</code>.
|
|
</li>
|
|
<li><code>xen://towada/</code><br/> — Connect to a
|
|
remote Xen hypervisor on host <code>towada</code> using TLS.
|
|
</li>
|
|
<li><code>xen://towada/?no_verify=1</code><br/> — Connect to a
|
|
remote Xen hypervisor on host <code>towada</code> using TLS. Do not verify
|
|
the server's certificate.
|
|
</li>
|
|
<li><code>qemu+unix:///system?socket=/opt/libvirt/run/libvirt/libvirt-sock</code><br/> —
|
|
Connect to the local qemu instances over a non-standard
|
|
Unix socket (the full path to the Unix socket is
|
|
supplied explicitly in this case).
|
|
</li>
|
|
<li><code>test+tcp://localhost:5000/default</code><br/> —
|
|
Connect to a libvirtd daemon offering unencrypted TCP/IP connections
|
|
on localhost port 5000 and use the test driver with default
|
|
settings.
|
|
</li>
|
|
</ul>
|
|
<h4>
|
|
<a name="Remote_URI_parameters">Extra parameters</a>
|
|
</h4>
|
|
<p>
|
|
Extra parameters can be added to remote URIs as part
|
|
of the query string (the part following <q><code>?</code></q>).
|
|
Remote URIs understand the extra parameters shown below.
|
|
Any others are passed unmodified through to the back end.
|
|
Note that parameter values must be
|
|
<a href="http://xmlsoft.org/html/libxml-uri.html#xmlURIEscapeStr">URI-escaped</a>.
|
|
</p>
|
|
<table class="top_table">
|
|
<tr>
|
|
<th> Name </th>
|
|
<th> Transports </th>
|
|
<th> Meaning </th>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
<code>name</code>
|
|
</td>
|
|
<td>
|
|
<i>any transport</i>
|
|
</td>
|
|
<td>
|
|
The name passed to the remote virConnectOpen function. The
|
|
name is normally formed by removing transport, hostname, port
|
|
number, username and extra parameters from the remote URI, but in certain
|
|
very complex cases it may be better to supply the name explicitly.
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td colspan="2"/>
|
|
<td> Example: <code>name=qemu:///system</code> </td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
<code>command</code>
|
|
</td>
|
|
<td> ssh, ext </td>
|
|
<td>
|
|
The external command. For ext transport this is required.
|
|
For ssh the default is <code>ssh</code>.
|
|
The PATH is searched for the command.
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td colspan="2"/>
|
|
<td> Example: <code>command=/opt/openssh/bin/ssh</code> </td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
<code>socket</code>
|
|
</td>
|
|
<td> unix, ssh </td>
|
|
<td>
|
|
The path to the Unix domain socket, which overrides the
|
|
compiled-in default. For ssh transport, this is passed to
|
|
the remote netcat command (see next).
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td colspan="2"/>
|
|
<td> Example: <code>socket=/opt/libvirt/run/libvirt/libvirt-sock</code> </td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
<code>netcat</code>
|
|
</td>
|
|
<td> ssh </td>
|
|
<td>
|
|
The name of the netcat command on the remote machine.
|
|
The default is <code>nc</code>. For ssh transport, libvirt
|
|
constructs an ssh command which looks like:
|
|
|
|
<pre><i>command</i> -p <i>port</i> [-l <i>username</i>] <i>hostname</i> <i>netcat</i> -U <i>socket</i>
|
|
</pre>
|
|
|
|
where <i>port</i>, <i>username</i>, <i>hostname</i> can be
|
|
specified as part of the remote URI, and <i>command</i>, <i>netcat</i>
|
|
and <i>socket</i> come from extra parameters (or
|
|
sensible defaults).
|
|
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td colspan="2"/>
|
|
<td> Example: <code>netcat=/opt/netcat/bin/nc</code> </td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
<code>no_verify</code>
|
|
</td>
|
|
<td> tls </td>
|
|
<td>
|
|
If set to a non-zero value, this disables client checks of the
|
|
server's certificate. Note that to disable server checks of
|
|
the client's certificate or IP address you must
|
|
<a href="#Remote_libvirtd_configuration">change the libvirtd
|
|
configuration</a>.
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td colspan="2"/>
|
|
<td> Example: <code>no_verify=1</code> </td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
<code>no_tty</code>
|
|
</td>
|
|
<td> ssh </td>
|
|
<td>
|
|
If set to a non-zero value, this stops ssh from asking for
|
|
a password if it cannot log in to the remote machine automatically
|
|
(eg. using ssh-agent etc.). Use this when you don't have access
|
|
to a terminal - for example in graphical programs which use libvirt.
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td colspan="2"/>
|
|
<td> Example: <code>no_tty=1</code> </td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
<code>pkipath</code>
|
|
</td>
|
|
<td> tls</td>
|
|
<td>
|
|
Specifies x509 certificates path for the client. If any of
|
|
the CA certificate, client certificate, or client key is
|
|
missing, the connection will fail with a fatal error.
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td colspan="2"/>
|
|
<td> Example: <code>pkipath=/tmp/pki/client</code> </td>
|
|
</tr>
|
|
</table>
|
|
<h3>
|
|
<a name="Remote_certificates">Generating TLS certificates</a>
|
|
</h3>
|
|
<h4>
|
|
<a name="Remote_PKI">Public Key Infrastructure set up</a>
|
|
</h4>
|
|
<p>
|
|
If you are unsure how to create TLS certificates, skip to the
|
|
next section.
|
|
</p>
|
|
<table class="top_table">
|
|
<tr>
|
|
<th> Location </th>
|
|
<th> Machine </th>
|
|
<th> Description </th>
|
|
<th> Required fields </th>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
<code>/etc/pki/CA/cacert.pem</code>
|
|
</td>
|
|
<td> Installed on all clients and servers </td>
|
|
<td> CA's certificate (<a href="#Remote_TLS_CA">more info</a>)</td>
|
|
<td> n/a </td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
<code>/etc/pki/libvirt/ private/serverkey.pem</code>
|
|
</td>
|
|
<td> Installed on the server </td>
|
|
<td> Server's private key (<a href="#Remote_TLS_server_certificates">more info</a>)</td>
|
|
<td> n/a </td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
<code>/etc/pki/libvirt/ servercert.pem</code>
|
|
</td>
|
|
<td> Installed on the server </td>
|
|
<td> Server's certificate signed by the CA.
|
|
(<a href="#Remote_TLS_server_certificates">more info</a>) </td>
|
|
<td> CommonName (CN) must be the hostname of the server as it
|
|
is seen by clients. </td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
<code>/etc/pki/libvirt/ private/clientkey.pem</code>
|
|
</td>
|
|
<td> Installed on the client </td>
|
|
<td> Client's private key. (<a href="#Remote_TLS_client_certificates">more info</a>) </td>
|
|
<td> n/a </td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
<code>/etc/pki/libvirt/ clientcert.pem</code>
|
|
</td>
|
|
<td> Installed on the client </td>
|
|
<td> Client's certificate signed by the CA
|
|
(<a href="#Remote_TLS_client_certificates">more info</a>) </td>
|
|
<td> Distinguished Name (DN) can be checked against an access
|
|
control list (<code>tls_allowed_dn_list</code>).
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
<p>
|
|
If 'pkipath' is specified in URI, then all the client
|
|
certificates must be found in the path specified, otherwise the
|
|
connection will fail with a fatal error. If 'pkipath' is not
|
|
specified:
|
|
</p>
|
|
<ul>
|
|
<li> For a non-root user, libvirt tries to find the certificates
|
|
in $HOME/.pki/libvirt. If any of the required certificates can
|
|
not be found, then the global default locations
|
|
(/etc/pki/CA/cacert.pem, /etc/pki/libvirt/private/clientkey,
|
|
/etc/pki/libvirt/clientcert.pem) will be used.
|
|
</li>
|
|
<li> For the root user, the global default locations will be used.</li>
|
|
</ul>
|
|
<h4>
|
|
<a name="Remote_TLS_background">Background to TLS certificates</a>
|
|
</h4>
|
|
<p>
|
|
Libvirt supports TLS certificates for verifying the identity
|
|
of the server and clients. There are two distinct checks involved:
|
|
</p>
|
|
<ul>
|
|
<li> The client should know that it is connecting to the right
|
|
server. Checking done by client by matching the certificate that
|
|
the server sends to the server's hostname. May be disabled by adding
|
|
<code>?no_verify=1</code> to the
|
|
<a href="#Remote_URI_parameters">remote URI</a>.
|
|
</li>
|
|
<li> The server should know that only permitted clients are
|
|
connecting. This can be done based on client's IP address, or on
|
|
client's IP address and client's certificate. Checking done by the
|
|
server. May be enabled and disabled in the <a href="#Remote_libvirtd_configuration">libvirtd.conf file</a>.
|
|
</li>
|
|
</ul>
|
|
<p>
|
|
For full certificate checking you will need to have certificates
|
|
issued by a recognised <a href="http://en.wikipedia.org/wiki/Certificate_authority">Certificate
|
|
Authority (CA)</a> for your server(s) and all clients. To avoid the
|
|
expense of getting certificates from a commercial CA, you can set up
|
|
your own CA and tell your server(s) and clients to trust certificates
|
|
issues by your own CA. Follow the instructions in the next section.
|
|
</p>
|
|
<p>
|
|
Be aware that the <a href="#Remote_libvirtd_configuration">default
|
|
configuration for libvirtd</a> allows any client to connect provided
|
|
they have a valid certificate issued by the CA for their own IP
|
|
address. You may want to change this to make it less (or more)
|
|
permissive, depending on your needs.
|
|
</p>
|
|
<h4>
|
|
<a name="Remote_TLS_CA">Setting up a Certificate Authority (CA)</a>
|
|
</h4>
|
|
<p>
|
|
You will need the <a href="http://www.gnu.org/software/gnutls/manual/html_node/Invoking-certtool.html">GnuTLS
|
|
certtool program documented here</a>. In Fedora, it is in the
|
|
<code>gnutls-utils</code> package.
|
|
</p>
|
|
<p>
|
|
Create a private key for your CA:
|
|
</p>
|
|
<pre>
|
|
certtool --generate-privkey > cakey.pem
|
|
</pre>
|
|
<p>
|
|
and self-sign it by creating a file with the
|
|
signature details called
|
|
<code>ca.info</code> containing:
|
|
</p>
|
|
<pre>
|
|
cn = <i>Name of your organization</i>
|
|
ca
|
|
cert_signing_key
|
|
</pre>
|
|
<pre>
|
|
certtool --generate-self-signed --load-privkey cakey.pem \
|
|
--template ca.info --outfile cacert.pem
|
|
</pre>
|
|
<p>
|
|
(You can delete <code>ca.info</code> file now if you
|
|
want).
|
|
</p>
|
|
<p>
|
|
Now you have two files which matter:
|
|
</p>
|
|
<ul>
|
|
<li><code>cakey.pem</code> - Your CA's private key (keep this very secret!)
|
|
</li>
|
|
<li><code>cacert.pem</code> - Your CA's certificate (this is public).
|
|
</li>
|
|
</ul>
|
|
<p><code>cacert.pem</code> has to be installed on clients and
|
|
server(s) to let them know that they can trust certificates issued by
|
|
your CA.
|
|
</p>
|
|
<p>
|
|
The normal installation directory for <code>cacert.pem</code>
|
|
is <code>/etc/pki/CA/cacert.pem</code> on all clients and servers.
|
|
</p>
|
|
<p>
|
|
To see the contents of this file, do:
|
|
</p>
|
|
<pre><b>certtool -i --infile cacert.pem</b>
|
|
|
|
X.509 certificate info:
|
|
|
|
Version: 3
|
|
Serial Number (hex): 00
|
|
Subject: CN=Red Hat Emerging Technologies
|
|
Issuer: CN=Red Hat Emerging Technologies
|
|
Signature Algorithm: RSA-SHA
|
|
Validity:
|
|
Not Before: Mon Jun 18 16:22:18 2007
|
|
Not After: Tue Jun 17 16:22:18 2008
|
|
<i>[etc]</i>
|
|
</pre>
|
|
<p>
|
|
This is all that is required to set up your CA. Keep the CA's private
|
|
key carefully as you will need it when you come to issue certificates
|
|
for your clients and servers.
|
|
</p>
|
|
<h4>
|
|
<a name="Remote_TLS_server_certificates">Issuing server certificates</a>
|
|
</h4>
|
|
<p>
|
|
For each server (libvirtd) you need to issue a certificate
|
|
with the X.509 CommonName (CN) field set to the hostname
|
|
of the server. The CN must match the hostname which
|
|
clients will be using to connect to the server.
|
|
</p>
|
|
<p>
|
|
In the example below, clients will be connecting to the
|
|
server using a <a href="#Remote_URI_reference">URI</a> of
|
|
<code>xen://oirase/</code>, so the CN must be "<code>oirase</code>".
|
|
</p>
|
|
<p>
|
|
Make a private key for the server:
|
|
</p>
|
|
<pre>
|
|
certtool --generate-privkey > serverkey.pem
|
|
</pre>
|
|
<p>
|
|
and sign that key with the CA's private key by first
|
|
creating a template file called <code>server.info</code>
|
|
(only the CN field matters, which as explained above must
|
|
be the server's hostname):
|
|
</p>
|
|
<pre>
|
|
organization = <i>Name of your organization</i>
|
|
cn = oirase
|
|
tls_www_server
|
|
encryption_key
|
|
signing_key
|
|
</pre>
|
|
<p>
|
|
and sign:
|
|
</p>
|
|
<pre>
|
|
certtool --generate-certificate --load-privkey serverkey.pem \
|
|
--load-ca-certificate cacert.pem --load-ca-privkey cakey.pem \
|
|
--template server.info --outfile servercert.pem
|
|
</pre>
|
|
<p>
|
|
This gives two files:
|
|
</p>
|
|
<ul>
|
|
<li><code>serverkey.pem</code> - The server's private key.
|
|
</li>
|
|
<li><code>servercert.pem</code> - The server's public key.
|
|
</li>
|
|
</ul>
|
|
<p>
|
|
We can examine this certificate and its signature:
|
|
</p>
|
|
<pre><b>certtool -i --infile servercert.pem</b>
|
|
X.509 certificate info:
|
|
|
|
Version: 3
|
|
Serial Number (hex): 00
|
|
Subject: O=Red Hat Emerging Technologies,CN=oirase
|
|
Issuer: CN=Red Hat Emerging Technologies
|
|
Signature Algorithm: RSA-SHA
|
|
Validity:
|
|
Not Before: Mon Jun 18 16:34:49 2007
|
|
Not After: Tue Jun 17 16:34:49 2008
|
|
</pre>
|
|
<p>
|
|
Note the "Issuer" CN is "Red Hat Emerging Technologies" (the CA) and
|
|
the "Subject" CN is "oirase" (the server).
|
|
</p>
|
|
<p>
|
|
Finally we have two files to install:
|
|
</p>
|
|
<ul>
|
|
<li><code>serverkey.pem</code> is
|
|
the server's private key which should be copied to the
|
|
server <i>only</i> as
|
|
<code>/etc/pki/libvirt/private/serverkey.pem</code>.
|
|
</li>
|
|
<li><code>servercert.pem</code> is the server's certificate
|
|
which can be installed on the server as
|
|
<code>/etc/pki/libvirt/servercert.pem</code>.
|
|
</li>
|
|
</ul>
|
|
<h4>
|
|
<a name="Remote_TLS_client_certificates">Issuing client certificates</a>
|
|
</h4>
|
|
<p>
|
|
For each client (ie. any program linked with libvirt, such as
|
|
<a href="http://virt-manager.et.redhat.com/">virt-manager</a>)
|
|
you need to issue a certificate with the X.509 Distinguished Name (DN)
|
|
set to a suitable name. You can decide this on a company / organisation
|
|
policy. For example, I use:
|
|
</p>
|
|
<pre>
|
|
C=GB,ST=London,L=London,O=Red Hat,CN=<i>name_of_client</i>
|
|
</pre>
|
|
<p>
|
|
The process is the same as for
|
|
<a href="#Remote_TLS_server_certificates">setting up the
|
|
server certificate</a> so here we just briefly cover the
|
|
steps.
|
|
</p>
|
|
<ol>
|
|
<li>
|
|
Make a private key:
|
|
<pre>
|
|
certtool --generate-privkey > clientkey.pem
|
|
</pre>
|
|
</li>
|
|
<li>
|
|
Act as CA and sign the certificate. Create client.info containing:
|
|
<pre>
|
|
country = GB
|
|
state = London
|
|
locality = London
|
|
organization = Red Hat
|
|
cn = client1
|
|
tls_www_client
|
|
encryption_key
|
|
signing_key
|
|
</pre>
|
|
and sign by doing:
|
|
<pre>
|
|
certtool --generate-certificate --load-privkey clientkey.pem \
|
|
--load-ca-certificate cacert.pem --load-ca-privkey cakey.pem \
|
|
--template client.info --outfile clientcert.pem
|
|
</pre>
|
|
</li>
|
|
<li>
|
|
Install the certificates on the client machine:
|
|
<pre>
|
|
cp clientkey.pem /etc/pki/libvirt/private/clientkey.pem
|
|
cp clientcert.pem /etc/pki/libvirt/clientcert.pem
|
|
</pre>
|
|
</li>
|
|
</ol>
|
|
<h4>
|
|
<a name="Remote_TLS_troubleshooting">Troubleshooting TLS certificate problems</a>
|
|
</h4>
|
|
<dl>
|
|
<dt> failed to verify client's certificate </dt>
|
|
<dd>
|
|
<p>
|
|
On the server side, run the libvirtd server with
|
|
the '--listen' and '--verbose' options while the
|
|
client is connecting. The verbose log messages should
|
|
tell you enough to diagnose the problem.
|
|
</p>
|
|
</dd>
|
|
</dl>
|
|
<p> You can use the virt-pki-validate shell script
|
|
to analyze the setup on the client or server machines, preferably as root.
|
|
It will try to point out the possible problems and provide solutions to
|
|
fix the set up up to a point where you have secure remote access.</p>
|
|
<h3>
|
|
<a name="Remote_libvirtd_configuration">libvirtd configuration file</a>
|
|
</h3>
|
|
<p>
|
|
Libvirtd (the remote daemon) is configured from a file called
|
|
<code>/etc/libvirt/libvirtd.conf</code>, or specified on
|
|
the command line using <code>-f filename</code> or
|
|
<code>--config filename</code>.
|
|
</p>
|
|
<p>
|
|
This file should contain lines of the form below.
|
|
Blank lines and comments beginning with <code>#</code> are ignored.
|
|
</p>
|
|
<pre>setting = value</pre>
|
|
<p>The following settings, values and default are:</p>
|
|
<table class="top_table">
|
|
<tr>
|
|
<th> Line </th>
|
|
<th> Default </th>
|
|
<th> Meaning </th>
|
|
</tr>
|
|
<tr>
|
|
<td> listen_tls <i>[0|1]</i> </td>
|
|
<td> 1 (on) </td>
|
|
<td>
|
|
Listen for secure TLS connections on the public TCP/IP port.
|
|
Note: it is also necessary to start the server in listening mode by
|
|
running it with --listen or editing /etc/sysconfig/libvirtd by uncommenting the LIBVIRTD_ARGS="--listen" line
|
|
to cause the server to come up in listening mode whenever it is started.
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td> listen_tcp <i>[0|1]</i> </td>
|
|
<td> 0 (off) </td>
|
|
<td>
|
|
Listen for unencrypted TCP connections on the public TCP/IP port.
|
|
Note: it is also necessary to start the server in listening mode.
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td> tls_port <i>"service"</i> </td>
|
|
<td> "16514" </td>
|
|
<td>
|
|
The port number or service name to listen on for secure TLS connections.
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td> tcp_port <i>"service"</i> </td>
|
|
<td> "16509" </td>
|
|
<td>
|
|
The port number or service name to listen on for unencrypted TCP connections.
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td> mdns_adv <i>[0|1]</i> </td>
|
|
<td> 1 (advertise with mDNS) </td>
|
|
<td>
|
|
If set to 1 then the virtualization service will be advertised over
|
|
mDNS to hosts on the local LAN segment.
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td> mdns_name <i>"name"</i> </td>
|
|
<td> "Virtualization Host HOSTNAME" </td>
|
|
<td>
|
|
The name to advertise for this host with Avahi mDNS. The default
|
|
includes the machine's short hostname. This must be unique to the
|
|
local LAN segment.
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td> unix_sock_group <i>"groupname"</i> </td>
|
|
<td> "root" </td>
|
|
<td>
|
|
The UNIX group to own the UNIX domain socket. If the socket permissions allow
|
|
group access, then applications running under matching group can access the
|
|
socket. Only valid if running as root
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td> unix_sock_ro_perms <i>"octal-perms"</i> </td>
|
|
<td> "0777" </td>
|
|
<td>
|
|
The permissions for the UNIX domain socket for read-only client connections.
|
|
The default allows any user to monitor domains.
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td> unix_sock_rw_perms <i>"octal-perms"</i> </td>
|
|
<td> "0700" </td>
|
|
<td>
|
|
The permissions for the UNIX domain socket for read-write client connections.
|
|
The default allows only root to manage domains.
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td> tls_no_verify_certificate <i>[0|1]</i> </td>
|
|
<td> 0 (certificates are verified) </td>
|
|
<td>
|
|
If set to 1 then if a client certificate check fails, it is not an error.
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td> tls_no_verify_address <i>[0|1]</i> </td>
|
|
<td> 0 (addresses are verified) </td>
|
|
<td>
|
|
If set to 1 then if a client IP address check fails, it is not an error.
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td> key_file <i>"filename"</i> </td>
|
|
<td> "/etc/pki/libvirt/ private/serverkey.pem" </td>
|
|
<td>
|
|
Change the path used to find the server's private key.
|
|
If you set this to an empty string, then no private key is loaded.
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td> cert_file <i>"filename"</i> </td>
|
|
<td> "/etc/pki/libvirt/ servercert.pem" </td>
|
|
<td>
|
|
Change the path used to find the server's certificate.
|
|
If you set this to an empty string, then no certificate is loaded.
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td> ca_file <i>"filename"</i> </td>
|
|
<td> "/etc/pki/CA/cacert.pem" </td>
|
|
<td>
|
|
Change the path used to find the trusted CA certificate.
|
|
If you set this to an empty string, then no trusted CA certificate is loaded.
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td> crl_file <i>"filename"</i> </td>
|
|
<td> (no CRL file is used) </td>
|
|
<td>
|
|
Change the path used to find the CA certificate revocation list (CRL) file.
|
|
If you set this to an empty string, then no CRL is loaded.
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td> tls_allowed_dn_list ["DN1", "DN2"] </td>
|
|
<td> (none - DNs are not checked) </td>
|
|
<td>
|
|
<p>
|
|
Enable an access control list of client certificate Distinguished
|
|
Names (DNs) which can connect to the TLS port on this server.
|
|
</p>
|
|
<p>
|
|
The default is that DNs are not checked.
|
|
</p>
|
|
<p>
|
|
This list may contain wildcards such as <code>"C=GB,ST=London,L=London,O=Red Hat,CN=*"</code>
|
|
See the POSIX <code>fnmatch</code> function for the format
|
|
of the wildcards.
|
|
</p>
|
|
<p>
|
|
Note that if this is an empty list, <i>no client can connect</i>.
|
|
</p>
|
|
<p>
|
|
Note also that GnuTLS returns DNs without spaces
|
|
after commas between the fields (and this is what we check against),
|
|
but the <code>openssl x509</code> tool shows spaces.
|
|
</p>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
<h3>
|
|
<a name="Remote_IPv6">IPv6 support</a>
|
|
</h3>
|
|
<p>
|
|
The libvirtd service and libvirt remote client driver both use the
|
|
<code>getaddrinfo()</code> functions for name resolution and are
|
|
thus fully IPv6 enabled. ie, if a server has IPv6 address configured
|
|
the daemon will listen for incoming connections on both IPv4 and IPv6
|
|
protocols. If a client has an IPv6 address configured and the DNS
|
|
address resolved for a service is reachable over IPv6, then an IPv6
|
|
connection will be made, otherwise IPv4 will be used. In summary it
|
|
should just 'do the right thing(tm)'.
|
|
</p>
|
|
<h3>
|
|
<a name="Remote_limitations">Limitations</a>
|
|
</h3>
|
|
<ul>
|
|
<li> Fine-grained authentication: libvirt in general,
|
|
but in particular the remote case should support more
|
|
fine-grained authentication for operations, rather than
|
|
just read-write/read-only as at present.
|
|
</li>
|
|
</ul>
|
|
<p>
|
|
Please come and discuss these issues and more on <a href="https://www.redhat.com/mailman/listinfo/libvir-list" title="libvir-list mailing list">the mailing list</a>.
|
|
</p>
|
|
<h3>
|
|
<a name="Remote_implementation_notes">Implementation notes</a>
|
|
</h3>
|
|
<p>
|
|
The current implementation uses <a href="http://en.wikipedia.org/wiki/External_Data_Representation" title="External Data Representation">XDR</a>-encoded packets with a
|
|
simple remote procedure call implementation which also supports
|
|
asynchronous messaging and asynchronous and out-of-order replies,
|
|
although these latter features are not used at the moment.
|
|
</p>
|
|
<p>
|
|
The implementation should be considered <b>strictly internal</b> to
|
|
libvirt and <b>subject to change at any time without notice</b>. If
|
|
you wish to talk to libvirtd, link to libvirt. If there is a problem
|
|
that means you think you need to use the protocol directly, please
|
|
first discuss this on <a href="https://www.redhat.com/mailman/listinfo/libvir-list" title="libvir-list mailing list">the mailing list</a>.
|
|
</p>
|
|
<p>
|
|
The messaging protocol is described in
|
|
<code>qemud/remote_protocol.x</code>.
|
|
</p>
|
|
<p>
|
|
Authentication and encryption (for TLS) is done using <a href="http://www.gnu.org/software/gnutls/" title="GnuTLS project page">GnuTLS</a> and the RPC protocol is unaware of this layer.
|
|
</p>
|
|
<p>
|
|
Protocol messages are sent using a simple 32 bit length word (encoded
|
|
XDR int) followed by the message header (XDR
|
|
<code>remote_message_header</code>) followed by the message body. The
|
|
length count includes the length word itself, and is measured in
|
|
bytes. Maximum message size is <code>REMOTE_MESSAGE_MAX</code> and to
|
|
avoid denial of services attacks on the XDR decoders strings are
|
|
individually limited to <code>REMOTE_STRING_MAX</code> bytes. In the
|
|
TLS case, messages may be split over TLS records, but a TLS record
|
|
cannot contain parts of more than one message. In the common RPC case
|
|
a single <code>REMOTE_CALL</code> message is sent from client to
|
|
server, and the server then replies synchronously with a single
|
|
<code>REMOTE_REPLY</code> message, but other forms of messaging are
|
|
also possible.
|
|
</p>
|
|
<p>
|
|
The protocol contains support for multiple program types and protocol
|
|
versioning, modelled after SunRPC.
|
|
</p>
|
|
</body>
|
|
</html>
|