mirror of
https://git.proxmox.com/git/pve-docs
synced 2025-05-28 17:40:16 +00:00
certs: extend ACME section with DNS/plugin info
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
This commit is contained in:
parent
c1bcd1410f
commit
0b447f1cc8
@ -54,18 +54,31 @@ interface with Let's Encrypt for easy setup of trusted TLS certificates which
|
||||
are accepted out of the box on most modern operating systems and browsers.
|
||||
|
||||
Currently the two ACME endpoints implemented are Let's Encrypt (LE) and its
|
||||
staging environment (see https://letsencrypt.org), both using the standalone
|
||||
HTTP challenge.
|
||||
staging environment (see https://letsencrypt.org). Our ACME client supports
|
||||
validation of `http-01` challenges using a built-in webserver and validation of
|
||||
`dns-01` challenges using a DNS plugin.
|
||||
|
||||
Because of https://letsencrypt.org/docs/rate-limits/[rate-limits] you should use
|
||||
LE `staging` for experiments.
|
||||
|
||||
ACME Plugin configuration is stored in `/etc/pve/priv/acme/plugins.cfg`. There
|
||||
is always an implicitly configured `standalone` plugin for validating `http-01`
|
||||
challenges via the built-in webserver spawned on port 80.
|
||||
|
||||
There are a few prerequisites to use Let's Encrypt:
|
||||
|
||||
1. **Port 80** of the node needs to be reachable from the internet.
|
||||
2. There **must** be no other listener on port 80.
|
||||
3. The requested (sub)domain needs to resolve to a public IP of the Node.
|
||||
4. You have to accept the ToS of Let's Encrypt.
|
||||
* You have to accept the ToS of Let's Encrypt to register an account.
|
||||
|
||||
For `http-01` challenges:
|
||||
|
||||
* **Port 80** of the node needs to be reachable from the internet.
|
||||
* There **must** be no other listener on port 80.
|
||||
* The requested (sub)domain needs to resolve to a public IP of the Node.
|
||||
|
||||
For `dns-01` challenges:
|
||||
|
||||
* DNS needs to be handled by a server that allows automatic provisioning of
|
||||
TXT records
|
||||
|
||||
At the moment the GUI uses only the default ACME account.
|
||||
|
||||
@ -173,3 +186,109 @@ If a node has been successfully configured with an ACME-provided certificate
|
||||
(either via pvenode or via the GUI), the certificate will be automatically
|
||||
renewed by the pve-daily-update.service. Currently, renewal will be attempted
|
||||
if the certificate has expired already, or will expire in the next 30 days.
|
||||
|
||||
Configuring DNS APIs for validation
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
On systems where external access for validation via the `http-01` method is
|
||||
not possible or desired, it is possible to use the `dns-01` validation method.
|
||||
This validation method requires a DNS server that allows provisioning of `TXT`
|
||||
records via an API.
|
||||
|
||||
{PVE} re-uses the DNS plugins developed for the `acme.sh`
|
||||
footnote:[acme.sh https://github.com/acmesh-official/acme.sh]
|
||||
project, please refer to its documentation for details on configuration of
|
||||
specific APIs.
|
||||
|
||||
Combining `http-01` and `dns-01` validation is possible in case your node is
|
||||
reachable via multiple domains with different requirements / DNS provisioning
|
||||
capabilities. Mixing DNS APIs from multiple providers or instances is also
|
||||
possible by specifying different plugin instances per domain.
|
||||
|
||||
A special `alias` mode can be used to handle the validation on a different
|
||||
domain/DNS server, in case your primary/real DNS does not support provisioning
|
||||
via an API. Manually set up a permanent `CNAME` record for
|
||||
`_acme-challenge.domain1.example` pointing to `_acme-challenge.domain2.example`
|
||||
and set the `alias` property in the {PVE} node configuration file to
|
||||
`domain2.example` to allow the DNS server of `domain2.example` to validate all
|
||||
challenges for `domain1.example`.
|
||||
|
||||
.Example: Setting up the OVH API for validating a domain
|
||||
|
||||
Note:: the account registration steps are the same no matter which plugins are used, and are not repeated here.
|
||||
Note:: `OVH_AK` and `OVH_AS` need to be obtained from OVH according to the OVH API documentation
|
||||
|
||||
----
|
||||
root@proxmox:~# cat /path/to/api-token
|
||||
OVH_AK=XXXXXXXXXXXXXXXX
|
||||
OVH_AS=YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
|
||||
root@proxmox:~# source /path/to/api-token
|
||||
root@proxmox:~# curl -XPOST -H"X-Ovh-Application: $OVH_AK" -H "Content-type: application/json" \
|
||||
https://eu.api.ovh.com/1.0/auth/credential -d '{
|
||||
"accessRules": [
|
||||
{"method": "GET","path": "/auth/time"},
|
||||
{"method": "GET","path": "/domain"},
|
||||
{"method": "GET","path": "/domain/zone/*"},
|
||||
{"method": "GET","path": "/domain/zone/*/record"},
|
||||
{"method": "POST","path": "/domain/zone/*/record"},
|
||||
{"method": "POST","path": "/domain/zone/*/refresh"},
|
||||
{"method": "PUT","path": "/domain/zone/*/record/"},
|
||||
{"method": "DELETE","path": "/domain/zone/*/record/*"}
|
||||
]
|
||||
}'
|
||||
{"consumerKey":"ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ","state":"pendingValidation","validationUrl":"https://eu.api.ovh.com/auth/?credentialToken=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"}
|
||||
|
||||
(open validation URL and follow instructions to link Application Key with account/Consumer Key)
|
||||
|
||||
root@proxmox:~# echo "OVH_CK=ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" >> /path/to/api-token
|
||||
root@proxmox:~# pvenode acme plugin add dns example_plugin --api ovh --data /path/to/api_token
|
||||
root@proxmox:~# pvenode acme plugin config example_plugin
|
||||
┌────────┬──────────────────────────────────────────┐
|
||||
│ key │ value │
|
||||
╞════════╪══════════════════════════════════════════╡
|
||||
│ api │ ovh │
|
||||
├────────┼──────────────────────────────────────────┤
|
||||
│ data │ OVH_AK=XXXXXXXXXXXXXXXX │
|
||||
│ │ OVH_AS=YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY │
|
||||
│ │ OVH_CK=ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ │
|
||||
├────────┼──────────────────────────────────────────┤
|
||||
│ digest │ 867fcf556363ca1bea866863093fcab83edf47a1 │
|
||||
├────────┼──────────────────────────────────────────┤
|
||||
│ plugin │ example_plugin │
|
||||
├────────┼──────────────────────────────────────────┤
|
||||
│ type │ dns │
|
||||
└────────┴──────────────────────────────────────────┘
|
||||
root@proxmox:~# pvenode config set -acmedomain0 example.proxmox.com,plugin=example_plugin
|
||||
root@proxmox:~# pvenode acme cert order
|
||||
Loading ACME account details
|
||||
Placing ACME order
|
||||
Order URL: https://acme-staging-v02.api.letsencrypt.org/acme/order/11111111/22222222
|
||||
|
||||
Getting authorization details from 'https://acme-staging-v02.api.letsencrypt.org/acme/authz-v3/33333333'
|
||||
The validation for example.proxmox.com is pending!
|
||||
[Wed Apr 22 09:25:30 CEST 2020] Using OVH endpoint: ovh-eu
|
||||
[Wed Apr 22 09:25:30 CEST 2020] Checking authentication
|
||||
[Wed Apr 22 09:25:30 CEST 2020] Consumer key is ok.
|
||||
[Wed Apr 22 09:25:31 CEST 2020] Adding record
|
||||
[Wed Apr 22 09:25:32 CEST 2020] Added, sleep 10 seconds.
|
||||
Add TXT record: _acme-challenge.example.proxmox.com
|
||||
Triggering validation
|
||||
Sleeping for 5 seconds
|
||||
Status is 'valid'!
|
||||
[Wed Apr 22 09:25:48 CEST 2020] Using OVH endpoint: ovh-eu
|
||||
[Wed Apr 22 09:25:48 CEST 2020] Checking authentication
|
||||
[Wed Apr 22 09:25:48 CEST 2020] Consumer key is ok.
|
||||
Remove TXT record: _acme-challenge.example.proxmox.com
|
||||
|
||||
All domains validated!
|
||||
|
||||
Creating CSR
|
||||
Checking order status
|
||||
Order is ready, finalizing order
|
||||
valid!
|
||||
|
||||
Downloading certificate
|
||||
Setting pveproxy certificate and key
|
||||
Restarting pveproxy
|
||||
Task OK
|
||||
----
|
||||
|
Loading…
Reference in New Issue
Block a user