SSL: автоматическое обновление

Cloudflare перед сайтом

Сайт за Cloudflare: на Free и Pro наш сертификат стоит на вашем сервере, на Business и Enterprise — обновляется в Cloudflare скриптом через API.

Обновляется сам

Если сайт работает через прокси Cloudflare (оранжевое облачко в DNS), посетители видят сертификат, который отдаёт Cloudflare, а не ваш сервер.

Тарифы Free и Pro

Cloudflare сам выдаёт бесплатный сертификат для посетителей, и поставить туда свой на этих тарифах нельзя. Наш сертификат нужен на вашем сервере — чтобы связь Cloudflare → сервер тоже была защищена и проверялась (режим SSL/TLS → Full (strict)). Настройте автоматическое обновление на сервере по инструкции для него: сервер Linux, cPanel, Kubernetes.

Тарифы Business и Enterprise — свой сертификат в Cloudflare

Здесь можно загрузить свой сертификат (SSL/TLS → Edge Certificates → Upload Custom SSL Certificate), но Cloudflare его не продлевает. Скрипт ниже раз в сутки забирает свежий сертификат по ссылке и обновляет его в Cloudflare через API. Запускайте его на любом сервере Linux с curl и openssl — обычно на том, что стоит за Cloudflare.

Что понадобится

  • Ссылка на сертификат из кабинета: https://api.zrazu.com/ssl-pull/zsp_ВАШ_ТОКЕН.
  • Закрытый ключ без пароля. Ключ ECDSA — без блока EC PARAMETERS.
  • Zone ID — на странице домена в Cloudflare, справа внизу (API → Zone ID).
  • ID сертификата: SSL/TLS → Edge Certificates, строка вашего сертификата → развернуть → Certificate ID. Если сертификата ещё нет, сначала загрузите его вручную (кнопка выше) из https://api.zrazu.com/ssl-pull/zsp_ВАШ_ТОКЕН/fullchain.pem и со своим ключом.
  • API-токен: My Profile → API Tokens → Create Token → Create Custom Token → разрешение Zone → SSL and Certificates → Edit, Zone Resources — только этот домен.

Шаг 1. Ключ и скрипт на сервере

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.sh

В первый файл вставьте ключ, во второй — скрипт ниже с вашими ZONE, CERT_ID и TOKEN.

#!/bin/sh
# ZRAZU: обновление собственного сертификата в Cloudflare по личной ссылке. Запускается cron раз в сутки.
set -eu
PULL="https://api.zrazu.com/ssl-pull/zsp_ВАШ_ТОКЕН"
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: по ссылке не сертификат"; exit 1; }
if [ -f applied.pem ] && cmp -s new.pem applied.pem; then echo "ZRAZU: сертификат не изменился"; 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: сертификат выпущен на другой ключ — положите новый key.pem"; 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: сертификат в Cloudflare обновлён"
else
  echo "ZRAZU: Cloudflare отказал:"
  printf '%s\n' "$out"
  exit 1
fi

Cloudflare может выдать обновлённому сертификату новый ID — скрипт запоминает его в файле cert_id сам.

Шаг 2. Первый запуск и расписание

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.com

Проверка

  1. Первый запуск пишет «сертификат в Cloudflare обновлён», следующие — «сертификат не изменился».
  2. SSL/TLS → Edge Certificates — у вашего сертификата новая дата Expires On.
  3. Сайт: https://zrazu.com/tools/ssl/example.com/.

Если не получилось

  • Authentication error — токен без разрешения SSL and Certificates → Edit или не на этот домен.
  • custom certificate not found — неправильный CERT_ID: удалите файл /etc/ssl/zrazu/example.com/cert_id, исправьте строку в скрипте и запустите снова.
  • «сертификат выпущен на другой ключ» — сертификат перевыпускали с новым ключом: замените key.pem.

Эта страница в Markdown