xref: /openbmc/qemu/docs/system/tls.rst (revision b15bdb1d8324efe662b94d5c8bac231c4b3a81a9)
1324b2298SPaolo Bonzini.. _network_005ftls:
2324b2298SPaolo Bonzini
3324b2298SPaolo BonziniTLS setup for network services
4324b2298SPaolo Bonzini------------------------------
5324b2298SPaolo Bonzini
6324b2298SPaolo BonziniAlmost all network services in QEMU have the ability to use TLS for
7324b2298SPaolo Bonzinisession data encryption, along with x509 certificates for simple client
8324b2298SPaolo Bonziniauthentication. What follows is a description of how to generate
9324b2298SPaolo Bonzinicertificates suitable for usage with QEMU, and applies to the VNC
10324b2298SPaolo Bonziniserver, character devices with the TCP backend, NBD server and client,
11324b2298SPaolo Bonziniand migration server and client.
12324b2298SPaolo Bonzini
13324b2298SPaolo BonziniAt a high level, QEMU requires certificates and private keys to be
14324b2298SPaolo Bonziniprovided in PEM format. Aside from the core fields, the certificates
15324b2298SPaolo Bonzinishould include various extension data sets, including v3 basic
16324b2298SPaolo Bonziniconstraints data, key purpose, key usage and subject alt name.
17324b2298SPaolo Bonzini
18324b2298SPaolo BonziniThe GnuTLS package includes a command called ``certtool`` which can be
19324b2298SPaolo Bonziniused to easily generate certificates and keys in the required format
20324b2298SPaolo Bonziniwith expected data present. Alternatively a certificate management
21324b2298SPaolo Bonziniservice may be used.
22324b2298SPaolo Bonzini
23324b2298SPaolo BonziniAt a minimum it is necessary to setup a certificate authority, and issue
24324b2298SPaolo Bonzinicertificates to each server. If using x509 certificates for
25324b2298SPaolo Bonziniauthentication, then each client will also need to be issued a
26324b2298SPaolo Bonzinicertificate.
27324b2298SPaolo Bonzini
28324b2298SPaolo BonziniAssuming that the QEMU network services will only ever be exposed to
29324b2298SPaolo Bonziniclients on a private intranet, there is no need to use a commercial
30324b2298SPaolo Bonzinicertificate authority to create certificates. A self-signed CA is
31324b2298SPaolo Bonzinisufficient, and in fact likely to be more secure since it removes the
32324b2298SPaolo Bonziniability of malicious 3rd parties to trick the CA into mis-issuing certs
33324b2298SPaolo Bonzinifor impersonating your services. The only likely exception where a
34324b2298SPaolo Bonzinicommercial CA might be desirable is if enabling the VNC websockets
35324b2298SPaolo Bonziniserver and exposing it directly to remote browser clients. In such a
36324b2298SPaolo Bonzinicase it might be useful to use a commercial CA to avoid needing to
37324b2298SPaolo Bonziniinstall custom CA certs in the web browsers.
38324b2298SPaolo Bonzini
39324b2298SPaolo BonziniThe recommendation is for the server to keep its certificates in either
40324b2298SPaolo Bonzini``/etc/pki/qemu`` or for unprivileged users in ``$HOME/.pki/qemu``.
41324b2298SPaolo Bonzini
42324b2298SPaolo Bonzini.. _tls_005fgenerate_005fca:
43324b2298SPaolo Bonzini
44324b2298SPaolo BonziniSetup the Certificate Authority
45324b2298SPaolo Bonzini~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
46324b2298SPaolo Bonzini
47324b2298SPaolo BonziniThis step only needs to be performed once per organization /
48324b2298SPaolo Bonziniorganizational unit. First the CA needs a private key. This key must be
49324b2298SPaolo Bonzinikept VERY secret and secure. If this key is compromised the entire trust
50324b2298SPaolo Bonzinichain of the certificates issued with it is lost.
51324b2298SPaolo Bonzini
52324b2298SPaolo Bonzini::
53324b2298SPaolo Bonzini
54324b2298SPaolo Bonzini   # certtool --generate-privkey > ca-key.pem
55324b2298SPaolo Bonzini
56324b2298SPaolo BonziniTo generate a self-signed certificate requires one core piece of
57324b2298SPaolo Bonziniinformation, the name of the organization. A template file ``ca.info``
58324b2298SPaolo Bonzinishould be populated with the desired data to avoid having to deal with
59324b2298SPaolo Bonziniinteractive prompts from certtool::
60324b2298SPaolo Bonzini
61324b2298SPaolo Bonzini   # cat > ca.info <<EOF
62324b2298SPaolo Bonzini   cn = Name of your organization
63324b2298SPaolo Bonzini   ca
64324b2298SPaolo Bonzini   cert_signing_key
65324b2298SPaolo Bonzini   EOF
66324b2298SPaolo Bonzini   # certtool --generate-self-signed \
67f029f911SDaniel P. Berrangé              --load-privkey ca-key.pem \
68324b2298SPaolo Bonzini              --template ca.info \
69324b2298SPaolo Bonzini              --outfile ca-cert.pem
70324b2298SPaolo Bonzini
71324b2298SPaolo BonziniThe ``ca`` keyword in the template sets the v3 basic constraints
72324b2298SPaolo Bonziniextension to indicate this certificate is for a CA, while
73324b2298SPaolo Bonzini``cert_signing_key`` sets the key usage extension to indicate this will
74324b2298SPaolo Bonzinibe used for signing other keys. The generated ``ca-cert.pem`` file
75324b2298SPaolo Bonzinishould be copied to all servers and clients wishing to utilize TLS
76324b2298SPaolo Bonzinisupport in the VNC server. The ``ca-key.pem`` must not be
77324b2298SPaolo Bonzinidisclosed/copied anywhere except the host responsible for issuing
78324b2298SPaolo Bonzinicertificates.
79324b2298SPaolo Bonzini
80324b2298SPaolo Bonzini.. _tls_005fgenerate_005fserver:
81324b2298SPaolo Bonzini
82324b2298SPaolo BonziniIssuing server certificates
83324b2298SPaolo Bonzini~~~~~~~~~~~~~~~~~~~~~~~~~~~
84324b2298SPaolo Bonzini
85324b2298SPaolo BonziniEach server (or host) needs to be issued with a key and certificate.
86324b2298SPaolo BonziniWhen connecting the certificate is sent to the client which validates it
87324b2298SPaolo Bonziniagainst the CA certificate. The core pieces of information for a server
88324b2298SPaolo Bonzinicertificate are the hostnames and/or IP addresses that will be used by
89324b2298SPaolo Bonziniclients when connecting. The hostname / IP address that the client
90324b2298SPaolo Bonzinispecifies when connecting will be validated against the hostname(s) and
91324b2298SPaolo BonziniIP address(es) recorded in the server certificate, and if no match is
92324b2298SPaolo Bonzinifound the client will close the connection.
93324b2298SPaolo Bonzini
94324b2298SPaolo BonziniThus it is recommended that the server certificate include both the
95324b2298SPaolo Bonzinifully qualified and unqualified hostnames. If the server will have
96324b2298SPaolo Bonzinipermanently assigned IP address(es), and clients are likely to use them
97324b2298SPaolo Bonziniwhen connecting, they may also be included in the certificate. Both IPv4
98324b2298SPaolo Bonziniand IPv6 addresses are supported. Historically certificates only
99324b2298SPaolo Bonziniincluded 1 hostname in the ``CN`` field, however, usage of this field
100324b2298SPaolo Bonzinifor validation is now deprecated. Instead modern TLS clients will
101324b2298SPaolo Bonzinivalidate against the Subject Alt Name extension data, which allows for
102324b2298SPaolo Bonzinimultiple entries. In the future usage of the ``CN`` field may be
103324b2298SPaolo Bonzinidiscontinued entirely, so providing SAN extension data is strongly
104324b2298SPaolo Bonzinirecommended.
105324b2298SPaolo Bonzini
106324b2298SPaolo BonziniOn the host holding the CA, create template files containing the
107324b2298SPaolo Bonziniinformation for each server, and use it to issue server certificates.
108324b2298SPaolo Bonzini
109324b2298SPaolo Bonzini::
110324b2298SPaolo Bonzini
111324b2298SPaolo Bonzini   # cat > server-hostNNN.info <<EOF
112324b2298SPaolo Bonzini   organization = Name  of your organization
113324b2298SPaolo Bonzini   cn = hostNNN.foo.example.com
114324b2298SPaolo Bonzini   dns_name = hostNNN
115324b2298SPaolo Bonzini   dns_name = hostNNN.foo.example.com
116324b2298SPaolo Bonzini   ip_address = 10.0.1.87
117324b2298SPaolo Bonzini   ip_address = 192.8.0.92
118324b2298SPaolo Bonzini   ip_address = 2620:0:cafe::87
119324b2298SPaolo Bonzini   ip_address = 2001:24::92
120324b2298SPaolo Bonzini   tls_www_server
121324b2298SPaolo Bonzini   encryption_key
122324b2298SPaolo Bonzini   signing_key
123324b2298SPaolo Bonzini   EOF
124324b2298SPaolo Bonzini   # certtool --generate-privkey > server-hostNNN-key.pem
125324b2298SPaolo Bonzini   # certtool --generate-certificate \
126324b2298SPaolo Bonzini              --load-ca-certificate ca-cert.pem \
127324b2298SPaolo Bonzini              --load-ca-privkey ca-key.pem \
128324b2298SPaolo Bonzini              --load-privkey server-hostNNN-key.pem \
129324b2298SPaolo Bonzini              --template server-hostNNN.info \
130324b2298SPaolo Bonzini              --outfile server-hostNNN-cert.pem
131324b2298SPaolo Bonzini
132324b2298SPaolo BonziniThe ``dns_name`` and ``ip_address`` fields in the template are setting
133324b2298SPaolo Bonzinithe subject alt name extension data. The ``tls_www_server`` keyword is
134324b2298SPaolo Bonzinithe key purpose extension to indicate this certificate is intended for
135324b2298SPaolo Bonziniusage in a web server. Although QEMU network services are not in fact
136324b2298SPaolo BonziniHTTP servers (except for VNC websockets), setting this key purpose is
137324b2298SPaolo Bonzinistill recommended. The ``encryption_key`` and ``signing_key`` keyword is
138324b2298SPaolo Bonzinithe key usage extension to indicate this certificate is intended for
139324b2298SPaolo Bonziniusage in the data session.
140324b2298SPaolo Bonzini
141324b2298SPaolo BonziniThe ``server-hostNNN-key.pem`` and ``server-hostNNN-cert.pem`` files
142324b2298SPaolo Bonzinishould now be securely copied to the server for which they were
143324b2298SPaolo Bonzinigenerated, and renamed to ``server-key.pem`` and ``server-cert.pem``
144324b2298SPaolo Bonziniwhen added to the ``/etc/pki/qemu`` directory on the target host. The
145324b2298SPaolo Bonzini``server-key.pem`` file is security sensitive and should be kept
146324b2298SPaolo Bonziniprotected with file mode 0600 to prevent disclosure.
147324b2298SPaolo Bonzini
148324b2298SPaolo Bonzini.. _tls_005fgenerate_005fclient:
149324b2298SPaolo Bonzini
150324b2298SPaolo BonziniIssuing client certificates
151324b2298SPaolo Bonzini~~~~~~~~~~~~~~~~~~~~~~~~~~~
152324b2298SPaolo Bonzini
153324b2298SPaolo BonziniThe QEMU x509 TLS credential setup defaults to enabling client
154324b2298SPaolo Bonziniverification using certificates, providing a simple authentication
155324b2298SPaolo Bonzinimechanism. If this default is used, each client also needs to be issued
156324b2298SPaolo Bonzinia certificate. The client certificate contains enough metadata to
157324b2298SPaolo Bonziniuniquely identify the client with the scope of the certificate
158324b2298SPaolo Bonziniauthority. The client certificate would typically include fields for
159324b2298SPaolo Bonziniorganization, state, city, building, etc.
160324b2298SPaolo Bonzini
161324b2298SPaolo BonziniOnce again on the host holding the CA, create template files containing
162324b2298SPaolo Bonzinithe information for each client, and use it to issue client
163324b2298SPaolo Bonzinicertificates.
164324b2298SPaolo Bonzini
165324b2298SPaolo Bonzini::
166324b2298SPaolo Bonzini
167324b2298SPaolo Bonzini   # cat > client-hostNNN.info <<EOF
168324b2298SPaolo Bonzini   country = GB
169324b2298SPaolo Bonzini   state = London
170324b2298SPaolo Bonzini   locality = City Of London
171324b2298SPaolo Bonzini   organization = Name of your organization
172324b2298SPaolo Bonzini   cn = hostNNN.foo.example.com
173324b2298SPaolo Bonzini   tls_www_client
174324b2298SPaolo Bonzini   encryption_key
175324b2298SPaolo Bonzini   signing_key
176324b2298SPaolo Bonzini   EOF
177324b2298SPaolo Bonzini   # certtool --generate-privkey > client-hostNNN-key.pem
178324b2298SPaolo Bonzini   # certtool --generate-certificate \
179324b2298SPaolo Bonzini              --load-ca-certificate ca-cert.pem \
180324b2298SPaolo Bonzini              --load-ca-privkey ca-key.pem \
181324b2298SPaolo Bonzini              --load-privkey client-hostNNN-key.pem \
182324b2298SPaolo Bonzini              --template client-hostNNN.info \
183324b2298SPaolo Bonzini              --outfile client-hostNNN-cert.pem
184324b2298SPaolo Bonzini
185*7a21bee2SDaniel P. BerrangéThe subject alt name extension data is not required for clients, so
186324b2298SPaolo Bonzinithe ``dns_name`` and ``ip_address`` fields are not included. The
187324b2298SPaolo Bonzini``tls_www_client`` keyword is the key purpose extension to indicate this
188324b2298SPaolo Bonzinicertificate is intended for usage in a web client. Although QEMU network
189324b2298SPaolo Bonziniclients are not in fact HTTP clients, setting this key purpose is still
190324b2298SPaolo Bonzinirecommended. The ``encryption_key`` and ``signing_key`` keyword is the
191324b2298SPaolo Bonzinikey usage extension to indicate this certificate is intended for usage
192324b2298SPaolo Bonziniin the data session.
193324b2298SPaolo Bonzini
194324b2298SPaolo BonziniThe ``client-hostNNN-key.pem`` and ``client-hostNNN-cert.pem`` files
195324b2298SPaolo Bonzinishould now be securely copied to the client for which they were
196324b2298SPaolo Bonzinigenerated, and renamed to ``client-key.pem`` and ``client-cert.pem``
197324b2298SPaolo Bonziniwhen added to the ``/etc/pki/qemu`` directory on the target host. The
198324b2298SPaolo Bonzini``client-key.pem`` file is security sensitive and should be kept
199324b2298SPaolo Bonziniprotected with file mode 0600 to prevent disclosure.
200324b2298SPaolo Bonzini
201324b2298SPaolo BonziniIf a single host is going to be using TLS in both a client and server
202324b2298SPaolo Bonzinirole, it is possible to create a single certificate to cover both roles.
203324b2298SPaolo BonziniThis would be quite common for the migration and NBD services, where a
204324b2298SPaolo BonziniQEMU process will be started by accepting a TLS protected incoming
205324b2298SPaolo Bonzinimigration, and later itself be migrated out to another host. To generate
206324b2298SPaolo Bonzinia single certificate, simply include the template data from both the
207324b2298SPaolo Bonziniclient and server instructions in one.
208324b2298SPaolo Bonzini
209324b2298SPaolo Bonzini::
210324b2298SPaolo Bonzini
211324b2298SPaolo Bonzini   # cat > both-hostNNN.info <<EOF
212324b2298SPaolo Bonzini   country = GB
213324b2298SPaolo Bonzini   state = London
214324b2298SPaolo Bonzini   locality = City Of London
215324b2298SPaolo Bonzini   organization = Name of your organization
216324b2298SPaolo Bonzini   cn = hostNNN.foo.example.com
217324b2298SPaolo Bonzini   dns_name = hostNNN
218324b2298SPaolo Bonzini   dns_name = hostNNN.foo.example.com
219324b2298SPaolo Bonzini   ip_address = 10.0.1.87
220324b2298SPaolo Bonzini   ip_address = 192.8.0.92
221324b2298SPaolo Bonzini   ip_address = 2620:0:cafe::87
222324b2298SPaolo Bonzini   ip_address = 2001:24::92
223324b2298SPaolo Bonzini   tls_www_server
224324b2298SPaolo Bonzini   tls_www_client
225324b2298SPaolo Bonzini   encryption_key
226324b2298SPaolo Bonzini   signing_key
227324b2298SPaolo Bonzini   EOF
228324b2298SPaolo Bonzini   # certtool --generate-privkey > both-hostNNN-key.pem
229324b2298SPaolo Bonzini   # certtool --generate-certificate \
230324b2298SPaolo Bonzini              --load-ca-certificate ca-cert.pem \
231324b2298SPaolo Bonzini              --load-ca-privkey ca-key.pem \
232324b2298SPaolo Bonzini              --load-privkey both-hostNNN-key.pem \
233324b2298SPaolo Bonzini              --template both-hostNNN.info \
234324b2298SPaolo Bonzini              --outfile both-hostNNN-cert.pem
235324b2298SPaolo Bonzini
236324b2298SPaolo BonziniWhen copying the PEM files to the target host, save them twice, once as
237324b2298SPaolo Bonzini``server-cert.pem`` and ``server-key.pem``, and again as
238324b2298SPaolo Bonzini``client-cert.pem`` and ``client-key.pem``.
239324b2298SPaolo Bonzini
240324b2298SPaolo Bonzini.. _tls_005fcreds_005fsetup:
241324b2298SPaolo Bonzini
242324b2298SPaolo BonziniTLS x509 credential configuration
243324b2298SPaolo Bonzini~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
244324b2298SPaolo Bonzini
245324b2298SPaolo BonziniQEMU has a standard mechanism for loading x509 credentials that will be
246324b2298SPaolo Bonziniused for network services and clients. It requires specifying the
247324b2298SPaolo Bonzini``tls-creds-x509`` class name to the ``--object`` command line argument
248324b2298SPaolo Bonzinifor the system emulators. Each set of credentials loaded should be given
249324b2298SPaolo Bonzinia unique string identifier via the ``id`` parameter. A single set of TLS
250324b2298SPaolo Bonzinicredentials can be used for multiple network backends, so VNC,
251324b2298SPaolo Bonzinimigration, NBD, character devices can all share the same credentials.
252324b2298SPaolo BonziniNote, however, that credentials for use in a client endpoint must be
253324b2298SPaolo Bonziniloaded separately from those used in a server endpoint.
254324b2298SPaolo Bonzini
255324b2298SPaolo BonziniWhen specifying the object, the ``dir`` parameters specifies which
256324b2298SPaolo Bonzinidirectory contains the credential files. This directory is expected to
257324b2298SPaolo Bonzinicontain files with the names mentioned previously, ``ca-cert.pem``,
258324b2298SPaolo Bonzini``server-key.pem``, ``server-cert.pem``, ``client-key.pem`` and
259324b2298SPaolo Bonzini``client-cert.pem`` as appropriate. It is also possible to include a set
260324b2298SPaolo Bonziniof pre-generated Diffie-Hellman (DH) parameters in a file
261324b2298SPaolo Bonzini``dh-params.pem``, which can be created using the
262324b2298SPaolo Bonzini``certtool --generate-dh-params`` command. If omitted, QEMU will
263324b2298SPaolo Bonzinidynamically generate DH parameters when loading the credentials.
264324b2298SPaolo Bonzini
265324b2298SPaolo BonziniThe ``endpoint`` parameter indicates whether the credentials will be
266324b2298SPaolo Bonziniused for a network client or server, and determines which PEM files are
267324b2298SPaolo Bonziniloaded.
268324b2298SPaolo Bonzini
269324b2298SPaolo BonziniThe ``verify`` parameter determines whether x509 certificate validation
270324b2298SPaolo Bonzinishould be performed. This defaults to enabled, meaning clients will
271324b2298SPaolo Bonzinialways validate the server hostname against the certificate subject alt
272324b2298SPaolo Bonzininame fields and/or CN field. It also means that servers will request
273324b2298SPaolo Bonzinithat clients provide a certificate and validate them. Verification
274324b2298SPaolo Bonzinishould never be turned off for client endpoints, however, it may be
275324b2298SPaolo Bonziniturned off for server endpoints if an alternative mechanism is used to
276324b2298SPaolo Bonziniauthenticate clients. For example, the VNC server can use SASL to
277324b2298SPaolo Bonziniauthenticate clients instead.
278324b2298SPaolo Bonzini
279324b2298SPaolo BonziniTo load server credentials with client certificate validation enabled
280324b2298SPaolo Bonzini
281324b2298SPaolo Bonzini.. parsed-literal::
282324b2298SPaolo Bonzini
283324b2298SPaolo Bonzini   |qemu_system| -object tls-creds-x509,id=tls0,dir=/etc/pki/qemu,endpoint=server
284324b2298SPaolo Bonzini
285324b2298SPaolo Bonziniwhile to load client credentials use
286324b2298SPaolo Bonzini
287324b2298SPaolo Bonzini.. parsed-literal::
288324b2298SPaolo Bonzini
289324b2298SPaolo Bonzini   |qemu_system| -object tls-creds-x509,id=tls0,dir=/etc/pki/qemu,endpoint=client
290324b2298SPaolo Bonzini
291324b2298SPaolo BonziniNetwork services which support TLS will all have a ``tls-creds``
292324b2298SPaolo Bonziniparameter which expects the ID of the TLS credentials object. For
293324b2298SPaolo Bonziniexample with VNC:
294324b2298SPaolo Bonzini
295324b2298SPaolo Bonzini.. parsed-literal::
296324b2298SPaolo Bonzini
297324b2298SPaolo Bonzini   |qemu_system| -vnc 0.0.0.0:0,tls-creds=tls0
298324b2298SPaolo Bonzini
299324b2298SPaolo Bonzini.. _tls_005fpsk:
300324b2298SPaolo Bonzini
301324b2298SPaolo BonziniTLS Pre-Shared Keys (PSK)
302324b2298SPaolo Bonzini~~~~~~~~~~~~~~~~~~~~~~~~~
303324b2298SPaolo Bonzini
304324b2298SPaolo BonziniInstead of using certificates, you may also use TLS Pre-Shared Keys
305324b2298SPaolo Bonzini(TLS-PSK). This can be simpler to set up than certificates but is less
306324b2298SPaolo Bonziniscalable.
307324b2298SPaolo Bonzini
308324b2298SPaolo BonziniUse the GnuTLS ``psktool`` program to generate a ``keys.psk`` file
309324b2298SPaolo Bonzinicontaining one or more usernames and random keys::
310324b2298SPaolo Bonzini
311324b2298SPaolo Bonzini   mkdir -m 0700 /tmp/keys
312324b2298SPaolo Bonzini   psktool -u rich -p /tmp/keys/keys.psk
313324b2298SPaolo Bonzini
314c5ba6219SPhilippe Mathieu-DaudéTLS-enabled servers such as ``qemu-nbd`` can use this directory like so::
315324b2298SPaolo Bonzini
316324b2298SPaolo Bonzini   qemu-nbd \
317324b2298SPaolo Bonzini     -t -x / \
318324b2298SPaolo Bonzini     --object tls-creds-psk,id=tls0,endpoint=server,dir=/tmp/keys \
319324b2298SPaolo Bonzini     --tls-creds tls0 \
320324b2298SPaolo Bonzini     image.qcow2
321324b2298SPaolo Bonzini
322324b2298SPaolo BonziniWhen connecting from a qemu-based client you must specify the directory
323324b2298SPaolo Bonzinicontaining ``keys.psk`` and an optional username (defaults to "qemu")::
324324b2298SPaolo Bonzini
325324b2298SPaolo Bonzini   qemu-img info \
326324b2298SPaolo Bonzini     --object tls-creds-psk,id=tls0,dir=/tmp/keys,username=rich,endpoint=client \
327324b2298SPaolo Bonzini     --image-opts \
328324b2298SPaolo Bonzini     file.driver=nbd,file.host=localhost,file.port=10809,file.tls-creds=tls0,file.export=/
329