mirror of
				https://gitlab.com/libvirt/libvirt.git
				synced 2025-10-30 20:24:58 +03:00 
			
		
		
		
	Historically we have used a bare xen:/// URI for connecting to the legacy Xen driver. The new libxl Xen driver follows the new practice of allowing '/system' as a path, as well as bare '/' for compat with the old Xen driver. This documents xen:///system as the preferred format for Xen, leaving xen:/// as an undocumented feature just for back-compat. Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
		
			
				
	
	
		
			969 lines
		
	
	
		
			32 KiB
		
	
	
	
		
			XML
		
	
	
	
	
	
			
		
		
	
	
			969 lines
		
	
	
		
			32 KiB
		
	
	
	
		
			XML
		
	
	
	
	
	
| <?xml version="1.0" encoding="UTF-8"?>
 | |
| <!DOCTYPE html>
 | |
| <html xmlns="http://www.w3.org/1999/xhtml">
 | |
|   <body>
 | |
|     <h1 >Remote support</h1>
 | |
|     <p>
 | |
| Libvirt allows you to access hypervisors running on remote
 | |
| machines through authenticated and encrypted connections.
 | |
| </p>
 | |
|     <ul id="toc"></ul>
 | |
| 
 | |
|     <h2>
 | |
|       <a id="Remote_basic_usage">Basic usage</a>
 | |
|     </h2>
 | |
|     <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>compute1.libvirt.org</code> you would use
 | |
| <code>qemu://compute1.libvirt.org/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>
 | |
|     <h2>
 | |
|       <a id="Remote_transports">Transports</a>
 | |
|     </h2>
 | |
|     <p>
 | |
| Remote libvirt supports a range of transports:
 | |
| </p>
 | |
|     <dl>
 | |
|       <dt><code>tls</code></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><code>unix</code></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><code>ssh</code></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><code>ext</code></dt>
 | |
|       <dd> Any external program which can make a connection to the
 | |
|  remote machine by means outside the scope of libvirt. </dd>
 | |
|       <dt><code>tcp</code></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>
 | |
|       <dt><code>libssh2</code></dt>
 | |
|       <dd> Transport over the SSH protocol using
 | |
|       <a href="http://libssh2.org/" title="libssh2 homepage">libssh2</a> instead
 | |
| of the OpenSSH binary. This transport uses the libvirt authentication callback for
 | |
| all ssh authentication calls and therefore supports keyboard-interactive authentication
 | |
| even with graphical management applications. As with the classic ssh transport
 | |
| netcat is required on the remote side.</dd>
 | |
|       <dt><code>libssh</code></dt>
 | |
|       <dd> Transport over the SSH protocol using
 | |
|       <a href="http://libssh.org/" title="libssh homepage">libssh</a> instead
 | |
| of the OpenSSH binary. This transport uses the libvirt authentication callback for
 | |
| all ssh authentication calls and therefore supports keyboard-interactive authentication
 | |
| even with graphical management applications. As with the classic ssh transport
 | |
| netcat is required on the remote side.</dd>
 | |
|     </dl>
 | |
|     <p>
 | |
| The default transport, if no other is specified, is <code>tls</code>.
 | |
| </p>
 | |
|     <h2>
 | |
|       <a id="Remote_URI_reference">Remote URIs</a>
 | |
|     </h2>
 | |
|     <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/system</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/system</code><br/> — Connect to a
 | |
| remote Xen hypervisor on host <code>towada</code> using TLS.
 | |
| </li>
 | |
|       <li><code>xen://towada/system?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>
 | |
| <li><code>qemu+libssh2://user@host/system?known_hosts=/home/user/.ssh/known_hosts</code><br/> —
 | |
| Connect to a remote host using a ssh connection with the libssh2 driver
 | |
| and use a different known_hosts file.</li>
 | |
| <li><code>qemu+libssh://user@host/system?known_hosts=/home/user/.ssh/known_hosts</code><br/> —
 | |
| Connect to a remote host using a ssh connection with the libssh driver
 | |
| and use a different known_hosts file.</li>
 | |
|     </ul>
 | |
|     <h3>
 | |
|       <a id="Remote_URI_parameters">Extra parameters</a>
 | |
|     </h3>
 | |
|     <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>tls_priority</code>
 | |
|         </td>
 | |
|         <td> tls </td>
 | |
|         <td>
 | |
|   A vaid GNUTLS priority string
 | |
| </td>
 | |
|       </tr>
 | |
|       <tr>
 | |
|         <td colspan="2"/>
 | |
|         <td> Example: <code>tls_priority=NORMAL:-VERS-SSL3.0</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, libssh2, libssh </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, libssh2, libssh </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>keyfile</code>
 | |
