For the steps behind setting up a Tailscale derper service on Tencent Cloud, check out the related article.

Let’s Encrypt certificates only last three months now, so the derper certificate and key go stale pretty quickly. To stop doing this by hand, I’m going to polish up the Tailscale derper service I set up earlier.
My first try was to drop the re-copy step for the certificate and key straight into derper’s startup file, so it would run on every restart. But derper isn’t started as root, and the website files belong to root, so once I wired the copy step in, restarting derper threw permission errors. Moving the copy step in front of the user directive didn’t get rid of the problem either.

For safety, we don’t directly elevate the user running derper to root, and we’re not touching the owner or permissions of the website files either. With that as the ground rule, I set up a fresh script under my own user’s path to do the certificate and key copying.
sudo vim 自己的路径/derperCertSync.sh and add the update operation.
sudo vim 自己的路径/derper-cert-sync.sh

#!/bin/bash
sudo cp "自己的路径/fullchain.pem" "自己的路径/derper/自己域名.crt"
sudo cp "自己的路径/privkey.pem" "自己的路径/derper/自己域名.key"
sudo chown 具体用户: 具体用户 "自己的路径/derper/自己域名.crt" "自己的路径/derper/自己域名.key"
One thing to watch out for: the paths in the script must start from the root directory /home!!!! No relative paths, and nothing starting with ~ instead!!!
Once that’s done, change the script’s permissions.
sudo chmod +x 自己的路径/derper-cert-sync.sh
Next up, let’s configure the derper service’s startup file.
sudo vim /etc/systemd/system/derper.service
Before the user directive, add the line that runs the script to copy the certificates,
ExecStartPre=自己的路径/derper-cert-sync.sh

From now on the script runs and updates things every time the derper service restarts. To keep the certificate and key from expiring because the server sat there too long without an update, I also gave the derper service a timeout restart — around 30 days is plenty — and tossed in a restart-on-failure while I was at it.
Restart=on-failure
RestartSec=5
RuntimeMaxSec=2592000
After the changes, you need to refresh derper’s configuration by hand.
sudo systemctl daemon-reload
Finally, restart the derper service and that’s it.
sudo systemctl restart derper
In derper’s status you can see the script being called and run as root, then exiting as soon as the update is finished. The session opened and session closed you see there are just the script starting up and wrapping up.
systemctl status derper

No more “Permission denied” style errors in the derper service log. The script gets called, the update runs, and the permissions of the different users stay properly separated, which is a nice bump in security.
Last, let’s see whether the timeout logic actually took. The timeout comes out at a bit over 4 weeks, so it’s configured correctly.
systemctl show derper -p RuntimeMaxUSec -p ExecMainStartTimestamp

Open the site’s derper page in a browser, click the encryption indicator and you get connection secure, certificate valid — and the certificate’s validity dates have been updated too.



Published on July 27, 2025.
