]> git.proxmox.com Git - pve-docs.git/blame - certificate-management.adoc
cert management: move some headings a level up for better visibility
[pve-docs.git] / certificate-management.adoc
CommitLineData
aeecd9ea
SI
1[[sysadmin_certificate_management]]
2Certificate Management
3----------------------
4ifdef::wiki[]
5:pve-toplevel:
6endif::wiki[]
7
8
9Certificates for communication within the cluster
10~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
11
94958b8b 12Each {PVE} cluster creates its own (self-signed) Certificate Authority (CA) and
1a58a3c9
TL
13generates a certificate for each node which gets signed by the aforementioned
14CA. These certificates are used for encrypted communication with the cluster's
15`pveproxy` service and the Shell/Console feature if SPICE is used.
aeecd9ea 16
2971c735 17The CA certificate and key are stored in the xref:chapter_pmxcfs[Proxmox Cluster File System (pmxcfs)].
aeecd9ea 18
0a1739bd 19
aeecd9ea
SI
20Certificates for API and web GUI
21~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
22
0e9c6c13
FG
23The REST API and web GUI are provided by the `pveproxy` service, which runs on
24each node.
aeecd9ea
SI
25
26You have the following options for the certificate used by `pveproxy`:
27
0e9c6c13
FG
281. By default the node-specific certificate in
29`/etc/pve/nodes/NODENAME/pve-ssl.pem` is used. This certificate is signed by
0a1739bd
TL
30the cluster CA and therefore not automatically trusted by browsers and
31operating systems.
0e9c6c13 322. use an externally provided certificate (e.g. signed by a commercial CA).
0a1739bd 333. use ACME (Let's Encrypt) to get a trusted certificate with automatic
da30f82a 34renewal, this is also integrated in the {pve} API and Webinterface.
aeecd9ea 35
0e9c6c13 36For options 2 and 3 the file `/etc/pve/local/pveproxy-ssl.pem` (and
aeecd9ea
SI
37`/etc/pve/local/pveproxy-ssl.key`, which needs to be without password) is used.
38
da30f82a
TL
39NOTE: Keep in mind that `/etc/pve/local` is a node specific symlink to
40`/etc/pve/nodes/NODENAME`.
41
aeecd9ea
SI
42Certificates are managed with the {PVE} Node management command
43(see the `pvenode(1)` manpage).
44
0e9c6c13
FG
45WARNING: Do not replace or manually modify the automatically generated node
46certificate files in `/etc/pve/local/pve-ssl.pem` and
47`/etc/pve/local/pve-ssl.key` or the cluster CA files in
48`/etc/pve/pve-root-ca.pem` and `/etc/pve/priv/pve-root-ca.key`.
aeecd9ea 49
0a1739bd 50
aeecd9ea 51Getting trusted certificates via ACME
0a1739bd
TL
52~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
53
aeecd9ea
SI
54{PVE} includes an implementation of the **A**utomatic **C**ertificate
55**M**anagement **E**nvironment **ACME** protocol, allowing {pve} admins to
0e9c6c13
FG
56interface with Let's Encrypt for easy setup of trusted TLS certificates which
57are accepted out of the box on most modern operating systems and browsers.
aeecd9ea
SI
58
59Currently the two ACME endpoints implemented are Let's Encrypt (LE) and its
0b447f1c
FG
60staging environment (see https://letsencrypt.org). Our ACME client supports
61validation of `http-01` challenges using a built-in webserver and validation of
62`dns-01` challenges using a DNS plugin.
aeecd9ea
SI
63
64Because of https://letsencrypt.org/docs/rate-limits/[rate-limits] you should use
65LE `staging` for experiments.
66
0b447f1c
FG
67ACME Plugin configuration is stored in `/etc/pve/priv/acme/plugins.cfg`. There
68is always an implicitly configured `standalone` plugin for validating `http-01`
69challenges via the built-in webserver spawned on port 80.
70
aeecd9ea
SI
71There are a few prerequisites to use Let's Encrypt:
72
0b447f1c
FG
73* You have to accept the ToS of Let's Encrypt to register an account.
74
75For `http-01` challenges:
76
77* **Port 80** of the node needs to be reachable from the internet.
78* There **must** be no other listener on port 80.
79* The requested (sub)domain needs to resolve to a public IP of the Node.
80
81For `dns-01` challenges:
82
83* DNS needs to be handled by a server that allows automatic provisioning of
84TXT records
aeecd9ea
SI
85
86At the moment the GUI uses only the default ACME account.
87
88.Example: Sample `pvenode` invocation for using Let's Encrypt certificates
89
b0014034 90----
aeecd9ea
SI
91root@proxmox:~# pvenode acme account register default mail@example.invalid
92Directory endpoints:
930) Let's Encrypt V2 (https://acme-v02.api.letsencrypt.org/directory)
941) Let's Encrypt V2 Staging (https://acme-staging-v02.api.letsencrypt.org/directory)
952) Custom
96Enter selection:
971
98
99Attempting to fetch Terms of Service from 'https://acme-staging-v02.api.letsencrypt.org/directory'..
100Terms of Service: https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf
101Do you agree to the above terms? [y|N]y
102
103Attempting to register account with 'https://acme-staging-v02.api.letsencrypt.org/directory'..
104Generating ACME account key..
105Registering ACME account..
106Registration successful, account URL: 'https://acme-staging-v02.api.letsencrypt.org/acme/acct/xxxxxxx'
107Task OK
108root@proxmox:~# pvenode acme account list
109default
110root@proxmox:~# pvenode config set --acme domains=example.invalid
111root@proxmox:~# pvenode acme cert order
112Loading ACME account details
113Placing ACME order
114Order URL: https://acme-staging-v02.api.letsencrypt.org/acme/order/xxxxxxxxxxxxxx
115
116Getting authorization details from
117'https://acme-staging-v02.api.letsencrypt.org/acme/authz/xxxxxxxxxxxxxxxxxxxxx-xxxxxxxxxxxxx-xxxxxxx'
118... pending!
119Setting up webserver
120Triggering validation
121Sleeping for 5 seconds
122Status is 'valid'!
123
124All domains validated!
125
126Creating CSR
127Finalizing order
128Checking order status
129valid!
130
131Downloading certificate
132Setting pveproxy certificate and key
133Restarting pveproxy
134Task OK
d75e644b 135----
0e9c6c13 136
19b04e77 137Switching from the `staging` to the regular ACME directory
b0014034 138^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
19b04e77
SI
139
140Changing the ACME directory for an account is unsupported. If you want to switch
141an account from the `staging` ACME directory to the regular, trusted, one you
142need to deactivate it and recreate it.
143
144This procedure is also needed to change the default ACME account used in the GUI.
145
146.Example: Changing the `default` ACME account from the `staging` to the regular directory
147
d75e644b 148----
19b04e77
SI
149root@proxmox:~# pvenode acme account info default
150Directory URL: https://acme-staging-v02.api.letsencrypt.org/directory
151Account URL: https://acme-staging-v02.api.letsencrypt.org/acme/acct/6332194
152Terms Of Service: https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf
153
154Account information:
155ID: xxxxxxx
156Contact:
157 - mailto:example@proxmox.com
158Creation date: 2018-07-31T08:41:44.54196435Z
159Initial IP: 192.0.2.1
160Status: valid
161
162root@proxmox:~# pvenode acme account deactivate default
163Renaming account file from '/etc/pve/priv/acme/default' to '/etc/pve/priv/acme/_deactivated_default_4'
164Task OK
d75e644b 165
19b04e77
SI
166root@proxmox:~# pvenode acme account register default example@proxmox.com
167Directory endpoints:
1680) Let's Encrypt V2 (https://acme-v02.api.letsencrypt.org/directory)
1691) Let's Encrypt V2 Staging (https://acme-staging-v02.api.letsencrypt.org/directory)
1702) Custom
171Enter selection:
1720
173
174Attempting to fetch Terms of Service from 'https://acme-v02.api.letsencrypt.org/directory'..
175Terms of Service: https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf
176Do you agree to the above terms? [y|N]y
177
178Attempting to register account with 'https://acme-v02.api.letsencrypt.org/directory'..
179Generating ACME account key..
180Registering ACME account..
181Registration successful, account URL: 'https://acme-v02.api.letsencrypt.org/acme/acct/39335247'
182Task OK
d75e644b 183----
19b04e77 184
0e9c6c13
FG
185Automatic renewal of ACME certificates
186^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
187
188If a node has been successfully configured with an ACME-provided certificate
189(either via pvenode or via the GUI), the certificate will be automatically
190renewed by the pve-daily-update.service. Currently, renewal will be attempted
da30f82a 191if the certificate has expired already, or will expire in the next 30 days.
0b447f1c 192
0a1739bd
TL
193Configuring ACME DNS APIs for validation
194~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0b447f1c
FG
195
196On systems where external access for validation via the `http-01` method is
197not possible or desired, it is possible to use the `dns-01` validation method.
198This validation method requires a DNS server that allows provisioning of `TXT`
199records via an API.
200
201{PVE} re-uses the DNS plugins developed for the `acme.sh`
202footnote:[acme.sh https://github.com/acmesh-official/acme.sh]
203project, please refer to its documentation for details on configuration of
204specific APIs.
205
206Combining `http-01` and `dns-01` validation is possible in case your node is
207reachable via multiple domains with different requirements / DNS provisioning
208capabilities. Mixing DNS APIs from multiple providers or instances is also
209possible by specifying different plugin instances per domain.
210
211A special `alias` mode can be used to handle the validation on a different
212domain/DNS server, in case your primary/real DNS does not support provisioning
213via an API. Manually set up a permanent `CNAME` record for
214`_acme-challenge.domain1.example` pointing to `_acme-challenge.domain2.example`
215and set the `alias` property in the {PVE} node configuration file to
216`domain2.example` to allow the DNS server of `domain2.example` to validate all
217challenges for `domain1.example`.
218
219.Example: Setting up the OVH API for validating a domain
220
186c094b
TL
221NOTE: the account registration steps are the same no matter which plugins are
222used, and are not repeated here.
223
224NOTE: `OVH_AK` and `OVH_AS` need to be obtained from OVH according to the OVH
225API documentation
226
227
228First you need to get all information so you and {pve} can access the API.
0b447f1c
FG
229
230----
231root@proxmox:~# cat /path/to/api-token
232OVH_AK=XXXXXXXXXXXXXXXX
233OVH_AS=YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
234root@proxmox:~# source /path/to/api-token
235root@proxmox:~# curl -XPOST -H"X-Ovh-Application: $OVH_AK" -H "Content-type: application/json" \
236https://eu.api.ovh.com/1.0/auth/credential -d '{
237 "accessRules": [
238 {"method": "GET","path": "/auth/time"},
239 {"method": "GET","path": "/domain"},
240 {"method": "GET","path": "/domain/zone/*"},
241 {"method": "GET","path": "/domain/zone/*/record"},
242 {"method": "POST","path": "/domain/zone/*/record"},
243 {"method": "POST","path": "/domain/zone/*/refresh"},
244 {"method": "PUT","path": "/domain/zone/*/record/"},
245 {"method": "DELETE","path": "/domain/zone/*/record/*"}
246]
247}'
248{"consumerKey":"ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ","state":"pendingValidation","validationUrl":"https://eu.api.ovh.com/auth/?credentialToken=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"}
249
250(open validation URL and follow instructions to link Application Key with account/Consumer Key)
251
252root@proxmox:~# echo "OVH_CK=ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" >> /path/to/api-token
186c094b
TL
253----
254
255Now you can setup the the ACME plugin:
256
257----
0b447f1c
FG
258root@proxmox:~# pvenode acme plugin add dns example_plugin --api ovh --data /path/to/api_token
259root@proxmox:~# pvenode acme plugin config example_plugin
260┌────────┬──────────────────────────────────────────┐
261│ key │ value │
262╞════════╪══════════════════════════════════════════╡
263│ api │ ovh │
264├────────┼──────────────────────────────────────────┤
265│ data │ OVH_AK=XXXXXXXXXXXXXXXX │
266│ │ OVH_AS=YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY │
267│ │ OVH_CK=ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ │
268├────────┼──────────────────────────────────────────┤
269│ digest │ 867fcf556363ca1bea866863093fcab83edf47a1 │
270├────────┼──────────────────────────────────────────┤
271│ plugin │ example_plugin │
272├────────┼──────────────────────────────────────────┤
273│ type │ dns │
274└────────┴──────────────────────────────────────────┘
186c094b
TL
275----
276
277At last you can configure the domain you want to get certitficates for and
278place the certificate order for it:
279
280----
0b447f1c
FG
281root@proxmox:~# pvenode config set -acmedomain0 example.proxmox.com,plugin=example_plugin
282root@proxmox:~# pvenode acme cert order
283Loading ACME account details
284Placing ACME order
285Order URL: https://acme-staging-v02.api.letsencrypt.org/acme/order/11111111/22222222
286
287Getting authorization details from 'https://acme-staging-v02.api.letsencrypt.org/acme/authz-v3/33333333'
288The validation for example.proxmox.com is pending!
289[Wed Apr 22 09:25:30 CEST 2020] Using OVH endpoint: ovh-eu
290[Wed Apr 22 09:25:30 CEST 2020] Checking authentication
291[Wed Apr 22 09:25:30 CEST 2020] Consumer key is ok.
292[Wed Apr 22 09:25:31 CEST 2020] Adding record
293[Wed Apr 22 09:25:32 CEST 2020] Added, sleep 10 seconds.
294Add TXT record: _acme-challenge.example.proxmox.com
295Triggering validation
296Sleeping for 5 seconds
297Status is 'valid'!
298[Wed Apr 22 09:25:48 CEST 2020] Using OVH endpoint: ovh-eu
299[Wed Apr 22 09:25:48 CEST 2020] Checking authentication
300[Wed Apr 22 09:25:48 CEST 2020] Consumer key is ok.
301Remove TXT record: _acme-challenge.example.proxmox.com
302
303All domains validated!
304
305Creating CSR
306Checking order status
307Order is ready, finalizing order
308valid!
309
310Downloading certificate
311Setting pveproxy certificate and key
312Restarting pveproxy
313Task OK
314----