ansible-role-proxmox
ansible-role-proxmox copied to clipboard
Support in-PVE Let's Encrypt setup
PVE 5.2 introduced ACME support within PVE.
https://pve.proxmox.com/wiki/Certificate_Management
An ACME management module can be created to manage ACME registration and certificate.
Process I used to generate cert:
~# pvesh create /cluster/acme/account -contact $email -tos_url https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf
Generating ACME account key..
Registering ACME account..
Registration successful, account URL: 'https://acme-v02.api.letsencrypt.org/acme/acct/X'
200 OK
~# pvesh set /nodes/maika/config -acme domains=$fqdn
200 OK
~# pvesh create /nodes/maika/certificates/acme/certificate -force
Loading ACME account details
Placing ACME order
Order URL: https://acme-v02.api.letsencrypt.org/acme/order/X/X
Getting authorization details from 'https://acme-v02.api.letsencrypt.org/acme/authz/XXXXXXXXXXXXX'
... pending!
Setting up webserver
Triggering validation
Sleeping for 5 seconds
Status is 'valid'!
All domains validated!
Creating CSR
Finalizing order
Checking order status
valid!
Downloading certificate
Setting pveproxy certificate and key
Restarting pveproxy
200 OK
UPID:XXX
Note that failure returns 200 OK:
Triggering validation
Sleeping for 5 seconds
Status is still 'pending', trying again in 30 seconds
validating challenge 'https://acme-v02.api.letsencrypt.org/acme/authz/XXXXXXXX' failed
200 OK
Documentation should note that port 80 must be accessible from the Internet (above happened to me because firewall dropped connections) and nothing else should be running on port 80.
For the record, I think I had this working in the 'feature/letsencrypt` branch back in September but haven't merged it yet because of distractions.
Have a look at that
- name: Install Proxmox ACME Dependencies (Python2)
apt:
name: ['python-pexpect']
state: present
update_cache: yes
- name: Install Proxmox ACME Dependencies (Python3)
apt:
name: ['python3-pexpect']
state: present
update_cache: yes
- name: Verify ACME account
command: pvenode acme account list
register: __acme_account
- name: Create ACME Account
expect:
command: pvenode acme account register default {{ pve_acme_email_address }} --directory https://acme-v02.api.letsencrypt.org/directory
responses:
"Do you agree to the above terms": y
when: __acme_account.stdout is not search('default')
- name: Define ACME Domains
command: pvenode config set --acme domains={{ ansible_fqdn }}
when: __acme_account.stdout is not search('default')
- name: Register ACME Domains
command: pvenode acme cert order
when: __acme_account.stdout is not search('default')
The first two tasks depends on the interpreter, you want to use. I'd like python3, but default seems to be python2. For staging another URL must be used, it could be a default value and overwritten. Also pve_acme_email_address
and ansible_fqdn
must be defined.
I want to avoid the use of command
calls here as it's difficult to guarantee that they're idempotent. If you take a look at https://github.com/lae/ansible-role-proxmox/tree/feature/letsencrypt you'll see that I currently have a WIP proxmox_acme_account
module and would prefer that to be used.
I think the TOS is agreed to without using expect
in that branch so I don't think it's actually necessary to install python-pexpect
, but it's been a while. Either way, it's not exactly a Proxmox dependency here but an Ansible dependency - and dependencies in general would go into the identify_needed_packages.yml
tasks file (you can add a when
conditional to test whether ansible_python
is 3 or 2 iirc)
Do you know, what steps are missing in the branch? I'm not that good in Python but maybe I can help. The tasks above are working, but you comment about idempotent is correct.
It's been a while (dang...almost 2 years...) so I don't really remember. The branch will need to be rebased on develop first of all.
A quick perusal through the script and I think it only creates an ACME account, but doesn't actually register a certificate. I think my intention there might have been to have split modules for account management and certificate management (i.e. 2 different modules with different parameters). So at least that step is missing, and this might be the only thing judging from your tasks list.
I checked that today. There is some kind of reason, why you didn't go forward. It is easy via pvesh to manage the ACME account itself. But the domain management is not really possible with pvesh. There is:
# pvesh get nodes/node1/config
┌────────┬──────────────────────────────────────────┐
│ key │ value │
╞════════╪══════════════════════════════════════════╡
│ acme │ domains=node1.fqdn │
├────────┼──────────────────────────────────────────┤
│ digest │ 123c1af808c02d6b9eedc3af75c12a4165c65abc │
└────────┴──────────────────────────────────────────┘
but setting that value has no effect. You need to run also pvenode acme cert order
I've updated the branch feature/lets_encrypt. I've used it for a while via pvesh and it works like a charme.