</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>]
+<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>
<a href="http://xmlsoft.org/html/libxml-uri.html#xmlURIEscapeStr">URI-escaped</a>.
</p>
-<table>
+<table class="top_table">
<tr>
<th> Name </th>
<th> Transports </th>
<h3><a name="Remote_certificates">Generating TLS certificates</a></h3>
+<h4>Public Key Infrastructure set up</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> CommonName (CN) must be the client IP address as seen
+ by the server. Take particular care with IPv4 and IPv6
+ addresses, and note that on some operating systems IPv4 addresses
+ may need to be encapsulated as <code>::ffff:<i>a.b.c.d</i></code>
+ </td>
+</tr>
+</table>
+
+
+<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.openssl.org/docs/apps/CA.pl.html">OpenSSL CA.pl Perl
+script documented here</a>. In Fedora, it is in the
+<code>openssl-perl</code> package. In Debian and derivatives, it is
+in the base <code>openssl</code> package.
+</p>
+
+<p>Notes:</p>
+
+<ul>
+<li>
+You may find it
+better to start with the basic <code>CA.pl</code> script from OpenSSL
+itself, as Linux distributors seem to supply a hacked/broken one.
+</li>
+<li>
+A second confounding factor may be the default
+<code>openssl.cnf</code> file supplied with your
+Linux distribution. You can switch to a custom
+file by doing:
+<pre>
+export SSLEAY_CONFIG="-config your_config_file"
+</pre>
+</li>
+</ul>
+
+<p>
+These instructions assume that <code>CA.pl</code> is in an empty
+directory (because you will probably need to edit this script).
+Please read the <a
+href="http://www.openssl.org/docs/apps/CA.pl.html">CA.pl manpage</a>
+carefully before starting.
+</p>
+
+<p>
+Copy CA.pl into an empty directory and edit it. Near the top you will
+find various variables:
+</p>
+
+<p>
+<code>$DAYS</code> defaults to <code>"-days 365"</code>. You may wish
+to increase this, otherwise your CA and certificates will expire after
+a year, suddenly leaving your systems unmanageable.
+</p>
+
+<p>
+<code>$CATOP</code> may be set to <code>"./demoCA"</code> or some
+other directory. If you want you can change the name to a suitable
+directory name for your organisation.
+</p>
+
+<p>
+Now run:
+</p>
+
+<pre>
+<b>./CA.pl -newca</b>
+CA certificate filename (or enter to create)
+<b>[press enter key]</b>
+Making CA certificate ...
+Generating a 1024 bit RSA private key
+...++++++
+.......................++++++
+writing new private key to './demoCA/private/cakey.pem'
+Enter PEM pass phrase: <b>[type a passphrase]</b>
+Verifying - Enter PEM pass phrase: <b>[type a passphrase]</b>
+</pre>
+
+<p>
+It will ask some further questions about your organisation and then
+create a CA directory structure (usually called <code>demoCA</code>
+unless you changed it above). Some highlights of this directory:
+</p>
+
+<pre>
+demoCA/newcerts Certificates issued by the CA
+demoCA/crl Certificates revoked by the CA
+demoCA/cacert.pem The CA's own certificate (this is public)
+demoCA/private/cakey.pem The CA's private key (keep this secret)
+</pre>
+
+<p>
+The important file is <code>cacert.pem</code> which is your new CA's
+X.509 certificate. This file 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>openssl x509 -in demoCA/cacert.pem -text</b>
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ dd:b4:0f:d0:58:0e:08:fa
+ Signature Algorithm: sha1WithRSAEncryption
+ Issuer: C=GB, ST=London, L=London, O=Red Hat UK Ltd, OU=Emerging Technologies, CN=Red Hat/emailAddress=rjones@redhat.com
+ Validity
+ Not Before: May 10 10:26:47 2007 GMT
+ Not After : May 7 10:26:47 2017 GMT
+ Subject: C=GB, ST=London, L=London, O=Red Hat UK Ltd, OU=Emerging Technologies, CN=Red Hat/emailAddress=rjones@redhat.com
+
+<i>[etc]</i>
+</pre>
+
+<p>
+This is all that is required to set up your CA. Keep this directory
+structure and the passphrase safe as you will require them later when
+issuing certificates.
+</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>
+First move to the directory above the CA directory (from the example
+in the last section, <code>demoCA</code> would be a subdirectory).
+</p>
+
+<p>
+Make a private key and a request for a new certificate:
+</p>
+
+<pre>
+<b>./CA.pl -newreq</b>
+Generating a 1024 bit RSA private key
+...++++++
+....................++++++
+writing new private key to 'newreq.pem'
+Enter PEM pass phrase: <b>[enter a passphrase]</b>
+Verifying - Enter PEM pass phrase: <b>[enter a passphrase]</b>
+</pre>
+
+<p>
+You will be asked additional details about the certificate.
+The single important field is "Common Name" which as explained
+above <b>must</b> contain the server's hostname as clients
+see it.
+</p>
+
+<p>
+The operation creates a request file called <code>newreq.pem</code>
+which has both the private key and the unsigned certificate.
+In the situation of a "real" CA, you would send the certificate
+part off to be signed (along with lots of $$$). Instead we are
+going to act as CA and sign it ourselves:
+</p>
+
+<pre>
+<b>./CA.pl -signreq</b>
+Enter pass phrase for demoCA/private/cakey.pem: <b>[enter CA passphrase]</b>
+Check that the request matches the signature
+Signature ok
+Certificate Details:
+ Serial Number:
+ dd:b4:0f:d0:58:0e:08:fb
+ Validity
+ Not Before: May 10 11:10:40 2007 GMT
+ Not After : May 9 11:10:40 2008 GMT
+ Subject:
+ countryName = GB
+ stateOrProvinceName = London
+ localityName = London
+ organizationName = Red Hat UK Ltd
+ organizationalUnitName = Emerging Technologies
+ commonName = oirase
+ emailAddress = rjones@redhat.com
+ X509v3 extensions:
+ X509v3 Basic Constraints:
+ CA:FALSE
+ Netscape Comment:
+ OpenSSL Generated Certificate
+ X509v3 Subject Key Identifier:
+ DE:08:0D:12:73:76:06:97:EC:57:EF:8D:1B:48:ED:53:9A:1A:FE:7F
+ X509v3 Authority Key Identifier:
+ keyid:F6:84:4C:1B:2B:59:10:89:3F:0B:AB:05:7F:57:85:A6:33:C7:7A:60
+
+Certificate is to be certified until May 9 11:10:40 2008 GMT (365 days)
+Sign the certificate? [y/n]:<b>y</b>
+
+
+1 out of 1 certificate requests certified, commit? [y/n]<b>y</b>
+Write out database with 1 new entries
+Data Base Updated
+Signed certificate is in newcert.pem
+</pre>
+
<p>
-<i>This section to follow.</i>
+This step generates a server certificate signed by the CA
+for the server <code>oirase</code> (NB. the commonName field
+above). We can examine this certificate and its signature:
</p>
+<pre>
+<b>openssl x509 -in newcert.pem -text</b>
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ dd:b4:0f:d0:58:0e:08:fb
+ Signature Algorithm: sha1WithRSAEncryption
+ Issuer: C=GB, ST=London, L=London, O=Red Hat UK Ltd, OU=Emerging Technologies, CN=Red Hat/emailAddress=rjones@redhat.com
+ Validity
+ Not Before: May 10 11:10:40 2007 GMT
+ Not After : May 9 11:10:40 2008 GMT
+ Subject: C=GB, ST=London, L=London, O=Red Hat UK Ltd, OU=Emerging Technologies, CN=oirase/emailAddress=rjones@redhat.com
+</pre>
+<p>
+Note the "Issuer" CN is "Red Hat" (the CA) and the "Subject" CN is
+"oirase" (the server).
+</p>
+<p>
+At this point we have <code>newreq.pem</code> which contains the
+private key and unsigned certificate and <code>newcert.pem</code>
+which contains the signed certificate. For the server we need just
+the private key and signed certificate. For the clients we need just
+the signed certificate. So there is one final step which is to
+extract the private key from <code>newreq.pem</code>:
+</p>
+<pre>
+<b>openssl rsa -in newreq.pem -out serverkey.pem</b>
+Enter pass phrase for newreq.pem:
+writing RSA key
+
+<b>mv newcert.pem servercert.pem</b>
+</pre>
+
+<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 CommonName (CN)
+field set to the IP address of the client as seen from the
+server.
+</p>
+
+<p>
+Normally then the CN will just be a string such as
+"<code>192.168.2.5</code>". On machines with IPv6 enabled,
+IPv4 addresses may appear embedded, for example:
+"<code>::ffff:<i>a.b.c.d</i></code>".
+</p>
+
+<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 and a request for a new certificate:
+<pre>
+./CA.pl -newreq
+</pre>
+You <b>must</b> set the CommonName (CN) field to be the
+client's IP address as seen by the server. See notes above.
+</li>
+
+<li>
+Act as CA and sign the certificate:
+<pre>
+./CA.pl -signreq
+</pre>
+</li>
+
+<li>
+Extract the private key for the client and rename the
+signed certificate:
+<pre>
+openssl rsa -in newreq.pem -out clientkey.pem
+mv newcert.pem 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 '--remote' and '--verbose' options while the
+client is connecting. The verbose messages will tell
+you the client's actual IP address versus what is
+in the client's certificate. Also you will find out
+common problems such as expired certificates.
+</p>
+</dd>
+</dl>
<h3><a name="Remote_libvirtd_configuration">libvirtd configuration</a></h3>
<p>
-<i>This section to follow.</i>
+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>
+<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.
+</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.
+</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> 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_clients ["ip1", "ip2", "ip3"] </td>
+<td> (none - any client can connect) </td>
+<td>
+ <p>
+ Enable an access control list of the IP addresses of clients
+ who can connect to the TLS or TCP ports on this server.
+ </p>
+ <p>
+ The default is that any client can connect, but their
+ certificate must match their IP address and must be
+ issued by the trusted CA. If you use this option, then
+ in addition only the IP addresses listed may connect.
+ </p>
+ <p>
+ This list may contain wildcards such as <code>192.168.*</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>
+</td>
+</tr>
+</table>
<h3><a name="Remote_IPv6">IPv6 support</a></h3>
</p><h3><a name="Remote_URI_reference" id="Remote_URI_reference">Remote URIs</a></h3><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>]
+<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.
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><tr><th> Name </th>
+</p><table class="top_table"><tr><th> Name </th>
<th> Transports </th>
<th> Meaning </th>
</tr><tr><td> <code>name</code> </td>
</td>
</tr><tr><td colspan="2"></td>
<td> Example: <code>no_verify=1</code> </td>
-</tr></table><h3><a name="Remote_certificates" id="Remote_certificates">Generating TLS certificates</a></h3><p>
-<i>This section to follow.</i>
-</p><h3><a name="Remote_libvirtd_configuration" id="Remote_libvirtd_configuration">libvirtd configuration</a></h3><p>
-<i>This section to follow.</i>
-</p><h3><a name="Remote_IPv6" id="Remote_IPv6">IPv6 support</a></h3><p>
+</tr></table><h3><a name="Remote_certificates" id="Remote_certificates">Generating TLS certificates</a></h3><h4>Public Key Infrastructure set up</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> CommonName (CN) must be the client IP address as seen
+ by the server. Take particular care with IPv4 and IPv6
+ addresses, and note that on some operating systems IPv4 addresses
+ may need to be encapsulated as <code>::ffff:<i>a.b.c.d</i></code>
+ </td>
+</tr></table><h4><a name="Remote_TLS_background" id="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" id="Remote_TLS_CA">Setting up a Certificate Authority (CA)</a></h4><p>
+You will need the <a href="http://www.openssl.org/docs/apps/CA.pl.html">OpenSSL CA.pl Perl
+script documented here</a>. In Fedora, it is in the
+<code>openssl-perl</code> package. In Debian and derivatives, it is
+in the base <code>openssl</code> package.
+</p><p>Notes:</p><ul><li>
+You may find it
+better to start with the basic <code>CA.pl</code> script from OpenSSL
+itself, as Linux distributors seem to supply a hacked/broken one.
+</li>
+<li>
+A second confounding factor may be the default
+<code>openssl.cnf</code> file supplied with your
+Linux distribution. You can switch to a custom
+file by doing:
+<pre>
+export SSLEAY_CONFIG="-config your_config_file"
+</pre>
+</li>
+</ul><p>
+These instructions assume that <code>CA.pl</code> is in an empty
+directory (because you will probably need to edit this script).
+Please read the <a href="http://www.openssl.org/docs/apps/CA.pl.html">CA.pl manpage</a>
+carefully before starting.
+</p><p>
+Copy CA.pl into an empty directory and edit it. Near the top you will
+find various variables:
+</p><p>
+<code>$DAYS</code> defaults to <code>"-days 365"</code>. You may wish
+to increase this, otherwise your CA and certificates will expire after
+a year, suddenly leaving your systems unmanageable.
+</p><p>
+<code>$CATOP</code> may be set to <code>"./demoCA"</code> or some
+other directory. If you want you can change the name to a suitable
+directory name for your organisation.
+</p><p>
+Now run:
+</p><pre>
+<b>./CA.pl -newca</b>
+CA certificate filename (or enter to create)
+<b>[press enter key]</b>
+Making CA certificate ...
+Generating a 1024 bit RSA private key
+...++++++
+.......................++++++
+writing new private key to './demoCA/private/cakey.pem'
+Enter PEM pass phrase: <b>[type a passphrase]</b>
+Verifying - Enter PEM pass phrase: <b>[type a passphrase]</b>
+</pre><p>
+It will ask some further questions about your organisation and then
+create a CA directory structure (usually called <code>demoCA</code>
+unless you changed it above). Some highlights of this directory:
+</p><pre>
+demoCA/newcerts Certificates issued by the CA
+demoCA/crl Certificates revoked by the CA
+demoCA/cacert.pem The CA's own certificate (this is public)
+demoCA/private/cakey.pem The CA's private key (keep this secret)
+</pre><p>
+The important file is <code>cacert.pem</code> which is your new CA's
+X.509 certificate. This file 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>openssl x509 -in demoCA/cacert.pem -text</b>
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ dd:b4:0f:d0:58:0e:08:fa
+ Signature Algorithm: sha1WithRSAEncryption
+ Issuer: C=GB, ST=London, L=London, O=Red Hat UK Ltd, OU=Emerging Technologies, CN=Red Hat/emailAddress=rjones@redhat.com
+ Validity
+ Not Before: May 10 10:26:47 2007 GMT
+ Not After : May 7 10:26:47 2017 GMT
+ Subject: C=GB, ST=London, L=London, O=Red Hat UK Ltd, OU=Emerging Technologies, CN=Red Hat/emailAddress=rjones@redhat.com
+
+<i>[etc]</i>
+</pre><p>
+This is all that is required to set up your CA. Keep this directory
+structure and the passphrase safe as you will require them later when
+issuing certificates.
+</p><h4><a name="Remote_TLS_server_certificates" id="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>
+First move to the directory above the CA directory (from the example
+in the last section, <code>demoCA</code> would be a subdirectory).
+</p><p>
+Make a private key and a request for a new certificate:
+</p><pre>
+<b>./CA.pl -newreq</b>
+Generating a 1024 bit RSA private key
+...++++++
+....................++++++
+writing new private key to 'newreq.pem'
+Enter PEM pass phrase: <b>[enter a passphrase]</b>
+Verifying - Enter PEM pass phrase: <b>[enter a passphrase]</b>
+</pre><p>
+You will be asked additional details about the certificate.
+The single important field is "Common Name" which as explained
+above <b>must</b> contain the server's hostname as clients
+see it.
+</p><p>
+The operation creates a request file called <code>newreq.pem</code>
+which has both the private key and the unsigned certificate.
+In the situation of a "real" CA, you would send the certificate
+part off to be signed (along with lots of $$$). Instead we are
+going to act as CA and sign it ourselves:
+</p><pre>
+<b>./CA.pl -signreq</b>
+Enter pass phrase for demoCA/private/cakey.pem: <b>[enter CA passphrase]</b>
+Check that the request matches the signature
+Signature ok
+Certificate Details:
+ Serial Number:
+ dd:b4:0f:d0:58:0e:08:fb
+ Validity
+ Not Before: May 10 11:10:40 2007 GMT
+ Not After : May 9 11:10:40 2008 GMT
+ Subject:
+ countryName = GB
+ stateOrProvinceName = London
+ localityName = London
+ organizationName = Red Hat UK Ltd
+ organizationalUnitName = Emerging Technologies
+ commonName = oirase
+ emailAddress = rjones@redhat.com
+ X509v3 extensions:
+ X509v3 Basic Constraints:
+ CA:FALSE
+ Netscape Comment:
+ OpenSSL Generated Certificate
+ X509v3 Subject Key Identifier:
+ DE:08:0D:12:73:76:06:97:EC:57:EF:8D:1B:48:ED:53:9A:1A:FE:7F
+ X509v3 Authority Key Identifier:
+ keyid:F6:84:4C:1B:2B:59:10:89:3F:0B:AB:05:7F:57:85:A6:33:C7:7A:60
+
+Certificate is to be certified until May 9 11:10:40 2008 GMT (365 days)
+Sign the certificate? [y/n]:<b>y</b>
+
+
+1 out of 1 certificate requests certified, commit? [y/n]<b>y</b>
+Write out database with 1 new entries
+Data Base Updated
+Signed certificate is in newcert.pem
+</pre><p>
+This step generates a server certificate signed by the CA
+for the server <code>oirase</code> (NB. the commonName field
+above). We can examine this certificate and its signature:
+</p><pre>
+<b>openssl x509 -in newcert.pem -text</b>
+Certificate:
+ Data:
+ Version: 3 (0x2)
+ Serial Number:
+ dd:b4:0f:d0:58:0e:08:fb
+ Signature Algorithm: sha1WithRSAEncryption
+ Issuer: C=GB, ST=London, L=London, O=Red Hat UK Ltd, OU=Emerging Technologies, CN=Red Hat/emailAddress=rjones@redhat.com
+ Validity
+ Not Before: May 10 11:10:40 2007 GMT
+ Not After : May 9 11:10:40 2008 GMT
+ Subject: C=GB, ST=London, L=London, O=Red Hat UK Ltd, OU=Emerging Technologies, CN=oirase/emailAddress=rjones@redhat.com
+</pre><p>
+Note the "Issuer" CN is "Red Hat" (the CA) and the "Subject" CN is
+"oirase" (the server).
+</p><p>
+At this point we have <code>newreq.pem</code> which contains the
+private key and unsigned certificate and <code>newcert.pem</code>
+which contains the signed certificate. For the server we need just
+the private key and signed certificate. For the clients we need just
+the signed certificate. So there is one final step which is to
+extract the private key from <code>newreq.pem</code>:
+</p><pre>
+<b>openssl rsa -in newreq.pem -out serverkey.pem</b>
+Enter pass phrase for newreq.pem:
+writing RSA key
+
+<b>mv newcert.pem servercert.pem</b>
+</pre><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" id="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 CommonName (CN)
+field set to the IP address of the client as seen from the
+server.
+</p><p>
+Normally then the CN will just be a string such as
+"<code>192.168.2.5</code>". On machines with IPv6 enabled,
+IPv4 addresses may appear embedded, for example:
+"<code>::ffff:<i>a.b.c.d</i></code>".
+</p><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 and a request for a new certificate:
+<pre>
+./CA.pl -newreq
+</pre>
+You <b>must</b> set the CommonName (CN) field to be the
+client's IP address as seen by the server. See notes above.
+</li>
+
+<li>
+Act as CA and sign the certificate:
+<pre>
+./CA.pl -signreq
+</pre>
+</li>
+
+<li>
+Extract the private key for the client and rename the
+signed certificate:
+<pre>
+openssl rsa -in newreq.pem -out clientkey.pem
+mv newcert.pem 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" id="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 '--remote' and '--verbose' options while the
+client is connecting. The verbose messages will tell
+you the client's actual IP address versus what is
+in the client's certificate. Also you will find out
+common problems such as expired certificates.
+</p>
+</dd>
+</dl><h3><a name="Remote_libvirtd_configuration" id="Remote_libvirtd_configuration">libvirtd configuration</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><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.
+</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.
+</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> 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_clients ["ip1", "ip2", "ip3"] </td>
+<td> (none - any client can connect) </td>
+<td>
+ <p>
+ Enable an access control list of the IP addresses of clients
+ who can connect to the TLS or TCP ports on this server.
+ </p>
+ <p>
+ The default is that any client can connect, but their
+ certificate must match their IP address and must be
+ issued by the trusted CA. If you use this option, then
+ in addition only the IP addresses listed may connect.
+ </p>
+ <p>
+ This list may contain wildcards such as <code>192.168.*</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>
+</td>
+</tr></table><h3><a name="Remote_IPv6" id="Remote_IPv6">IPv6 support</a></h3><p>
IPv6 has received some limited testing and should work. Problems with
libvirt and IPv6 should be reported as <a href="bugs.html">bugs</a>.
</p><h3><a name="Remote_limitations" id="Remote_limitations">Limitations</a></h3><ul><li> Remote storage: To be fully useful, particularly for