|         </td>
 | |
|         <td> ssh, libssh2, libssh </td>
 | |
|         <td>
 | |
|   The name of the private key file to use to authentication to the remote
 | |
|   machine.  If this option is not used the default keys are used.
 | |
|         </td>
 | |
|       </tr>
 | |
|       <tr>
 | |
|         <td colspan="2"/>
 | |
|         <td> Example: <code>keyfile=/root/.ssh/example_key</code> </td>
 | |
|       </tr>
 | |
| 
 | |
|       <tr>
 | |
|         <td>
 | |
|           <code>no_verify</code>
 | |
|         </td>
 | |
|         <td> ssh, tls </td>
 | |
|         <td>
 | |
|   SSH: If set to a non-zero value, this disables client's strict host key
 | |
|   checking making it auto-accept new host keys.  Existing host keys will
 | |
|   still be validated.
 | |
|   <br/>
 | |
|   <br/>
 | |
|   TLS: 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>
 | |
|       <tr>
 | |
|         <td>
 | |
|           <code>known_hosts</code>
 | |
|         </td>
 | |
|         <td> libssh2, libssh </td>
 | |
|         <td>
 | |
|   Path to the known_hosts file to verify the host key against. LibSSH2 and
 | |
|   libssh support OpenSSH-style known_hosts files, although LibSSH2 does not
 | |
|   support all key types, so using files created by the OpenSSH binary may
 | |
|   result into truncating the known_hosts file. Thus, with LibSSH2 it's
 | |
|   recommended to use the default known_hosts file is located in libvirt's
 | |
|   client local configuration directory e.g.: ~/.config/libvirt/known_hosts.
 | |
|   Note: Use absolute paths.
 | |
| </td>
 | |
|       </tr>
 | |
|       <tr>
 | |
|         <td colspan="2"/>
 | |
|         <td> Example: <code>known_hosts=/root/.ssh/known_hosts</code> </td>
 | |
|       </tr>
 | |
|       <tr>
 | |
|         <td>
 | |
|           <code>sshauth</code>
 | |
|         </td>
 | |
|         <td> libssh2, libssh </td>
 | |
|         <td>
 | |
