SSL: automatic renewal
Cloudflare in front of your site
Site behind Cloudflare: on Free and Pro our certificate sits on your server; on Business and Enterprise a script renews it in Cloudflare via the API.
Renews by itself
If your site works through the Cloudflare proxy (the orange cloud in DNS), visitors see the certificate served by Cloudflare, not by your server.
Free and Pro plans
Cloudflare issues a free certificate for visitors itself, and on these plans you cannot upload your own there. Our certificate is needed on your server, so that the Cloudflare → server connection is also protected and verified (the SSL/TLS → Full (strict) mode). Set up automatic renewal on the server using the guide for it: Linux server, cPanel, Kubernetes.
Business and Enterprise plans — your own certificate in Cloudflare
Here you can upload your own certificate (SSL/TLS → Edge Certificates → Upload Custom SSL Certificate), but Cloudflare does not renew it. The script below fetches the fresh certificate from the link once a day and updates it in Cloudflare through the API. Run it on any Linux server with curl and openssl, usually the one behind Cloudflare.
What you need
- The certificate link from your account:
https://api.zrazu.com/ssl-pull/zsp_YOUR_TOKEN. - A private key without a password. An ECDSA key must not have an
EC PARAMETERSblock. - Zone ID — on your domain's page in Cloudflare, bottom right (API → Zone ID).
- Certificate ID: SSL/TLS → Edge Certificates, your certificate's row → expand → Certificate ID. If there is no certificate yet, first upload it manually (the button above) from
https://api.zrazu.com/ssl-pull/zsp_YOUR_TOKEN/fullchain.pemwith your key. - API token: My Profile → API Tokens → Create Token → Create Custom Token → permission Zone → SSL and Certificates → Edit, Zone Resources — only this domain.
Step 1. Key and script on the server
sudo mkdir -p /etc/ssl/zrazu/example.com
sudo chmod 700 /etc/ssl/zrazu/example.com
sudo nano /etc/ssl/zrazu/example.com/key.pem
sudo nano /usr/local/bin/zrazu-cloudflare-example.com.shPaste the key into the first file and the script below into the second, with your ZONE, CERT_ID and TOKEN.
#!/bin/sh
# ZRAZU: updates your own certificate in Cloudflare using the personal link. Run by cron once a day.
set -eu
PULL="https://api.zrazu.com/ssl-pull/zsp_YOUR_TOKEN"
DIR="/etc/ssl/zrazu/example.com"
ZONE="ZONE_ID"
CERT_ID="CERTIFICATE_ID"
TOKEN="API_TOKEN"
API="https://api.cloudflare.com/client/v4/zones/$ZONE/custom_certificates"
umask 077
cd "$DIR"
[ -f cert_id ] || echo "$CERT_ID" > cert_id
curl -fsS --retry 3 --max-time 60 -o new.pem "$PULL/fullchain.pem"
grep -q "BEGIN CERTIFICATE" new.pem || { echo "ZRAZU: the link does not return a certificate"; exit 1; }
if [ -f applied.pem ] && cmp -s new.pem applied.pem; then echo "ZRAZU: certificate unchanged"; exit 0; fi
cert_pub=$(openssl x509 -in new.pem -noout -pubkey | openssl sha256)
key_pub=$(openssl pkey -in key.pem -pubout | openssl sha256)
[ "$cert_pub" = "$key_pub" ] || { echo "ZRAZU: certificate was issued for a different key — put the new key.pem in place"; exit 1; }
json() { awk '{ gsub(/\\/, "\\\\"); gsub(/"/, "\\\""); printf "%s\\n", $0 }' "$1"; }
printf '{"certificate":"%s","private_key":"%s","bundle_method":"force"}' "$(json new.pem)" "$(json key.pem)" > body.json
out=$(curl -sS -X PATCH "$API/$(cat cert_id)" -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" --data @body.json)
rm -f body.json
if printf '%s' "$out" | grep -q '"success": *true'; then
id=$(printf '%s' "$out" | tr -d '\n' | grep -o '"result": *{.*' | grep -o '"id": *"[0-9a-f]*"' | head -n 1 | cut -d'"' -f4)
[ -z "$id" ] || echo "$id" > cert_id
mv -f new.pem applied.pem
echo "ZRAZU: certificate updated in Cloudflare"
else
echo "ZRAZU: Cloudflare refused:"
printf '%s\n' "$out"
exit 1
fiCloudflare may give the updated certificate a new ID. The script remembers it in the cert_id file by itself.
Step 2. First run and schedule
sudo chmod 700 /usr/local/bin/zrazu-cloudflare-example.com.sh
sudo /usr/local/bin/zrazu-cloudflare-example.com.sh
echo "23 4 * * * root /usr/local/bin/zrazu-cloudflare-example.com.sh >> /var/log/zrazu-ssl.log 2>&1" | sudo tee /etc/cron.d/zrazu-cloudflare-example.comCheck
- The first run prints "certificate updated in Cloudflare", later runs print "certificate unchanged".
- SSL/TLS → Edge Certificates — your certificate shows a new Expires On date.
- Site: https://zrazu.com/tools/ssl/example.com/.
If it did not work
Authentication error— the token lacks the SSL and Certificates → Edit permission or is not for this domain.custom certificate not found— wrongCERT_ID: delete the file/etc/ssl/zrazu/example.com/cert_id, fix the line in the script and run it again.- "certificate was issued for a different key" — the certificate was reissued with a new key: replace
key.pem.