]> git.proxmox.com Git - pve-docs.git/blob - certificate-management.adoc
certs: extend ACME section with DNS/plugin info
[pve-docs.git] / certificate-management.adoc
1 [[sysadmin_certificate_management]]
2 Certificate Management
3 ----------------------
4 ifdef::wiki[]
5 :pve-toplevel:
6 endif::wiki[]
7
8
9 Certificates for communication within the cluster
10 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
11
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.
16
17 The CA certificate and key are stored in the xref:chapter_pmxcfs[Proxmox Cluster File System (pmxcfs)].
18
19 Certificates for API and web GUI
20 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
21
22 The REST API and web GUI are provided by the `pveproxy` service, which runs on
23 each node.
24
25 You have the following options for the certificate used by `pveproxy`:
26
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
30 default.
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.
34
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.
37
38 NOTE: Keep in mind that `/etc/pve/local` is a node specific symlink to
39 `/etc/pve/nodes/NODENAME`.
40
41 Certificates are managed with the {PVE} Node management command
42 (see the `pvenode(1)` manpage).
43
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`.
48
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.
55
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.
60
61 Because of https://letsencrypt.org/docs/rate-limits/[rate-limits] you should use
62 LE `staging` for experiments.
63
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.
67
68 There are a few prerequisites to use Let's Encrypt:
69
70 * You have to accept the ToS of Let's Encrypt to register an account.
71
72 For `http-01` challenges:
73
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.
77
78 For `dns-01` challenges:
79
80 * DNS needs to be handled by a server that allows automatic provisioning of
81 TXT records
82
83 At the moment the GUI uses only the default ACME account.
84
85 .Example: Sample `pvenode` invocation for using Let's Encrypt certificates
86
87 ----
88 root@proxmox:~# pvenode acme account register default mail@example.invalid
89 Directory endpoints:
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)
92 2) Custom
93 Enter selection:
94 1
95
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
99
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'
104 Task OK
105 root@proxmox:~# pvenode acme account list
106 default
107 root@proxmox:~# pvenode config set --acme domains=example.invalid
108 root@proxmox:~# pvenode acme cert order
109 Loading ACME account details
110 Placing ACME order
111 Order URL: https://acme-staging-v02.api.letsencrypt.org/acme/order/xxxxxxxxxxxxxx
112
113 Getting authorization details from
114 'https://acme-staging-v02.api.letsencrypt.org/acme/authz/xxxxxxxxxxxxxxxxxxxxx-xxxxxxxxxxxxx-xxxxxxx'
115 ... pending!
116 Setting up webserver
117 Triggering validation
118 Sleeping for 5 seconds
119 Status is 'valid'!
120
121 All domains validated!
122
123 Creating CSR
124 Finalizing order
125 Checking order status
126 valid!
127
128 Downloading certificate
129 Setting pveproxy certificate and key
130 Restarting pveproxy
131 Task OK
132 ----
133
134 Switching from the `staging` to the regular ACME directory
135 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
136
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.
140
141 This procedure is also needed to change the default ACME account used in the GUI.
142
143 .Example: Changing the `default` ACME account from the `staging` to the regular directory
144
145 ----
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
150
151 Account information:
152 ID: xxxxxxx
153 Contact:
154 - mailto:example@proxmox.com
155 Creation date: 2018-07-31T08:41:44.54196435Z
156 Initial IP: 192.0.2.1
157 Status: valid
158
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'
161 Task OK
162
163 root@proxmox:~# pvenode acme account register default example@proxmox.com
164 Directory endpoints:
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)
167 2) Custom
168 Enter selection:
169 0
170
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
174
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'
179 Task OK
180 ----
181
182 Automatic renewal of ACME certificates
183 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
184
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.
189
190 Configuring DNS APIs for validation
191 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
192
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`
196 records via an API.
197
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
201 specific APIs.
202
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.
207
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`.
215
216 .Example: Setting up the OVH API for validating a domain
217
218 Note:: the account registration steps are the same no matter which plugins are used, and are not repeated here.
219 Note:: `OVH_AK` and `OVH_AS` need to be obtained from OVH according to the OVH API documentation
220
221 ----
222 root@proxmox:~# cat /path/to/api-token
223 OVH_AK=XXXXXXXXXXXXXXXX
224 OVH_AS=YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
225 root@proxmox:~# source /path/to/api-token
226 root@proxmox:~# curl -XPOST -H"X-Ovh-Application: $OVH_AK" -H "Content-type: application/json" \
227 https://eu.api.ovh.com/1.0/auth/credential -d '{
228 "accessRules": [
229 {"method": "GET","path": "/auth/time"},
230 {"method": "GET","path": "/domain"},
231 {"method": "GET","path": "/domain/zone/*"},
232 {"method": "GET","path": "/domain/zone/*/record"},
233 {"method": "POST","path": "/domain/zone/*/record"},
234 {"method": "POST","path": "/domain/zone/*/refresh"},
235 {"method": "PUT","path": "/domain/zone/*/record/"},
236 {"method": "DELETE","path": "/domain/zone/*/record/*"}
237 ]
238 }'
239 {"consumerKey":"ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ","state":"pendingValidation","validationUrl":"https://eu.api.ovh.com/auth/?credentialToken=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"}
240
241 (open validation URL and follow instructions to link Application Key with account/Consumer Key)
242
243 root@proxmox:~# echo "OVH_CK=ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" >> /path/to/api-token
244 root@proxmox:~# pvenode acme plugin add dns example_plugin --api ovh --data /path/to/api_token
245 root@proxmox:~# pvenode acme plugin config example_plugin
246 ┌────────┬──────────────────────────────────────────┐
247 │ key │ value │
248 ╞════════╪══════════════════════════════════════════╡
249 │ api │ ovh │
250 ├────────┼──────────────────────────────────────────┤
251 │ data │ OVH_AK=XXXXXXXXXXXXXXXX │
252 │ │ OVH_AS=YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY │
253 │ │ OVH_CK=ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ │
254 ├────────┼──────────────────────────────────────────┤
255 │ digest │ 867fcf556363ca1bea866863093fcab83edf47a1 │
256 ├────────┼──────────────────────────────────────────┤
257 │ plugin │ example_plugin │
258 ├────────┼──────────────────────────────────────────┤
259 │ type │ dns │
260 └────────┴──────────────────────────────────────────┘
261 root@proxmox:~# pvenode config set -acmedomain0 example.proxmox.com,plugin=example_plugin
262 root@proxmox:~# pvenode acme cert order
263 Loading ACME account details
264 Placing ACME order
265 Order URL: https://acme-staging-v02.api.letsencrypt.org/acme/order/11111111/22222222
266
267 Getting authorization details from 'https://acme-staging-v02.api.letsencrypt.org/acme/authz-v3/33333333'
268 The validation for example.proxmox.com is pending!
269 [Wed Apr 22 09:25:30 CEST 2020] Using OVH endpoint: ovh-eu
270 [Wed Apr 22 09:25:30 CEST 2020] Checking authentication
271 [Wed Apr 22 09:25:30 CEST 2020] Consumer key is ok.
272 [Wed Apr 22 09:25:31 CEST 2020] Adding record
273 [Wed Apr 22 09:25:32 CEST 2020] Added, sleep 10 seconds.
274 Add TXT record: _acme-challenge.example.proxmox.com
275 Triggering validation
276 Sleeping for 5 seconds
277 Status is 'valid'!
278 [Wed Apr 22 09:25:48 CEST 2020] Using OVH endpoint: ovh-eu
279 [Wed Apr 22 09:25:48 CEST 2020] Checking authentication
280 [Wed Apr 22 09:25:48 CEST 2020] Consumer key is ok.
281 Remove TXT record: _acme-challenge.example.proxmox.com
282
283 All domains validated!
284
285 Creating CSR
286 Checking order status
287 Order is ready, finalizing order
288 valid!
289
290 Downloading certificate
291 Setting pveproxy certificate and key
292 Restarting pveproxy
293 Task OK
294 ----