Trigger (run custom script) when ACME certificate was renewed?

fdcastel

Member
Sep 28, 2021
24
4
8
Short version:

I have ACME certificates configured in my Proxmox. And everything is working perfectly.

Now, how can I run a custom script when the certificate is renewed?



Long version:

In PBS documentation, we learn that we can use:
Bash:
NODE=$(hostname)
cp /etc/pve/nodes/${NODE}/pveproxy-ssl.pem /etc/proxmox-backup/proxy.pem
cp /etc/pve/nodes/${NODE}/pveproxy-ssl.key /etc/proxmox-backup/proxy.key
chmod 640 /etc/proxmox-backup/proxy.key /etc/proxmox-backup/proxy.pem
chgrp backup /etc/proxmox-backup/proxy.key /etc/proxmox-backup/proxy.pem
systemctl reload proxmox-backup-proxy.service
to share ACME certificates between a PVE and a PBS installed on the same server. Nice!

Problem is, this same documentation also left an "exercise for the reader":

You only need to schedule the copying of the certificate and key after each renewal (e.g. by creating an appropriate cronjob or systemd-timer)

At the risk of appearing obtuse... How can I do this? ;)
 
Or, as an alternative solution, can I create a symlink between

/etc/pve/nodes/${NODE}/pveproxy-ssl.{pem|key}

and

/etc/proxmox-backup/proxy.{pem|key}

?
 
Studying the code, to the best of my understanding:

- There is a pve-daily-update.service;
- Which runs the script /usr/bin/pveupdate (once a day, around 1AM, with a randomized offset of 5h);
- Which may or may not request an ACME certificate renew, based on elapsed days since the last renew.

As a last resort, I can change the code for /usr/bin/pveupdate. But of course I'm looking for other non-intrusive ways before taking this path.
 
Or, as an alternative solution, can I create a symlink between

/etc/pve/nodes/${NODE}/pveproxy-ssl.{pem|key}

and

/etc/proxmox-backup/proxy.{pem|key}

?

This didn't work. I tried with:

Bash:
NODE=$(hostname)
ln -sf /etc/pve/nodes/${NODE}/pveproxy-ssl.pem /etc/proxmox-backup/proxy.pem
ln -sf /etc/pve/nodes/${NODE}/pveproxy-ssl.key /etc/proxmox-backup/proxy.key
chgrp -h backup /etc/proxmox-backup/proxy.key /etc/proxmox-backup/proxy.pem
systemctl reload proxmox-backup-proxy.service

But then the proxmox-backup-proxy.service service won't start:

Code:
proxmox-backup-proxy[29160]: Error: failed to set tls acceptor private key file
proxmox-backup-proxy[29160]: Caused by:
proxmox-backup-proxy[29160]:     error:8000000D:system library:file_ctrl:reason(2):../crypto/bio/bss_file.c:297:calling fopen(/etc/proxmox-backup/proxy.key, r), error:10080002:BIO routines:file_ctrl:system lib:../crypto/bio/bss_file.c:300:, error:0A080002:SSL routines:SSL_CTX_use_PrivateKey_file:system lib:../ssl/ssl_rsa.c:367:
systemd[1]: proxmox-backup-proxy.service: Main process exited, code=exited, status=1/FAILURE
 
For now, I'm using a daily cron job:

Bash:
cat > /etc/cron.daily/update-pbs-certificates <<'EOF'
#!/bin/bash

diff /etc/pve/nodes/$HOSTNAME/pveproxy-ssl.pem /etc/proxmox-backup/proxy.pem
if [ $? -ne 1 ]; then
    cp /etc/pve/nodes/$HOSTNAME/pveproxy-ssl.pem /etc/proxmox-backup/proxy.pem
    cp /etc/pve/nodes/$HOSTNAME/pveproxy-ssl.key /etc/proxmox-backup/proxy.key

    chmod 640 /etc/proxmox-backup/proxy.key /etc/proxmox-backup/proxy.pem
    chgrp backup /etc/proxmox-backup/proxy.key /etc/proxmox-backup/proxy.pem

    systemctl reload proxmox-backup-proxy.service
fi
EOF

chmod +x /etc/cron.daily/update-pbs-certificates

However, if there is a better way to detect when the renewal kicks in, I would like to know.

Also: Update the PBS documentation.
 
Last edited:
I think I maybe have a little bit nice solution. Just create these two systemd unit files

Bash:
root@horst:/etc/systemd/system# cat copy_ssl_cert_pve2pbs.service
[Unit]
Description=Copy the PVE ssl certificate to the PBS location after it's updates by Let's encrypt

[Service]
Type=oneshot
ExecStartPre=/usr/bin/cp /etc/pve/nodes/%H/pveproxy-ssl.pem /etc/proxmox-backup/proxy.pem
ExecStartPre=/usr/bin/cp /etc/pve/nodes/%H/pveproxy-ssl.key /etc/proxmox-backup/proxy.key
ExecStartPre=/usr/bin/chmod 640 /etc/proxmox-backup/proxy.pem
ExecStartPre=/usr/bin/chmod 640 /etc/proxmox-backup/proxy.key
ExecStartPre=/usr/bin/chgrp backup /etc/proxmox-backup/proxy.pem
ExecStartPre=/usr/bin/chgrp backup /etc/proxmox-backup/proxy.key
ExecStart=/usr/bin/systemctl reload proxmox-backup-proxy.service

[Install]
WantedBy=multi-user.target

Bash:
cat copy_ssl_cert_pve2pbs.path
[Unit]
Description=Copy the PVE ssl certificate to the PBS location after it's updates by Let's encrypt

[Path]
PathChanged=/etc/pve/nodes/%H/pveproxy-ssl.pem
Unit=copy_ssl_cert_pve2pbs.service

[Install]
WantedBy=multi-user.target

Then start the service with: systemctl enable copy_ssl_cert_pve2pbs.{path,service} and then start the watcher service with systemctl start copy_ssl_cert_pve2pbs.path. As soon as the PVE SSL certificate get's updated the service is invoked and the PBS system gets also the new certificate. Using the %H syntax of systemd makes the units work on every system since it gets the hostname from the system itself.