SSL: automatic renewal

DirectAdmin hosting — the certificate renews itself

A cron job fetches the fresh certificate daily and installs it in DirectAdmin through the API with a login key allowed only SSL. No password needed.

Renews by itself

Use this for hosting with the DirectAdmin panel: NIC.UA, Tucha and many others. You can tell DirectAdmin by the login address ending in :2222 and menu sections Account Manager, Advanced Features, System Info & Files.

How it works: once a day the script fetches the certificate from the link and, if it is new, hands it to the panel together with your key — exactly as you would paste it by hand in SSL Certificates. It signs in to the panel not with your password but with a separate Login Key that is allowed one action only: installing a certificate. We never ask for or see your panel or hosting password.

What you need

  • The certificate link from your account: https://api.zrazu.com/ssl-pull/zsp_YOUR_TOKEN.
  • The private key the certificate was ordered with. If the ZRAZU account generated the CSR, this is the file you saved back then.
  • The Cron Jobs section in the panel (most plans have it) or any Linux server with curl and openssl.
  • 15 minutes.

Step 1. First installation (if the certificate is not there yet)

In Account Manager → SSL Certificates choose Paste a pre-generated certificate and key, paste the key and then the certificate below it into the one field, and save. Then Click Here to paste a CA Root Certificate, paste the chain (chain.pem from the certificate card), tick Use a CA Cert and save. Details are in replacing the certificate in a panel by hand.

Step 2. A login key for SSL only

Account Manager → Login Keys → Create Key (in older skins, Login Keys on the main page):

  • Key Name — zrazu-ssl;
  • Key Value — click Random and copy the value: it is shown only once;
  • Expires On — Never (the key is needed every day);
  • Commands — tick only CMD_API_SSL; without this the key opens the whole panel;
  • Allowed IPs — the IP the script will run from. If it is the hosting's own cron, the server IP (System Info & Files → System Information). An empty field lets the key work from any address;
  • Current Password — your panel password, to confirm the creation.

If there is no Login Keys item, the hosting has turned the feature off. Then replacing by hand remains, and we remind you in advance.

Step 3. Files in the home directory

In System Info & Files → File Manager create a .zrazu folder in the home directory (above domains and public_html) and three files in it:

  • key.pem — the private key including the -----BEGIN … PRIVATE KEY----- and -----END … PRIVATE KEY----- lines;
  • login — one line in quotes: the panel user name, a colon, the login key value:
user = "USER_NAME:KEY_VALUE"
  • zrazu-ssl.sh — the script below. Change only the PANEL line in it: the address you sign in to the panel with, including :2222, without a path.

Set permissions 600 on all three files (Permissions in File Manager): only your account can read them.

#!/bin/sh
# ZRAZU: updates the SSL certificate in DirectAdmin using the personal link. Run by cron once a day.
# The key stays with you; the certificate goes to the panel only if it matches the key.
set -eu
PATH=/usr/local/bin:/usr/bin:/bin
PULL="https://api.zrazu.com/ssl-pull/zsp_YOUR_TOKEN"
DOMAIN="example.com"
PANEL="https://server.example.com:2222"
DIR="$HOME/.zrazu"
KEY="$DIR/key.pem"
# The user name and login key live in a file, not on the command line, so other users of the server cannot see them.
LOGIN="$DIR/login"

umask 077
WORK=$(mktemp -d)
trap 'rm -rf "$WORK"' EXIT
TAG=""
[ -f "$DIR/$DOMAIN.etag" ] && TAG=$(cat "$DIR/$DOMAIN.etag")
CODE=$(curl -fsS --retry 3 --max-time 60 -o "$WORK/full.pem" -D "$WORK/hdr" -w '%{http_code}' -H "If-None-Match: $TAG" "$PULL/fullchain.pem")
if [ "$CODE" = "304" ]; then echo "ZRAZU: certificate unchanged"; exit 0; fi
grep -q "BEGIN CERTIFICATE" "$WORK/full.pem" || { echo "ZRAZU: the link does not return a certificate" >&2; exit 1; }
# The first certificate in the file is the site's, the rest is the chain.
awk -v d="$WORK" '/BEGIN CERTIFICATE/{n++} n==1{print > (d "/cert.pem")} n>1{print > (d "/chain.pem")}' "$WORK/full.pem"
if [ "$(openssl x509 -in "$WORK/cert.pem" -noout -pubkey | openssl sha256)" != "$(openssl pkey -in "$KEY" -pubout | openssl sha256)" ]; then
  echo "ZRAZU: certificate was issued for a different key — changing nothing, put the new key in $KEY" >&2
  exit 1