|   A comma separated list of authentication methods to use. Default (is
 | |
|   "agent,privkey,password,keyboard-interactive". The order of the methods
 | |
|   is preserved. Some methods may require additional parameters.
 | |
| </td>
 | |
|       </tr>
 | |
|       <tr>
 | |
|         <td colspan="2"/>
 | |
|         <td> Example: <code>sshauth=privkey,agent</code> </td>
 | |
|       </tr>
 | |
|     </table>
 | |
|     <h2>
 | |
|       <a id="Remote_certificates">Generating TLS certificates</a>
 | |
|     </h2>
 | |
|     <h3>
 | |
|       <a id="Remote_PKI">Public Key Infrastructure set up</a>
 | |
|     </h3>
 | |
|     <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 the client and server </td>
 | |
|         <td> CA's certificate (<a href="#Remote_TLS_CA">more info</a>)</td>
 | |
|         <td> n/a </td>
 | |
|       </tr>
 | |
|       <tr>
 | |
|         <td>
 | |
|           <code>$HOME/.pki/cacert.pem</code>
 | |
|         </td>
 | |
|         <td> Installed on the client </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. All hostname and IP address variants that might
 | |
|           be used to reach the server should be listed in Subject Alt Name
 | |
|           fields.</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>
 | |
|       <tr>
 | |
|         <td>
 | |
|           <code>$HOME/.pki/libvirt/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>$HOME/.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 first. If the required CA certificate cannot
 | |
|         be found, then the global default location
 | |
|         (/etc/pki/CA/cacert.pem) will be used.
 | |
|         Likewise, if either the client certificate
 | |
|         or the client key cannot be found, then the global default
 | |
|         locations (/etc/pki/libvirt/clientcert.pem,
 | |
|         /etc/pki/libvirt/private/clientkey.pem) will be used.
 | |
|       </li>
 | |
|       <li> For the root user, the global default locations will always be used.</li>
 | |
|     </ul>
 | |
|     <h3>
 | |
|       <a id="Remote_TLS_background">Background to TLS certificates</a>
 | |
|     </h3>
 | |
|     <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>
 | |
|     <h3>
 | |
|       <a id="Remote_TLS_CA">Setting up a Certificate Authority (CA)</a>
 | |
|     </h3>
 | |
|     <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=Libvirt Project
 | |
| Issuer: CN=Libvirt Project
 | |
| 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>
 | |
|     <h3>
 | |
|       <a id="Remote_TLS_server_certificates">Issuing server certificates</a>
 | |
|     </h3>
 | |
|     <p>
 | |
| For each server (libvirtd) you need to issue a certificate
 | |
| containing one or more hostnames and/or IP addresses.
 | |
| Historically the CommonName (CN) field would contain the
 | |
| hostname of the server and would match the hostname used
 | |
| in the URI that clients pass to libvirt. In most TLS implementations
 | |
| the CN field is considered legacy data. The preferential mechanism
 | |
| is to use Subject Alt Name (SAN) extension fields to validate
 | |
| against. In the future use of the CN field for validation may be
 | |
| discontinued entirely, so it is strongly recommended to
 | |
| include the SAN fields.
 | |
| </p>
 | |
|     <p>
 | |
| In the example below, clients will be connecting to the
 | |
| server using a <a href="#Remote_URI_reference">URI</a> of
 | |
| <code>qemu://compute1.libvirt.org/system</code>, so the CN
 | |
| must be "<code>compute1.libvirt.org</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>.
 | |
| The template file will contain a number of fields to define
 | |
| the server as follows:
 | |
| </p>
 | |
|     <pre>
 | |
| organization = <i>Name of your organization</i>
 | |
| cn = compute1.libvirt.org
 | |
| dns_name = compute1
 | |
| dns_name = compute1.libvirt.org
 | |
| ip_address = 10.0.0.74
 | |
| ip_address = 192.168.1.24
 | |
| ip_address = 2001:cafe::74
 | |
| ip_address = fe20::24
 | |
| tls_www_server
 | |
| encryption_key
 | |
| signing_key
 | |
| </pre>
 | |
| <p>
 | |
| The 'cn' field should refer to the fully qualified public
 | |
| hostname of the server. For the SAN extension data, there
 | |
| must also be one or more 'dns_name' fields that contain all
 | |
| possible hostnames that can be reasonably used by clients
 | |
| to reach the server, both with and without domain name
 | |
| qualifiers. If clients are likely to connect to the server
 | |
| by IP address, then one or more 'ip_address' fields should
 | |
| also be added.
 | |
| </p>
 | |
|     <p>
 | |
| Use the template file as input to a <code>certtool</code>
 | |
| command to sign the server certificate:
 | |
| </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=Libvirt Project,CN=compute1.libvirt.org
 | |
| Issuer: CN=Libvirt Project
 | |
| Signature Algorithm: RSA-SHA
 | |
| Validity:
 | |
|         Not Before: Wed Oct 04 09:09:44 UTC 2017
 | |
|         Not After: Thu Oct 04 09:09:44 UTC 2018
 | |
| Extensions:
 | |
|         Basic Constraints (critical):
 | |
|                 Certificate Authority (CA): FALSE
 | |
|         Subject Alternative Name (not critical):
 | |
|                 DNSname: compute1
 | |
|                 DNSname: compute1.libvirt.org
 | |
|                 IPAddress: 10.0.0.74
 | |
|                 IPAddress: 192.168.1.24
 | |
|                 IPAddress: 2001:cafe::74
 | |
|                 IPAddress: fe20::24
 | |
| </pre>
 | |
|     <p>
 | |
| Note the "Issuer" CN is "Libvirt Project" (the CA) and
 | |
| the "Subject" CN is "compute1.libvirt.org" (the server).
 | |
| Notice that the hostname listed in the CN must also
 | |
| be duplicated as a DNSname entry
 | |
| </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>
 | |
|     <h3>
 | |
|       <a id="Remote_TLS_client_certificates">Issuing client certificates</a>
 | |
|     </h3>
 | |
|     <p>
 | |
| For each client (ie. any program linked with libvirt, such as
 | |
| <a href="http://virt-manager.org/">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:
 | |
| </p>
 | |
|     <pre>
 | |
| C=GB,ST=London,L=London,O=Libvirt Project,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 = Libvirt Project
 | |
| 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>
 | |
|     <h3>
 | |
|       <a id="Remote_TLS_troubleshooting">Troubleshooting TLS certificate problems</a>
 | |
|     </h3>
 | |
|     <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>
 | |
|     <h2>
 | |
|       <a id="Remote_libvirtd_configuration">libvirtd configuration file</a>
 | |
|     </h2>
 | |
|     <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> 0 (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=Libvirt Project,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>
 | |
|     <h2>
 | |
|       <a id="Remote_IPv6">IPv6 support</a>
 | |
|     </h2>
 | |
|     <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>
 | |
|     <h2>
 | |
|       <a id="Remote_limitations">Limitations</a>
 | |
|     </h2>
 | |
|     <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>
 | |
|   </body>
 | |
| </html>
 |