qemu/docs/system/tls.rst
<<
>>
Prefs
   1.. _network_005ftls:
   2
   3TLS setup for network services
   4------------------------------
   5
   6Almost all network services in QEMU have the ability to use TLS for
   7session data encryption, along with x509 certificates for simple client
   8authentication. What follows is a description of how to generate
   9certificates suitable for usage with QEMU, and applies to the VNC
  10server, character devices with the TCP backend, NBD server and client,
  11and migration server and client.
  12
  13At a high level, QEMU requires certificates and private keys to be
  14provided in PEM format. Aside from the core fields, the certificates
  15should include various extension data sets, including v3 basic
  16constraints data, key purpose, key usage and subject alt name.
  17
  18The GnuTLS package includes a command called ``certtool`` which can be
  19used to easily generate certificates and keys in the required format
  20with expected data present. Alternatively a certificate management
  21service may be used.
  22
  23At a minimum it is necessary to setup a certificate authority, and issue
  24certificates to each server. If using x509 certificates for
  25authentication, then each client will also need to be issued a
  26certificate.
  27
  28Assuming that the QEMU network services will only ever be exposed to
  29clients on a private intranet, there is no need to use a commercial
  30certificate authority to create certificates. A self-signed CA is
  31sufficient, and in fact likely to be more secure since it removes the
  32ability of malicious 3rd parties to trick the CA into mis-issuing certs
  33for impersonating your services. The only likely exception where a
  34commercial CA might be desirable is if enabling the VNC websockets
  35server and exposing it directly to remote browser clients. In such a
  36case it might be useful to use a commercial CA to avoid needing to
  37install custom CA certs in the web browsers.
  38
  39The recommendation is for the server to keep its certificates in either
  40``/etc/pki/qemu`` or for unprivileged users in ``$HOME/.pki/qemu``.
  41
  42.. _tls_005fgenerate_005fca:
  43
  44Setup the Certificate Authority
  45~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  46
  47This step only needs to be performed once per organization /
  48organizational unit. First the CA needs a private key. This key must be
  49kept VERY secret and secure. If this key is compromised the entire trust
  50chain of the certificates issued with it is lost.
  51
  52::
  53
  54   # certtool --generate-privkey > ca-key.pem
  55
  56To generate a self-signed certificate requires one core piece of
  57information, the name of the organization. A template file ``ca.info``
  58should be populated with the desired data to avoid having to deal with
  59interactive prompts from certtool::
  60
  61   # cat > ca.info <<EOF
  62   cn = Name of your organization
  63   ca
  64   cert_signing_key
  65   EOF
  66   # certtool --generate-self-signed \
  67              --load-privkey ca-key.pem \
  68              --template ca.info \
  69              --outfile ca-cert.pem
  70
  71The ``ca`` keyword in the template sets the v3 basic constraints
  72extension to indicate this certificate is for a CA, while
  73``cert_signing_key`` sets the key usage extension to indicate this will
  74be used for signing other keys. The generated ``ca-cert.pem`` file
  75should be copied to all servers and clients wishing to utilize TLS
  76support in the VNC server. The ``ca-key.pem`` must not be
  77disclosed/copied anywhere except the host responsible for issuing
  78certificates.
  79
  80.. _tls_005fgenerate_005fserver:
  81
  82Issuing server certificates
  83~~~~~~~~~~~~~~~~~~~~~~~~~~~
  84
  85Each server (or host) needs to be issued with a key and certificate.
  86When connecting the certificate is sent to the client which validates it
  87against the CA certificate. The core pieces of information for a server
  88certificate are the hostnames and/or IP addresses that will be used by
  89clients when connecting. The hostname / IP address that the client
  90specifies when connecting will be validated against the hostname(s) and
  91IP address(es) recorded in the server certificate, and if no match is
  92found the client will close the connection.
  93
  94Thus it is recommended that the server certificate include both the
  95fully qualified and unqualified hostnames. If the server will have
  96permanently assigned IP address(es), and clients are likely to use them
  97when connecting, they may also be included in the certificate. Both IPv4
  98and IPv6 addresses are supported. Historically certificates only
  99included 1 hostname in the ``CN`` field, however, usage of this field
 100for validation is now deprecated. Instead modern TLS clients will
 101validate against the Subject Alt Name extension data, which allows for
 102multiple entries. In the future usage of the ``CN`` field may be
 103discontinued entirely, so providing SAN extension data is strongly
 104recommended.
 105
 106On the host holding the CA, create template files containing the
 107information for each server, and use it to issue server certificates.
 108
 109::
 110
 111   # cat > server-hostNNN.info <<EOF
 112   organization = Name  of your organization
 113   cn = hostNNN.foo.example.com
 114   dns_name = hostNNN
 115   dns_name = hostNNN.foo.example.com
 116   ip_address = 10.0.1.87
 117   ip_address = 192.8.0.92
 118   ip_address = 2620:0:cafe::87
 119   ip_address = 2001:24::92
 120   tls_www_server
 121   encryption_key
 122   signing_key
 123   EOF
 124   # certtool --generate-privkey > server-hostNNN-key.pem
 125   # certtool --generate-certificate \
 126              --load-ca-certificate ca-cert.pem \
 127              --load-ca-privkey ca-key.pem \
 128              --load-privkey server-hostNNN-key.pem \
 129              --template server-hostNNN.info \
 130              --outfile server-hostNNN-cert.pem
 131
 132The ``dns_name`` and ``ip_address`` fields in the template are setting
 133the subject alt name extension data. The ``tls_www_server`` keyword is
 134the key purpose extension to indicate this certificate is intended for
 135usage in a web server. Although QEMU network services are not in fact
 136HTTP servers (except for VNC websockets), setting this key purpose is
 137still recommended. The ``encryption_key`` and ``signing_key`` keyword is
 138the key usage extension to indicate this certificate is intended for
 139usage in the data session.
 140
 141The ``server-hostNNN-key.pem`` and ``server-hostNNN-cert.pem`` files
 142should now be securely copied to the server for which they were
 143generated, and renamed to ``server-key.pem`` and ``server-cert.pem``
 144when added to the ``/etc/pki/qemu`` directory on the target host. The
 145``server-key.pem`` file is security sensitive and should be kept
 146protected with file mode 0600 to prevent disclosure.
 147
 148.. _tls_005fgenerate_005fclient:
 149
 150Issuing client certificates
 151~~~~~~~~~~~~~~~~~~~~~~~~~~~
 152
 153The QEMU x509 TLS credential setup defaults to enabling client
 154verification using certificates, providing a simple authentication
 155mechanism. If this default is used, each client also needs to be issued
 156a certificate. The client certificate contains enough metadata to
 157uniquely identify the client with the scope of the certificate
 158authority. The client certificate would typically include fields for
 159organization, state, city, building, etc.
 160
 161Once again on the host holding the CA, create template files containing
 162the information for each client, and use it to issue client
 163certificates.
 164
 165::
 166
 167   # cat > client-hostNNN.info <<EOF
 168   country = GB
 169   state = London
 170   locality = City Of London
 171   organization = Name of your organization
 172   cn = hostNNN.foo.example.com
 173   tls_www_client
 174   encryption_key
 175   signing_key
 176   EOF
 177   # certtool --generate-privkey > client-hostNNN-key.pem
 178   # certtool --generate-certificate \
 179              --load-ca-certificate ca-cert.pem \
 180              --load-ca-privkey ca-key.pem \
 181              --load-privkey client-hostNNN-key.pem \
 182              --template client-hostNNN.info \
 183              --outfile client-hostNNN-cert.pem
 184
 185The subject alt name extension data is not required for clients, so the
 186the ``dns_name`` and ``ip_address`` fields are not included. The
 187``tls_www_client`` keyword is the key purpose extension to indicate this
 188certificate is intended for usage in a web client. Although QEMU network
 189clients are not in fact HTTP clients, setting this key purpose is still
 190recommended. The ``encryption_key`` and ``signing_key`` keyword is the
 191key usage extension to indicate this certificate is intended for usage
 192in the data session.
 193
 194The ``client-hostNNN-key.pem`` and ``client-hostNNN-cert.pem`` files
 195should now be securely copied to the client for which they were
 196generated, and renamed to ``client-key.pem`` and ``client-cert.pem``
 197when added to the ``/etc/pki/qemu`` directory on the target host. The
 198``client-key.pem`` file is security sensitive and should be kept
 199protected with file mode 0600 to prevent disclosure.
 200
 201If a single host is going to be using TLS in both a client and server
 202role, it is possible to create a single certificate to cover both roles.
 203This would be quite common for the migration and NBD services, where a
 204QEMU process will be started by accepting a TLS protected incoming
 205migration, and later itself be migrated out to another host. To generate
 206a single certificate, simply include the template data from both the
 207client and server instructions in one.
 208
 209::
 210
 211   # cat > both-hostNNN.info <<EOF
 212   country = GB
 213   state = London
 214   locality = City Of London
 215   organization = Name of your organization
 216   cn = hostNNN.foo.example.com
 217   dns_name = hostNNN
 218   dns_name = hostNNN.foo.example.com
 219   ip_address = 10.0.1.87
 220   ip_address = 192.8.0.92
 221   ip_address = 2620:0:cafe::87
 222   ip_address = 2001:24::92
 223   tls_www_server
 224   tls_www_client
 225   encryption_key
 226   signing_key
 227   EOF
 228   # certtool --generate-privkey > both-hostNNN-key.pem
 229   # certtool --generate-certificate \
 230              --load-ca-certificate ca-cert.pem \
 231              --load-ca-privkey ca-key.pem \
 232              --load-privkey both-hostNNN-key.pem \
 233              --template both-hostNNN.info \
 234              --outfile both-hostNNN-cert.pem
 235
 236When copying the PEM files to the target host, save them twice, once as
 237``server-cert.pem`` and ``server-key.pem``, and again as
 238``client-cert.pem`` and ``client-key.pem``.
 239
 240.. _tls_005fcreds_005fsetup:
 241
 242TLS x509 credential configuration
 243~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 244
 245QEMU has a standard mechanism for loading x509 credentials that will be
 246used for network services and clients. It requires specifying the
 247``tls-creds-x509`` class name to the ``--object`` command line argument
 248for the system emulators. Each set of credentials loaded should be given
 249a unique string identifier via the ``id`` parameter. A single set of TLS
 250credentials can be used for multiple network backends, so VNC,
 251migration, NBD, character devices can all share the same credentials.
 252Note, however, that credentials for use in a client endpoint must be
 253loaded separately from those used in a server endpoint.
 254
 255When specifying the object, the ``dir`` parameters specifies which
 256directory contains the credential files. This directory is expected to
 257contain files with the names mentioned previously, ``ca-cert.pem``,
 258``server-key.pem``, ``server-cert.pem``, ``client-key.pem`` and
 259``client-cert.pem`` as appropriate. It is also possible to include a set
 260of pre-generated Diffie-Hellman (DH) parameters in a file
 261``dh-params.pem``, which can be created using the
 262``certtool --generate-dh-params`` command. If omitted, QEMU will
 263dynamically generate DH parameters when loading the credentials.
 264
 265The ``endpoint`` parameter indicates whether the credentials will be
 266used for a network client or server, and determines which PEM files are
 267loaded.
 268
 269The ``verify`` parameter determines whether x509 certificate validation
 270should be performed. This defaults to enabled, meaning clients will
 271always validate the server hostname against the certificate subject alt
 272name fields and/or CN field. It also means that servers will request
 273that clients provide a certificate and validate them. Verification
 274should never be turned off for client endpoints, however, it may be
 275turned off for server endpoints if an alternative mechanism is used to
 276authenticate clients. For example, the VNC server can use SASL to
 277authenticate clients instead.
 278
 279To load server credentials with client certificate validation enabled
 280
 281.. parsed-literal::
 282
 283   |qemu_system| -object tls-creds-x509,id=tls0,dir=/etc/pki/qemu,endpoint=server
 284
 285while to load client credentials use
 286
 287.. parsed-literal::
 288
 289   |qemu_system| -object tls-creds-x509,id=tls0,dir=/etc/pki/qemu,endpoint=client
 290
 291Network services which support TLS will all have a ``tls-creds``
 292parameter which expects the ID of the TLS credentials object. For
 293example with VNC:
 294
 295.. parsed-literal::
 296
 297   |qemu_system| -vnc 0.0.0.0:0,tls-creds=tls0
 298
 299.. _tls_005fpsk:
 300
 301TLS Pre-Shared Keys (PSK)
 302~~~~~~~~~~~~~~~~~~~~~~~~~
 303
 304Instead of using certificates, you may also use TLS Pre-Shared Keys
 305(TLS-PSK). This can be simpler to set up than certificates but is less
 306scalable.
 307
 308Use the GnuTLS ``psktool`` program to generate a ``keys.psk`` file
 309containing one or more usernames and random keys::
 310
 311   mkdir -m 0700 /tmp/keys
 312   psktool -u rich -p /tmp/keys/keys.psk
 313
 314TLS-enabled servers such as qemu-nbd can use this directory like so::
 315
 316   qemu-nbd \
 317     -t -x / \
 318     --object tls-creds-psk,id=tls0,endpoint=server,dir=/tmp/keys \
 319     --tls-creds tls0 \
 320     image.qcow2
 321
 322When connecting from a qemu-based client you must specify the directory
 323containing ``keys.psk`` and an optional username (defaults to "qemu")::
 324
 325   qemu-img info \
 326     --object tls-creds-psk,id=tls0,dir=/tmp/keys,username=rich,endpoint=client \
 327     --image-opts \
 328     file.driver=nbd,file.host=localhost,file.port=10809,file.tls-creds=tls0,file.export=/
 329