]> xenbits.xensource.com Git - libvirt.git/commitdiff
Thu May 10 17:00:00 BST 2007 Richard W.M. Jones <rjones@redhat.com>
authorRichard W.M. Jones <rjones@redhat.com>
Thu, 10 May 2007 15:55:39 +0000 (15:55 +0000)
committerRichard W.M. Jones <rjones@redhat.com>
Thu, 10 May 2007 15:55:39 +0000 (15:55 +0000)
* docs/libvir.html, docs/libvirt.css, docs/remote.html:
  Added documentation for TLS certificates and libvirtd.conf.
  CSS changes makes the tables look nicer.  remote.html is
  a generated file.

ChangeLog
docs/libvir.html
docs/libvirt.css
docs/remote.html

index c5636613f4dd0301655d9c37ed9c8a6fcaf9a7fd..b5c2c1c32c199a3c86092c53143724e9dfed0631 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+Thu May 10 17:00:00 BST 2007 Richard W.M. Jones  <rjones@redhat.com>
+
+       * docs/libvir.html, docs/libvirt.css, docs/remote.html:
+         Added documentation for TLS certificates and libvirtd.conf.
+         CSS changes makes the tables look nicer.  remote.html is
+         a generated file.
+
 Tue May  8 11:49:00 BST 2007  Richard W.M. Jones  <rjones@redhat.com>
 
        * src/hash.c, src/internal.h, src/libvirt_sym.version: Export
index 348aa65b843fe136818100b970d19d16aaee10c6..91fb9264dc16c9774ee75a297ea838f82e1725d4 100644 (file)
@@ -1456,7 +1456,7 @@ 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>
@@ -1508,7 +1508,7 @@ Note that parameter values must be
 <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>
@@ -1597,24 +1597,586 @@ Note that parameter values must be
 
 <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>
index 757f2ed87482f5101f8c986a0f376ce3b19df108..3272683f972ae4b31155d95749a99ff9e583f43e 100644 (file)
@@ -169,3 +169,12 @@ pre.programlisting
     border-style:              double;
     background:                #F0F0F0;
     }
+
+table.top_table {
+  border-collapse: collapse;
+}
+
+table.top_table th, table.top_table td {
+  vertical-align: top;
+  border: 1px solid #f0f0f0;
+}
\ No newline at end of file
index 1f169171e4c09948722ce727e63debfa518aba27..9da96dd1f8c62d30b61dbe9a910ff7e46e1bca23 100644 (file)
@@ -81,7 +81,7 @@ The default transport, if no other is specified, is <code>tls</code>.
 </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.
@@ -120,7 +120,7 @@ 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><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>
@@ -181,11 +181,418 @@ Note that parameter values must be
 </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