fi
openssl x509 -in "$WORK/cert.pem" -noout -checkend 0 >/dev/null || { echo "ZRAZU: certificate has already expired" >&2; exit 1; }
# The panel takes the key and certificate in one field: the key first, the certificate below it.
cat "$KEY" "$WORK/cert.pem" > "$WORK/paste.pem"
api() {
  OUT=$(curl -sS --max-time 60 -K "$LOGIN" "$PANEL/CMD_API_SSL" -d "domain=$DOMAIN" -d action=save "$@") || true
  case "$OUT" in
    error=0*) ;;
    *) echo "ZRAZU: the panel refused: $(printf '%s' "$OUT" | head -c 300)" >&2; exit 1 ;;
  esac
}
api -d type=paste -d request=no --data-urlencode "certificate@$WORK/paste.pem"
if [ -s "$WORK/chain.pem" ]; then
  api -d type=cacert -d active=yes --data-urlencode "cacert@$WORK/chain.pem"
fi
# The tag is written only after the panel accepted: if it did not, the next run tries again.
sed -n 's/^[Ee][Tt][Aa][Gg]: *//p' "$WORK/hdr" | tr -d '\r' > "$DIR/$DOMAIN.etag"
echo "ZRAZU: new certificate installed, valid until $(openssl x509 -in "$WORK/cert.pem" -noout -enddate | cut -d= -f2)"

The script changes nothing if the certificate has not changed, if the link does not return a certificate, or if the certificate does not match your key or has expired. The panel answers error=0 when it has accepted the certificate; any other answer is an error, and the script tries again the next day.

Step 4. Schedule

Advanced Features → Cron Jobs → Create Cron Job: Minute 17, Hour 4, the other fields *, command:

/bin/sh $HOME/.zrazu/zrazu-ssl.sh >> $HOME/.zrazu/log.txt 2>&1

Any minute will do — preferably not exactly 00. To check right away, temporarily set the time two minutes ahead, and after the run open .zrazu/log.txt: it should say "new certificate installed".

Your own Linux server instead of the hosting's cron: the same script with HOME pointing to your directory, a crontab -e line 17 4 * * * /bin/sh $HOME/.zrazu/zrazu-ssl.sh >> $HOME/.zrazu/log.txt 2>&1, and that server's IP in the key's Allowed IPs.

Check

Open https://zrazu.com/tools/ssl/example.com/ — it should show the ZRAZU certificate with the new expiry date.

So the hosting does not replace our certificate

If the domain has the free certificate on (Free & automatic certificate from Let's Encrypt in SSL Certificates), the panel renews it by itself and may replace ours. The script installs the certificate as a pasted one, and the panel stops renewing the free one; after the first run, check that the pasted certificate is selected in SSL Certificates.

If it did not work

This is a new guide: we have not yet tested it on a live panel. If it did not work, write to us in your account (Support) or by email with the text from .zrazu/log.txt, and we fix the guide the same day.

  • "the panel refused" with HTML saying Cannot Execute Your Request — the login key has no right to CMD_API_SSL, or the run comes from an IP outside Allowed IPs. Check step 2.
  • error=1 and text=… — the panel explains the reason in text: most often the domain is written differently from the panel (without *. and without www).
  • curl: (60) or SSL certificate problem — PANEL holds an address the panel has a different certificate for. Copy the address exactly from the browser bar when you sign in to the panel.
  • openssl: not found — this hosting has no openssl; run the script from your own Linux server.
  • curl: (22) … 404 — the link is disabled or replaced: create a new one in the certificate card and replace the PULL line.

This page in Markdown