From: Pavel Hrdina <phrdina(a)redhat.com>
Note that links from the first table leading to sections of this
document further below were removed for simplicity.
Signed-off-by: Pavel Hrdina <phrdina(a)redhat.com>
Signed-off-by: Peter Krempa <pkrempa(a)redhat.com>
---
docs/meson.build | 2 +-
docs/tlscerts.html.in | 413 ------------------------------------------
docs/tlscerts.rst | 331 +++++++++++++++++++++++++++++++++
3 files changed, 332 insertions(+), 414 deletions(-)
delete mode 100644 docs/tlscerts.html.in
create mode 100644 docs/tlscerts.rst
diff --git a/docs/meson.build b/docs/meson.build
index 9022e761ca..8b174fe41e 100644
--- a/docs/meson.build
+++ b/docs/meson.build
@@ -31,7 +31,6 @@ docs_html_in_files = [
'internals',
'remote',
'storage',
- 'tlscerts',
'uri',
'windows',
]
@@ -110,6 +109,7 @@ docs_rst_files = [
'testapi',
'testsuites',
'testtck',
+ 'tlscerts',
]
# list of web targets to build for docs/web rule
diff --git a/docs/tlscerts.html.in b/docs/tlscerts.html.in
deleted file mode 100644
index 5b7a5f56e4..0000000000
--- a/docs/tlscerts.html.in
+++ /dev/null
@@ -1,413 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE html>
-<html
xmlns="http://www.w3.org/1999/xhtml">
- <body>
- <h1>TLS x509 certificate setup</h1>
-
- <ul id="toc"></ul>
-
- <h2>
- <a id="Remote_PKI">Public Key Infrastructure set up</a>
- </h2>
- <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>
- <h2>
- <a id="Remote_TLS_background">Background to TLS
certificates</a>
- </h2>
- <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="uri.html#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.html#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="https://en.wikipedia.org/wiki/Certificate_authority">C...
-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.html#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>
- <h2>
- <a id="Remote_TLS_CA">Setting up a Certificate Authority
(CA)</a>
- </h2>
- <p>
-You will need the <a
href="https://www.gnutls.org/manual/html_node/certtool-Invocation.ht...
-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>
- <h2>
- <a id="Remote_TLS_server_certificates">Issuing server
certificates</a>
- </h2>
- <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="uri.html#URI_remote">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>
- <h2>
- <a id="Remote_TLS_client_certificates">Issuing client
certificates</a>
- </h2>
- <p>
-For each client (ie. any program linked with libvirt, such as
-<a
href="https://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>
- <h2>
- <a id="Remote_TLS_troubleshooting">Troubleshooting TLS certificate
problems</a>
- </h2>
- <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>
- </body>
-</html>
diff --git a/docs/tlscerts.rst b/docs/tlscerts.rst
new file mode 100644
index 0000000000..c86362974c
--- /dev/null
+++ b/docs/tlscerts.rst
@@ -0,0 +1,331 @@
+==========================
+TLS x509 certificate setup
+==========================
+
+.. contents::
+
+Public Key Infrastructure set up
+--------------------------------
+
+If you are unsure how to create TLS certificates, skip to the next section.
+
+.. list-table::
+ :header-rows: 1
+
+ * - Location
+ - Machine
+ - Description
+ - Required fields
+
+ * - ``/etc/pki/CA/cacert.pem``
+ - Installed on the client and server
+ - CA's certificate
+ - n/a
+
+ * - ``$HOME/.pki/cacert.pem``
+ - Installed on the client
+ - CA's certificate
+ - n/a
+
+ * - ``/etc/pki/libvirt/private/serverkey.pem``
+ - Installed on the server
+ - Server's private key
+ - n/a
+
+ * - ``/etc/pki/libvirt/servercert.pem``
+ - Installed on the server
+ - Server's certificate signed by the CA
+ - 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.
+
+ * - ``/etc/pki/libvirt/private/clientkey.pem``
+ - Installed on the client
+ - Client's private key
+ - n/a
+
+ * - ``/etc/pki/libvirt/clientcert.pem``
+ - Installed on the client
+ - Client's certificate signed by the CA
+ - Distinguished Name (DN) can be checked against an access control list
+ (``tls_allowed_dn_list``).
+
+ * - ``$HOME/.pki/libvirt/clientkey.pem``
+ - Installed on the client
+ - Client's private key
+ - n/a
+
+ * - ``$HOME/.pki/libvirt/clientcert.pem``
+ - Installed on the client
+ - Client's certificate signed by the CA
+ (`more info <#Remote_TLS_client_certificates>`__)
+ - Distinguished Name (DN) can be checked against an access control list
+ (``tls_allowed_dn_list``).
+
+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:
+
+- 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.
+
+- For the root user, the global default locations will always be used.
+
+Background to TLS certificates
+------------------------------
+
+Libvirt supports TLS certificates for verifying the identity of the server and
+clients. There are two distinct checks involved:
+
+- 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 ``?no_verify=1`` to the `remote
+ URI <uri.html#Remote_URI_parameters>`__.
+
+- 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
+ `libvirtd.conf file <remote.html#Remote_libvirtd_configuration>`__.
+
+For full certificate checking you will need to have certificates issued by a
+recognised `Certificate Authority
+(CA) <
https://en.wikipedia.org/wiki/Certificate_authority>`__ 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.
+
+Be aware that the `default configuration for
+libvirtd <remote.html#Remote_libvirtd_configuration>`__ 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.
+
+Setting up a Certificate Authority (CA)
+---------------------------------------
+
+You will need the `GnuTLS certtool program documented
+here <
https://www.gnutls.org/manual/html_node/certtool-Invocation.html>`__. In
+Fedora, it is in the ``gnutls-utils`` package.
+
+Create a private key for your CA:
+
+::
+
+ certtool --generate-privkey > cakey.pem
+
+and self-sign it by creating a file with the signature details called
+``ca.info`` containing:
+
+::
+
+ cn = Name of your organization
+ ca
+ cert_signing_key
+
+::
+
+ certtool --generate-self-signed --load-privkey cakey.pem \
+ --template ca.info --outfile cacert.pem
+
+(You can delete ``ca.info`` file now if you want).
+
+Now you have two files which matter:
+
+- ``cakey.pem`` - Your CA's private key (keep this very secret!)
+
+- ``cacert.pem`` - Your CA's certificate (this is public).
+
+``cacert.pem`` has to be installed on clients and server(s) to let them know
+that they can trust certificates issued by your CA.
+
+The normal installation directory for ``cacert.pem`` is
+``/etc/pki/CA/cacert.pem`` on all clients and servers.
+
+To see the contents of this file, do:
+
+::
+
+ certtool -i --infile cacert.pem
+
+ 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
+ [etc]
+
+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.
+
+Issuing server certificates
+---------------------------
+
+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.
+
+In the example below, clients will be connecting to the server using a
+`URI <uri.html#URI_remote>`__ of ``qemu://compute1.libvirt.org/system``, so the
+CN must be "``compute1.libvirt.org``".
+
+Make a private key for the server:
+
+::
+
+ certtool --generate-privkey > serverkey.pem
+
+and sign that key with the CA's private key by first creating a template file
+called ``server.info``. The template file will contain a number of fields to
+define the server as follows:
+
+::
+
+ organization = Name of your organization
+ 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
+
+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.
+
+Use the template file as input to a ``certtool`` command to sign the server
+certificate:
+
+::
+
+ certtool --generate-certificate --load-privkey serverkey.pem \
+ --load-ca-certificate cacert.pem --load-ca-privkey cakey.pem \
+ --template server.info --outfile servercert.pem
+
+This gives two files:
+
+- ``serverkey.pem`` - The server's private key.
+
+- ``servercert.pem`` - The server's public key.
+
+We can examine this certificate and its signature:
+
+::
+
+ certtool -i --infile servercert.pem
+ 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
+
+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
+
+Finally we have two files to install:
+
+- ``serverkey.pem`` is the server's private key which should be copied to the
+ server *only* as ``/etc/pki/libvirt/private/serverkey.pem``.
+
+- ``servercert.pem`` is the server's certificate which can be installed on the
+ server as ``/etc/pki/libvirt/servercert.pem``.
+
+Issuing client certificates
+---------------------------
+
+For each client (ie. any program linked with libvirt, such as
+`virt-manager <
https://virt-manager.org/>`__) 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:
+
+::
+
+ C=GB,ST=London,L=London,O=Libvirt Project,CN=name_of_client
+
+The process is the same as for `setting up the server
+certificate <#Remote_TLS_server_certificates>`__ so here we just briefly cover
+the steps.
+
+#. Make a private key:
+
+ ::
+
+ certtool --generate-privkey > clientkey.pem
+
+#. Act as CA and sign the certificate. Create client.info containing:
+
+ ::
+
+ country = GB
+ state = London
+ locality = London
+ organization = Libvirt Project
+ cn = client1
+ tls_www_client
+ encryption_key
+ signing_key
+
+ and sign by doing:
+
+ ::
+
+ certtool --generate-certificate --load-privkey clientkey.pem \
+ --load-ca-certificate cacert.pem --load-ca-privkey cakey.pem \
+ --template client.info --outfile clientcert.pem
+
+#. Install the certificates on the client machine:
+
+ ::
+
+ cp clientkey.pem /etc/pki/libvirt/private/clientkey.pem
+ cp clientcert.pem /etc/pki/libvirt/clientcert.pem
+
+Troubleshooting TLS certificate problems
+----------------------------------------
+
+failed to verify client's certificate
+ 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.
+
+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.
--
2.35.1