Add Automatic Certificate Management Environment (ACME) to ProxmoxVE (Let’sEncrypt) via DNS.
Most of the time, http authentication for the ACME protocol is perfect. But since PVE is an infrastructure device, you might not have the option nor want to expose its port 80 on Internet, voiding the http validation.
Remains the DNS validation. I write those lines because I struggled with the (lack of) documentation, but it’s probably very easy.
First, ensure you’re DNS provider is supported by listing plugins:
ls -lh /usr/share/proxmox-acme/dnsapi # ls -lh /usr/share/proxmox-acme/dnsapi |grep gandi -rw-r--r-- 1 root root 5.2K Apr 25 18:07 dns_gandi_livedns.sh
In my case, it’s Gandi, and the Gandi plugin is directly available in PVE (no need to install anything).
You must first create a Gandi token from their Web UI, then ensure it’s written in a file like this:
# cat /etc/pve/gandi_token GANDI_LIVEDNS_TOKEN=9034619778cf4fac009fa1a35d3c0aeb
After that, register the new plugin.
pvenode acme plugin add dns gandi_livedns --api gandi_livedns --data /etc/pve/gandi_token
Go the the Web UI, on one of the node, System->Certificates
Check the configuration:
root@pve1:~# pvenode acme plugin config gandi_livedns ┌────────┬──────────────────────────────────────────────────────────────┐ │ key │ value │ ╞════════╪══════════════════════════════════════════════════════════════╡ │ api │ gandi_livedns │ ├────────┼──────────────────────────────────────────────────────────────┤ │ data │ GANDI_LIVEDNS_TOKEN=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx │ ├────────┼──────────────────────────────────────────────────────────────┤ │ digest │ 92320581a99992036cfda042d40282853d613984 │ ├────────┼──────────────────────────────────────────────────────────────┤ │ plugin │ gandi_livedns │ ├────────┼──────────────────────────────────────────────────────────────┤ │ type │ dns │ └────────┴──────────────────────────────────────────────────────────────┘
In the ACME section, add a new entry, select DNS and the newly installed plugin
Create, then click on “Order Certificate Now”. You should see:
Loading ACME account details Placing ACME order Order URL: https://acme-v02.api.letsencrypt.org/acme/order/xxx/xxx Getting authorization details from 'https://acme-v02.api.letsencrypt.org/acme/authz-v3/xx' The validation for pve2.pivert.org is pending! [Tue Oct 22 23:21:07 CEST 2024] Adding record success Add TXT record: _acme-challenge.pve2.pivert.org Sleeping 30 seconds to wait for TXT record propagation Triggering validation Sleeping for 5 seconds Status is 'valid', domain 'pve2.pivert.org' OK! [Tue Oct 22 23:21:50 CEST 2024] Removing record success Remove TXT record: _acme-challenge.pve2.pivert.org 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
Then proceed for each host in the cluster.