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 signing_key 122 EOF 123 # certtool --generate-privkey > server-hostNNN-key.pem 124 # certtool --generate-certificate \ 125 --load-ca-certificate ca-cert.pem \ 126 --load-ca-privkey ca-key.pem \ 127 --load-privkey server-hostNNN-key.pem \ 128 --template server-hostNNN.info \ 129 --outfile server-hostNNN-cert.pem 130 131The ``dns_name`` and ``ip_address`` fields in the template are setting 132the subject alt name extension data. The ``tls_www_server`` keyword is 133the key purpose extension to indicate this certificate is intended for 134usage in a web server. Although QEMU network services are not in fact 135HTTP servers (except for VNC websockets), setting this key purpose is 136still recommended. The ``signing_key`` keyword is the key usage extension 137to indicate this certificate is intended for usage in the data session. 138 139The ``server-hostNNN-key.pem`` and ``server-hostNNN-cert.pem`` files 140should now be securely copied to the server for which they were 141generated, and renamed to ``server-key.pem`` and ``server-cert.pem`` 142when added to the ``/etc/pki/qemu`` directory on the target host. The 143``server-key.pem`` file is security sensitive and should be kept 144protected with file mode 0600 to prevent disclosure. 145 146.. _tls_005fgenerate_005fclient: 147 148Issuing client certificates 149~~~~~~~~~~~~~~~~~~~~~~~~~~~ 150 151The QEMU x509 TLS credential setup defaults to enabling client 152verification using certificates, providing a simple authentication 153mechanism. If this default is used, each client also needs to be issued 154a certificate. The client certificate contains enough metadata to 155uniquely identify the client with the scope of the certificate 156authority. The client certificate would typically include fields for 157organization, state, city, building, etc. 158 159Once again on the host holding the CA, create template files containing 160the information for each client, and use it to issue client 161certificates. 162 163:: 164 165 # cat > client-hostNNN.info <<EOF 166 country = GB 167 state = London 168 locality = City Of London 169 organization = Name of your organization 170 cn = hostNNN.foo.example.com 171 tls_www_client 172 signing_key 173 EOF 174 # certtool --generate-privkey > client-hostNNN-key.pem 175 # certtool --generate-certificate \ 176 --load-ca-certificate ca-cert.pem \ 177 --load-ca-privkey ca-key.pem \ 178 --load-privkey client-hostNNN-key.pem \ 179 --template client-hostNNN.info \ 180 --outfile client-hostNNN-cert.pem 181 182The subject alt name extension data is not required for clients, so 183the ``dns_name`` and ``ip_address`` fields are not included. The 184``tls_www_client`` keyword is the key purpose extension to indicate this 185certificate is intended for usage in a web client. Although QEMU network 186clients are not in fact HTTP clients, setting this key purpose is still 187recommended. The ``signing_key`` keyword is the key usage extension to 188indicate this certificate is intended for usage in the data session. 189 190The ``client-hostNNN-key.pem`` and ``client-hostNNN-cert.pem`` files 191should now be securely copied to the client for which they were 192generated, and renamed to ``client-key.pem`` and ``client-cert.pem`` 193when added to the ``/etc/pki/qemu`` directory on the target host. The 194``client-key.pem`` file is security sensitive and should be kept 195protected with file mode 0600 to prevent disclosure. 196 197If a single host is going to be using TLS in both a client and server 198role, it is possible to create a single certificate to cover both roles. 199This would be quite common for the migration and NBD services, where a 200QEMU process will be started by accepting a TLS protected incoming 201migration, and later itself be migrated out to another host. To generate 202a single certificate, simply include the template data from both the 203client and server instructions in one. 204 205:: 206 207 # cat > both-hostNNN.info <<EOF 208 country = GB 209 state = London 210 locality = City Of London 211 organization = Name of your organization 212 cn = hostNNN.foo.example.com 213 dns_name = hostNNN 214 dns_name = hostNNN.foo.example.com 215 ip_address = 10.0.1.87 216 ip_address = 192.8.0.92 217 ip_address = 2620:0:cafe::87 218 ip_address = 2001:24::92 219 tls_www_server 220 tls_www_client 221 signing_key 222 EOF 223 # certtool --generate-privkey > both-hostNNN-key.pem 224 # certtool --generate-certificate \ 225 --load-ca-certificate ca-cert.pem \ 226 --load-ca-privkey ca-key.pem \ 227 --load-privkey both-hostNNN-key.pem \ 228 --template both-hostNNN.info \ 229 --outfile both-hostNNN-cert.pem 230 231When copying the PEM files to the target host, save them twice, once as 232``server-cert.pem`` and ``server-key.pem``, and again as 233``client-cert.pem`` and ``client-key.pem``. 234 235.. _tls_005fcreds_005fsetup: 236 237TLS x509 credential configuration 238~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 239 240QEMU has a standard mechanism for loading x509 credentials that will be 241used for network services and clients. It requires specifying the 242``tls-creds-x509`` class name to the ``--object`` command line argument 243for the system emulators. Each set of credentials loaded should be given 244a unique string identifier via the ``id`` parameter. A single set of TLS 245credentials can be used for multiple network backends, so VNC, 246migration, NBD, character devices can all share the same credentials. 247Note, however, that credentials for use in a client endpoint must be 248loaded separately from those used in a server endpoint. 249 250When specifying the object, the ``dir`` parameters specifies which 251directory contains the credential files. This directory is expected to 252contain files with the names mentioned previously, ``ca-cert.pem``, 253``server-key.pem``, ``server-cert.pem``, ``client-key.pem`` and 254``client-cert.pem`` as appropriate. It is also possible to include a set 255of pre-generated Diffie-Hellman (DH) parameters in a file 256``dh-params.pem``, which can be created using the 257``certtool --generate-dh-params`` command. If omitted, QEMU will 258dynamically generate DH parameters when loading the credentials. 259 260The ``endpoint`` parameter indicates whether the credentials will be 261used for a network client or server, and determines which PEM files are 262loaded. 263 264The ``verify`` parameter determines whether x509 certificate validation 265should be performed. This defaults to enabled, meaning clients will 266always validate the server hostname against the certificate subject alt 267name fields and/or CN field. It also means that servers will request 268that clients provide a certificate and validate them. Verification 269should never be turned off for client endpoints, however, it may be 270turned off for server endpoints if an alternative mechanism is used to 271authenticate clients. For example, the VNC server can use SASL to 272authenticate clients instead. 273 274To load server credentials with client certificate validation enabled 275 276.. parsed-literal:: 277 278 |qemu_system| -object tls-creds-x509,id=tls0,dir=/etc/pki/qemu,endpoint=server 279 280while to load client credentials use 281 282.. parsed-literal:: 283 284 |qemu_system| -object tls-creds-x509,id=tls0,dir=/etc/pki/qemu,endpoint=client 285 286Network services which support TLS will all have a ``tls-creds`` 287parameter which expects the ID of the TLS credentials object. For 288example with VNC: 289 290.. parsed-literal:: 291 292 |qemu_system| -vnc 0.0.0.0:0,tls-creds=tls0 293 294.. _tls_005fpsk: 295 296TLS Pre-Shared Keys (PSK) 297~~~~~~~~~~~~~~~~~~~~~~~~~ 298 299Instead of using certificates, you may also use TLS Pre-Shared Keys 300(TLS-PSK). This can be simpler to set up than certificates but is less 301scalable. 302 303Use the GnuTLS ``psktool`` program to generate a ``keys.psk`` file 304containing one or more usernames and random keys:: 305 306 mkdir -m 0700 /tmp/keys 307 psktool -u rich -p /tmp/keys/keys.psk 308 309TLS-enabled servers such as ``qemu-nbd`` can use this directory like so:: 310 311 qemu-nbd \ 312 -t -x / \ 313 --object tls-creds-psk,id=tls0,endpoint=server,dir=/tmp/keys \ 314 --tls-creds tls0 \ 315 image.qcow2 316 317When connecting from a qemu-based client you must specify the directory 318containing ``keys.psk`` and an optional username (defaults to "qemu"):: 319 320 qemu-img info \ 321 --object tls-creds-psk,id=tls0,dir=/tmp/keys,username=rich,endpoint=client \ 322 --image-opts \ 323 file.driver=nbd,file.host=localhost,file.port=10809,file.tls-creds=tls0,file.export=/ 324