---
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
```