--- tags: server --- # Certificate Renewal on PVE with wildcards Make sure PVE does _not_ renew certificates on its own. All ACME plugins should be disabled. Install certbot: ``` apt install python3-certbot-dns-cloudflare ``` Create `/etc/cloudflare.ini` and set the Cloudflare API token: ```ini # Cloudflare API token used by Certbot dns_cloudflare_api_token = ... ``` Make this file readable for `root` only: ``` chmod 0600 /etc/cloudflare.ini ``` Create a service file `certbot-renew.service` to automate the update. Unfortunately, the PVE FUSE configuration file system does not allow symlinks. That is why we need to copy the certificate. ```ini [Unit] Description=Certbot Renew [Service] Type=simple ExecStart=/usr/bin/certbot certonly -n --agree-tos -m kiesow@elan-ev.de --dns-cloudflare --dns-cloudflare-credentials /etc/cloudflare.ini -d vm-test.elan.codes -d *.vm-test.elan.codes ExecStopPost=/usr/bin/cp /etc/letsencrypt/live/vm-test.elan.codes/privkey.pem /etc/pve/local/pveproxy-ssl.key ExecStopPost=/usr/bin/cp /etc/letsencrypt/live/vm-test.elan.codes/fullchain.pem /etc/pve/local/pveproxy-ssl.pem ExecStopPost=-/bin/systemctl reload nginx.service ExecStopPost=-/bin/systemctl reload pveproxy.service ``` Deploy this to `/etc/systemd/system/certbot-renew.service` and check if it works: ``` systemctl start certbot-renew.service systemctl status certbot-renew.service ``` Create a timer to automatically trigger this service: ```ini [Unit] Description=Certbot Renew Scheduling. [Timer] OnCalendar=*-*-* 01:30:00 [Install] WantedBy=multi-user.target ``` Deploy this to `/etc/systemd/system/certbot-renew.timer` and enable the timer: ``` systemctl start certbot-renew.timer systemctl enable certbot-renew.timer systemctl list-timers ```