1 [[sysadmin_certificate_management]]
9 Certificates for communication within the cluster
10 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
12 Each {PVE} cluster creates its own (self-signed) Certificate Authority (CA) and
13 generates a certificate for each node which gets signed by the aforementioned
14 CA. These certificates are used for encrypted communication with the cluster's
15 `pveproxy` service and the Shell/Console feature if SPICE is used.
17 The CA certificate and key are stored in the xref:chapter_pmxcfs[Proxmox Cluster File System (pmxcfs)].
19 Certificates for API and web GUI
20 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
22 The REST API and web GUI are provided by the `pveproxy` service, which runs on
25 You have the following options for the certificate used by `pveproxy`:
27 1. By default the node-specific certificate in
28 `/etc/pve/nodes/NODENAME/pve-ssl.pem` is used. This certificate is signed by
29 the cluster CA and therefore not trusted by browsers and operating systems by
31 2. use an externally provided certificate (e.g. signed by a commercial CA).
32 3. use ACME (e.g., Let's Encrypt) to get a trusted certificate with automatic
33 renewal, this is also integrated in the {pve} API and Webinterface.
35 For options 2 and 3 the file `/etc/pve/local/pveproxy-ssl.pem` (and
36 `/etc/pve/local/pveproxy-ssl.key`, which needs to be without password) is used.
38 NOTE: Keep in mind that `/etc/pve/local` is a node specific symlink to
39 `/etc/pve/nodes/NODENAME`.
41 Certificates are managed with the {PVE} Node management command
42 (see the `pvenode(1)` manpage).
44 WARNING: Do not replace or manually modify the automatically generated node
45 certificate files in `/etc/pve/local/pve-ssl.pem` and
46 `/etc/pve/local/pve-ssl.key` or the cluster CA files in
47 `/etc/pve/pve-root-ca.pem` and `/etc/pve/priv/pve-root-ca.key`.
49 Getting trusted certificates via ACME
50 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
51 {PVE} includes an implementation of the **A**utomatic **C**ertificate
52 **M**anagement **E**nvironment **ACME** protocol, allowing {pve} admins to
53 interface with Let's Encrypt for easy setup of trusted TLS certificates which
54 are accepted out of the box on most modern operating systems and browsers.
56 Currently the two ACME endpoints implemented are Let's Encrypt (LE) and its
57 staging environment (see https://letsencrypt.org). Our ACME client supports
58 validation of `http-01` challenges using a built-in webserver and validation of
59 `dns-01` challenges using a DNS plugin.
61 Because of https://letsencrypt.org/docs/rate-limits/[rate-limits] you should use
62 LE `staging` for experiments.
64 ACME Plugin configuration is stored in `/etc/pve/priv/acme/plugins.cfg`. There
65 is always an implicitly configured `standalone` plugin for validating `http-01`
66 challenges via the built-in webserver spawned on port 80.
68 There are a few prerequisites to use Let's Encrypt:
70 * You have to accept the ToS of Let's Encrypt to register an account.
72 For `http-01` challenges:
74 * **Port 80** of the node needs to be reachable from the internet.
75 * There **must** be no other listener on port 80.
76 * The requested (sub)domain needs to resolve to a public IP of the Node.
78 For `dns-01` challenges:
80 * DNS needs to be handled by a server that allows automatic provisioning of
83 At the moment the GUI uses only the default ACME account.
85 .Example: Sample `pvenode` invocation for using Let's Encrypt certificates
88 root@proxmox:~# pvenode acme account register default mail@example.invalid
90 0) Let's Encrypt V2 (https://acme-v02.api.letsencrypt.org/directory)
91 1) Let's Encrypt V2 Staging (https://acme-staging-v02.api.letsencrypt.org/directory)
96 Attempting to fetch Terms of Service from 'https://acme-staging-v02.api.letsencrypt.org/directory'..
97 Terms of Service: https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf
98 Do you agree to the above terms? [y|N]y
100 Attempting to register account with 'https://acme-staging-v02.api.letsencrypt.org/directory'..
101 Generating ACME account key..
102 Registering ACME account..
103 Registration successful, account URL: 'https://acme-staging-v02.api.letsencrypt.org/acme/acct/xxxxxxx'
105 root@proxmox:~# pvenode acme account list
107 root@proxmox:~# pvenode config set --acme domains=example.invalid
108 root@proxmox:~# pvenode acme cert order
109 Loading ACME account details
111 Order URL: https://acme-staging-v02.api.letsencrypt.org/acme/order/xxxxxxxxxxxxxx
113 Getting authorization details from
114 'https://acme-staging-v02.api.letsencrypt.org/acme/authz/xxxxxxxxxxxxxxxxxxxxx-xxxxxxxxxxxxx-xxxxxxx'
117 Triggering validation
118 Sleeping for 5 seconds
121 All domains validated!
125 Checking order status
128 Downloading certificate
129 Setting pveproxy certificate and key
134 Switching from the `staging` to the regular ACME directory
135 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
137 Changing the ACME directory for an account is unsupported. If you want to switch
138 an account from the `staging` ACME directory to the regular, trusted, one you
139 need to deactivate it and recreate it.
141 This procedure is also needed to change the default ACME account used in the GUI.
143 .Example: Changing the `default` ACME account from the `staging` to the regular directory
146 root@proxmox:~# pvenode acme account info default
147 Directory URL: https://acme-staging-v02.api.letsencrypt.org/directory
148 Account URL: https://acme-staging-v02.api.letsencrypt.org/acme/acct/6332194
149 Terms Of Service: https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf
154 - mailto:example@proxmox.com
155 Creation date: 2018-07-31T08:41:44.54196435Z
156 Initial IP: 192.0.2.1
159 root@proxmox:~# pvenode acme account deactivate default
160 Renaming account file from '/etc/pve/priv/acme/default' to '/etc/pve/priv/acme/_deactivated_default_4'
163 root@proxmox:~# pvenode acme account register default example@proxmox.com
165 0) Let's Encrypt V2 (https://acme-v02.api.letsencrypt.org/directory)
166 1) Let's Encrypt V2 Staging (https://acme-staging-v02.api.letsencrypt.org/directory)
171 Attempting to fetch Terms of Service from 'https://acme-v02.api.letsencrypt.org/directory'..
172 Terms of Service: https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf
173 Do you agree to the above terms? [y|N]y
175 Attempting to register account with 'https://acme-v02.api.letsencrypt.org/directory'..
176 Generating ACME account key..
177 Registering ACME account..
178 Registration successful, account URL: 'https://acme-v02.api.letsencrypt.org/acme/acct/39335247'
182 Automatic renewal of ACME certificates
183 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
185 If a node has been successfully configured with an ACME-provided certificate
186 (either via pvenode or via the GUI), the certificate will be automatically
187 renewed by the pve-daily-update.service. Currently, renewal will be attempted
188 if the certificate has expired already, or will expire in the next 30 days.
190 Configuring DNS APIs for validation
191 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
193 On systems where external access for validation via the `http-01` method is
194 not possible or desired, it is possible to use the `dns-01` validation method.
195 This validation method requires a DNS server that allows provisioning of `TXT`
198 {PVE} re-uses the DNS plugins developed for the `acme.sh`
199 footnote:[acme.sh https://github.com/acmesh-official/acme.sh]
200 project, please refer to its documentation for details on configuration of
203 Combining `http-01` and `dns-01` validation is possible in case your node is
204 reachable via multiple domains with different requirements / DNS provisioning
205 capabilities. Mixing DNS APIs from multiple providers or instances is also
206 possible by specifying different plugin instances per domain.
208 A special `alias` mode can be used to handle the validation on a different
209 domain/DNS server, in case your primary/real DNS does not support provisioning
210 via an API. Manually set up a permanent `CNAME` record for
211 `_acme-challenge.domain1.example` pointing to `_acme-challenge.domain2.example`
212 and set the `alias` property in the {PVE} node configuration file to
213 `domain2.example` to allow the DNS server of `domain2.example` to validate all
214 challenges for `domain1.example`.
216 .Example: Setting up the OVH API for validating a domain
218 NOTE: the account registration steps are the same no matter which plugins are
219 used, and are not repeated here.
221 NOTE: `OVH_AK` and `OVH_AS` need to be obtained from OVH according to the OVH
225 First you need to get all information so you and {pve} can access the API.
228 root@proxmox:~# cat /path/to/api-token
229 OVH_AK=XXXXXXXXXXXXXXXX
230 OVH_AS=YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
231 root@proxmox:~# source /path/to/api-token
232 root@proxmox:~# curl -XPOST -H"X-Ovh-Application: $OVH_AK" -H "Content-type: application/json" \
233 https://eu.api.ovh.com/1.0/auth/credential -d '{
235 {"method": "GET","path": "/auth/time"},
236 {"method": "GET","path": "/domain"},
237 {"method": "GET","path": "/domain/zone/*"},
238 {"method": "GET","path": "/domain/zone/*/record"},
239 {"method": "POST","path": "/domain/zone/*/record"},
240 {"method": "POST","path": "/domain/zone/*/refresh"},
241 {"method": "PUT","path": "/domain/zone/*/record/"},
242 {"method": "DELETE","path": "/domain/zone/*/record/*"}
245 {"consumerKey":"ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ","state":"pendingValidation","validationUrl":"https://eu.api.ovh.com/auth/?credentialToken=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"}
247 (open validation URL and follow instructions to link Application Key with account/Consumer Key)
249 root@proxmox:~# echo "OVH_CK=ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" >> /path/to/api-token
252 Now you can setup the the ACME plugin:
255 root@proxmox:~# pvenode acme plugin add dns example_plugin --api ovh --data /path/to/api_token
256 root@proxmox:~# pvenode acme plugin config example_plugin
257 ┌────────┬──────────────────────────────────────────┐
259 ╞════════╪══════════════════════════════════════════╡
261 ├────────┼──────────────────────────────────────────┤
262 │ data │ OVH_AK=XXXXXXXXXXXXXXXX │
263 │ │ OVH_AS=YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY │
264 │ │ OVH_CK=ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ │
265 ├────────┼──────────────────────────────────────────┤
266 │ digest │ 867fcf556363ca1bea866863093fcab83edf47a1 │
267 ├────────┼──────────────────────────────────────────┤
268 │ plugin │ example_plugin │
269 ├────────┼──────────────────────────────────────────┤
271 └────────┴──────────────────────────────────────────┘
274 At last you can configure the domain you want to get certitficates for and
275 place the certificate order for it:
278 root@proxmox:~# pvenode config set -acmedomain0 example.proxmox.com,plugin=example_plugin
279 root@proxmox:~# pvenode acme cert order
280 Loading ACME account details
282 Order URL: https://acme-staging-v02.api.letsencrypt.org/acme/order/11111111/22222222
284 Getting authorization details from 'https://acme-staging-v02.api.letsencrypt.org/acme/authz-v3/33333333'
285 The validation for example.proxmox.com is pending!
286 [Wed Apr 22 09:25:30 CEST 2020] Using OVH endpoint: ovh-eu
287 [Wed Apr 22 09:25:30 CEST 2020] Checking authentication
288 [Wed Apr 22 09:25:30 CEST 2020] Consumer key is ok.
289 [Wed Apr 22 09:25:31 CEST 2020] Adding record
290 [Wed Apr 22 09:25:32 CEST 2020] Added, sleep 10 seconds.
291 Add TXT record: _acme-challenge.example.proxmox.com
292 Triggering validation
293 Sleeping for 5 seconds
295 [Wed Apr 22 09:25:48 CEST 2020] Using OVH endpoint: ovh-eu
296 [Wed Apr 22 09:25:48 CEST 2020] Checking authentication
297 [Wed Apr 22 09:25:48 CEST 2020] Consumer key is ok.
298 Remove TXT record: _acme-challenge.example.proxmox.com
300 All domains validated!
303 Checking order status
304 Order is ready, finalizing order
307 Downloading certificate
308 Setting pveproxy certificate and key