]> git.proxmox.com Git - pve-docs.git/blame_incremental - certificate-management.adoc
storage: fixup PBS wiki link
[pve-docs.git] / certificate-management.adoc
... / ...
CommitLineData
1[[sysadmin_certificate_management]]
2Certificate Management
3----------------------
4ifdef::wiki[]
5:pve-toplevel:
6endif::wiki[]
7
8
9Certificates for Intra-Cluster Communication
10~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
11
12Each {PVE} cluster creates by default its own (self-signed) Certificate
13Authority (CA) and generates a certificate for each node which gets signed by
14the aforementioned CA. These certificates are used for encrypted communication
15with the cluster's `pveproxy` service and the Shell/Console feature if SPICE is
16used.
17
18The CA certificate and key are stored in the xref:chapter_pmxcfs[Proxmox Cluster File System (pmxcfs)].
19
20
21[[sysadmin_certs_api_gui]]
22Certificates for API and Web GUI
23~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24
25The REST API and web GUI are provided by the `pveproxy` service, which runs on
26each node.
27
28You have the following options for the certificate used by `pveproxy`:
29
301. By default the node-specific certificate in
31`/etc/pve/nodes/NODENAME/pve-ssl.pem` is used. This certificate is signed by
32the cluster CA and therefore not automatically trusted by browsers and
33operating systems.
342. use an externally provided certificate (e.g. signed by a commercial CA).
353. use ACME (Let's Encrypt) to get a trusted certificate with automatic
36renewal, this is also integrated in the {pve} API and Webinterface.
37
38For options 2 and 3 the file `/etc/pve/local/pveproxy-ssl.pem` (and
39`/etc/pve/local/pveproxy-ssl.key`, which needs to be without password) is used.
40
41NOTE: Keep in mind that `/etc/pve/local` is a node specific symlink to
42`/etc/pve/nodes/NODENAME`.
43
44Certificates are managed with the {PVE} Node management command
45(see the `pvenode(1)` manpage).
46
47WARNING: Do not replace or manually modify the automatically generated node
48certificate files in `/etc/pve/local/pve-ssl.pem` and
49`/etc/pve/local/pve-ssl.key` or the cluster CA files in
50`/etc/pve/pve-root-ca.pem` and `/etc/pve/priv/pve-root-ca.key`.
51
52[[sysadmin_certs_upload_custom]]
53Upload Custom Certificate
54~~~~~~~~~~~~~~~~~~~~~~~~~
55
56If you already have a certificate which you want to use for a {pve} node you
57can upload that certificate simply over the web interface.
58
59[thumbnail="screenshot/gui-node-certs-upload-custom.png"]
60
61Note that the certificates key file, if provided, mustn't be password
62protected.
63
64[[sysadmin_certs_get_trusted_acme_cert]]
65Trusted certificates via Let's Encrypt (ACME)
66~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
67
68{PVE} includes an implementation of the **A**utomatic **C**ertificate
69**M**anagement **E**nvironment **ACME** protocol, allowing {pve} admins to
70interface with Let's Encrypt for easy setup of trusted TLS certificates which
71are accepted out of the box on most modern operating systems and browsers.
72
73Currently the two ACME endpoints implemented are the
74https://letsencrypt.org[Let's Encrypt (LE)] production and its staging
75environment. Our ACME client supports validation of `http-01` challenges using
76a built-in webserver and validation of `dns-01` challenges using a DNS plugin
77supporting all the DNS API endpoints https://acme.sh[acme.sh] does.
78
79[[sysadmin_certs_acme_account]]
80ACME Account
81^^^^^^^^^^^^
82
83[thumbnail="screenshot/gui-datacenter-acme-register-account.png"]
84
85You need to register an ACME account per cluster with the endpoint you want to
86use. The email address used for that account will server as contact point for
87renewal-due or similar notifications from the ACME endpoint.
88
89You can register and deactivate ACME accounts over the web interface
90`Datacenter -> ACME` or using the `pvenode` command line tool.
91----
92 pvenode acme account register account-name mail@example.com
93----
94
95TIP: Because of https://letsencrypt.org/docs/rate-limits/[rate-limits] you
96should use LE `staging` for experiments or if you use ACME for the first time.
97
98[[sysadmin_certs_acme_plugins]]
99ACME Plugins
100^^^^^^^^^^^^
101
102The ACME plugins task is to provide automatic verification that you, and thus
103the {pve} cluster under your operation, are the real owner of a domain. This is
104the basis building block for automatic certificate management.
105
106The ACME protocol specifies different types of challenges, for example the
107`http-01` where a webserver provides a file with a certain value to proof that
108it controls a domain. Sometimes this isn't possible, either because of
109technical limitations or if the address a domain points to is not reachable
110from the public internet. For such cases one could use the `dns-01` challenge.
111That challenge provides also a certain value, but not over a text file, but
112through a DNS record on the authority name server of the domain.
113
114[thumbnail="screenshot/gui-datacenter-acme-overview.png"]
115
116{pve} supports both of those challenge types out of the box, you can configure
117plugins either over the web interface under `Datacenter -> ACME`, or using the
118`pvenode acme plugin add` command.
119
120ACME Plugin configurations are stored in `/etc/pve/priv/acme/plugins.cfg`.
121A plugin is available for all nodes in the cluster.
122
123Node Domains
124^^^^^^^^^^^^
125
126Each domain is node specific. You can add new or manage existing domain entries
127under `Node -> Certificates`, or using the `pvenode config` command.
128
129[thumbnail="screenshot/gui-node-certs-add-domain.png"]
130
131After configuring the desired domain(s) for a node and ensuring that the
132desired ACME account is selected, you can order your new certificate over the
133web-interface. On success the interface will reload after 10 seconds.
134
135Renewal will happen xref:sysadmin_certs_acme_automatic_renewal[automatically].
136
137[[sysadmin_certs_acme_http_challenge]]
138ACME HTTP Challenge Plugin
139~~~~~~~~~~~~~~~~~~~~~~~~~~
140
141There is always an implicitly configured `standalone` plugin for validating
142`http-01` challenges via the built-in webserver spawned on port 80.
143
144NOTE: The name `standalone` means that it can provide the validation on it's
145own, without any third party service. So, this plugin works also for cluster
146nodes.
147
148There are a few prerequisites to use it for certificate management with Let's
149Encrypts ACME.
150
151* You have to accept the ToS of Let's Encrypt to register an account.
152* **Port 80** of the node needs to be reachable from the internet.
153* There **must** be no other listener on port 80.
154* The requested (sub)domain needs to resolve to a public IP of the Node.
155
156
157[[sysadmin_certs_acme_dns_challenge]]
158ACME DNS API Challenge Plugin
159~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
160
161On systems where external access for validation via the `http-01` method is
162not possible or desired, it is possible to use the `dns-01` validation method.
163This validation method requires a DNS server that allows provisioning of `TXT`
164records via an API.
165
166[[sysadmin_certs_acme_dns_api_config]]
167Configuring ACME DNS APIs for validation
168^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
169
170{PVE} re-uses the DNS plugins developed for the `acme.sh`
171footnote:[acme.sh https://github.com/acmesh-official/acme.sh]
172project, please refer to its documentation for details on configuration of
173specific APIs.
174
175The easiest way to configure a new plugin with the DNS API is using the web
176interface (`Datacenter -> ACME`).
177
178[thumbnail="screenshot/gui-datacenter-acme-add-dns-plugin.png"]
179
180Choose `DNS` as challenge type. Then you can select your API provider, enter
181the credential data to access your account over their API.
182
183TIP: See the acme.sh
184https://github.com/acmesh-official/acme.sh/wiki/dnsapi#how-to-use-dns-api[How to use DNS API]
185wiki for more detailed information about getting API credentials for your
186provider.
187
188As there are so many API endpoints {pve} autogenerates the form for the
189credentials, but not all providers are annotated yet. For those you will see a
190bigger text area, simply copy all the credentials `KEY`=`VALUE` pairs in there.
191
192DNS Validation through CNAME Alias
193^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
194
195A special `alias` mode can be used to handle the validation on a different
196domain/DNS server, in case your primary/real DNS does not support provisioning
197via an API. Manually set up a permanent `CNAME` record for
198`_acme-challenge.domain1.example` pointing to `_acme-challenge.domain2.example`
199and set the `alias` property in the {PVE} node configuration file to
200`domain2.example` to allow the DNS server of `domain2.example` to validate all
201challenges for `domain1.example`.
202
203
204Combination of Plugins
205^^^^^^^^^^^^^^^^^^^^^^
206
207Combining `http-01` and `dns-01` validation is possible in case your node is
208reachable via multiple domains with different requirements / DNS provisioning
209capabilities. Mixing DNS APIs from multiple providers or instances is also
210possible by specifying different plugin instances per domain.
211
212TIP: Accessing the same service over multiple domains increases complexity and
213should be avoided if possible.
214
215[[sysadmin_certs_acme_automatic_renewal]]
216Automatic renewal of ACME certificates
217~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
218
219If a node has been successfully configured with an ACME-provided certificate
220(either via pvenode or via the GUI), the certificate will be automatically
221renewed by the `pve-daily-update.service`. Currently, renewal will be attempted
222if the certificate has expired already, or will expire in the next 30 days.
223
224
225ACME Examples with `pvenode`
226~~~~~~~~~~~~~~~~~~~~~~~~~~~~
227
228Example: Sample `pvenode` invocation for using Let's Encrypt certificates
229^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
230
231----
232root@proxmox:~# pvenode acme account register default mail@example.invalid
233Directory endpoints:
2340) Let's Encrypt V2 (https://acme-v02.api.letsencrypt.org/directory)
2351) Let's Encrypt V2 Staging (https://acme-staging-v02.api.letsencrypt.org/directory)
2362) Custom
237Enter selection: 1
238
239Terms of Service: https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf
240Do you agree to the above terms? [y|N]y
241...
242Task OK
243root@proxmox:~# pvenode config set --acme domains=example.invalid
244root@proxmox:~# pvenode acme cert order
245Loading ACME account details
246Placing ACME order
247...
248Status is 'valid'!
249
250All domains validated!
251...
252Downloading certificate
253Setting pveproxy certificate and key
254Restarting pveproxy
255Task OK
256----
257
258Example: Setting up the OVH API for validating a domain
259^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
260
261NOTE: the account registration steps are the same no matter which plugins are
262used, and are not repeated here.
263
264NOTE: `OVH_AK` and `OVH_AS` need to be obtained from OVH according to the OVH
265API documentation
266
267
268First you need to get all information so you and {pve} can access the API.
269
270----
271root@proxmox:~# cat /path/to/api-token
272OVH_AK=XXXXXXXXXXXXXXXX
273OVH_AS=YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
274root@proxmox:~# source /path/to/api-token
275root@proxmox:~# curl -XPOST -H"X-Ovh-Application: $OVH_AK" -H "Content-type: application/json" \
276https://eu.api.ovh.com/1.0/auth/credential -d '{
277 "accessRules": [
278 {"method": "GET","path": "/auth/time"},
279 {"method": "GET","path": "/domain"},
280 {"method": "GET","path": "/domain/zone/*"},
281 {"method": "GET","path": "/domain/zone/*/record"},
282 {"method": "POST","path": "/domain/zone/*/record"},
283 {"method": "POST","path": "/domain/zone/*/refresh"},
284 {"method": "PUT","path": "/domain/zone/*/record/"},
285 {"method": "DELETE","path": "/domain/zone/*/record/*"}
286]
287}'
288{"consumerKey":"ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ","state":"pendingValidation","validationUrl":"https://eu.api.ovh.com/auth/?credentialToken=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"}
289
290(open validation URL and follow instructions to link Application Key with account/Consumer Key)
291
292root@proxmox:~# echo "OVH_CK=ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" >> /path/to/api-token
293----
294
295Now you can setup the the ACME plugin:
296
297----
298root@proxmox:~# pvenode acme plugin add dns example_plugin --api ovh --data /path/to/api_token
299root@proxmox:~# pvenode acme plugin config example_plugin
300┌────────┬──────────────────────────────────────────┐
301│ key │ value │
302╞════════╪══════════════════════════════════════════╡
303│ api │ ovh │
304├────────┼──────────────────────────────────────────┤
305│ data │ OVH_AK=XXXXXXXXXXXXXXXX │
306│ │ OVH_AS=YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY │
307│ │ OVH_CK=ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ │
308├────────┼──────────────────────────────────────────┤
309│ digest │ 867fcf556363ca1bea866863093fcab83edf47a1 │
310├────────┼──────────────────────────────────────────┤
311│ plugin │ example_plugin │
312├────────┼──────────────────────────────────────────┤
313│ type │ dns │
314└────────┴──────────────────────────────────────────┘
315----
316
317At last you can configure the domain you want to get certitficates for and
318place the certificate order for it:
319
320----
321root@proxmox:~# pvenode config set -acmedomain0 example.proxmox.com,plugin=example_plugin
322root@proxmox:~# pvenode acme cert order
323Loading ACME account details
324Placing ACME order
325Order URL: https://acme-staging-v02.api.letsencrypt.org/acme/order/11111111/22222222
326
327Getting authorization details from 'https://acme-staging-v02.api.letsencrypt.org/acme/authz-v3/33333333'
328The validation for example.proxmox.com is pending!
329[Wed Apr 22 09:25:30 CEST 2020] Using OVH endpoint: ovh-eu
330[Wed Apr 22 09:25:30 CEST 2020] Checking authentication
331[Wed Apr 22 09:25:30 CEST 2020] Consumer key is ok.
332[Wed Apr 22 09:25:31 CEST 2020] Adding record
333[Wed Apr 22 09:25:32 CEST 2020] Added, sleep 10 seconds.
334Add TXT record: _acme-challenge.example.proxmox.com
335Triggering validation
336Sleeping for 5 seconds
337Status is 'valid'!
338[Wed Apr 22 09:25:48 CEST 2020] Using OVH endpoint: ovh-eu
339[Wed Apr 22 09:25:48 CEST 2020] Checking authentication
340[Wed Apr 22 09:25:48 CEST 2020] Consumer key is ok.
341Remove TXT record: _acme-challenge.example.proxmox.com
342
343All domains validated!
344
345Creating CSR
346Checking order status
347Order is ready, finalizing order
348valid!
349
350Downloading certificate
351Setting pveproxy certificate and key
352Restarting pveproxy
353Task OK
354----
355
356[[sysadmin_certs_acme_switch_from_staging]]
357Example: Switching from the `staging` to the regular ACME directory
358^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
359
360Changing the ACME directory for an account is unsupported, but as {pve}
361supports more than one account you can just create a new one with the
362production (trusted) ACME directory as endpoint. You can also deactivate the
363staging account and recreate it.
364
365// TODO: add example with account screenshot here
366
367.Example: Changing the `default` ACME account from `staging` to directory using `pvenode`
368----
369root@proxmox:~# pvenode acme account deactivate default
370Renaming account file from '/etc/pve/priv/acme/default' to '/etc/pve/priv/acme/_deactivated_default_4'
371Task OK
372
373root@proxmox:~# pvenode acme account register default example@proxmox.com
374Directory endpoints:
3750) Let's Encrypt V2 (https://acme-v02.api.letsencrypt.org/directory)
3761) Let's Encrypt V2 Staging (https://acme-staging-v02.api.letsencrypt.org/directory)
3772) Custom
378Enter selection: 0
379
380Terms of Service: https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf
381Do you agree to the above terms? [y|N]y
382...
383Task OK
384----