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

Google Cloud — балансировщик с Certificate Manager

Задача Cloud Run по расписанию Cloud Scheduler раз в сутки обновляет сертификат в Certificate Manager на месте — балансировщик подхватывает его сам.

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

Подходит для внешнего балансировщика Google Cloud, если сертификат подключён через Certificate Manager (certificate map). Certificate Manager обновляет сертификат на месте: привязки не меняются. Для «классических» сертификатов балансировщика (compute ssl-certificates) обновления на месте нет — перенесите сертификат в Certificate Manager.

Всё делается командами в Cloud Shell (кнопка >_ вверху консоли Google Cloud) — ничего ставить на свой компьютер не нужно.

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

  • Ссылка на сертификат из кабинета: https://api.zrazu.com/ssl-pull/zsp_ВАШ_ТОКЕН.
  • Закрытый ключ без пароля — файл key.pem. В Cloud Shell загрузите его через меню ⋮ → Upload.
  • Роль Owner или Editor в проекте.

Шаг 1. Скрипт обновления

В Cloud Shell откройте редактор nano zrazu-gcp-update.sh, вставьте текст и сохраните (Ctrl+O, Enter, Ctrl+X). Если сертификат в Certificate Manager уже есть под другим названием, измените CERT; региональный сертификат — измените LOCATION.

#!/bin/sh
# ZRAZU: обновление сертификата в Google Certificate Manager по личной ссылке. Запускается раз в сутки.
set -eu
PULL="https://api.zrazu.com/ssl-pull/zsp_ВАШ_ТОКЕН"
CERT="zrazu-ssl"
LOCATION="global"
KEY=/zrazu-key/key.pem

cd /tmp
curl -fsS --retry 3 --max-time 60 -o new.pem "$PULL/fullchain.pem"
grep -q "BEGIN CERTIFICATE" new.pem || { echo "ZRAZU: not a certificate"; exit 1; }
current=$(gcloud certificate-manager certificates describe "$CERT" --location="$LOCATION" --format='value(pemCertificate)' | tr -d '\r\n ')
if [ "$current" = "$(tr -d '\r\n ' < new.pem)" ]; then echo "ZRAZU: unchanged"; exit 0; fi
gcloud certificate-manager certificates update "$CERT" --location="$LOCATION" --certificate-file=new.pem --private-key-file="$KEY" --quiet
echo "ZRAZU: updated"

Шаг 2. Первый сертификат (если его ещё нет в Certificate Manager)

curl -fsS -o fullchain.pem "https://api.zrazu.com/ssl-pull/zsp_ВАШ_ТОКЕН/fullchain.pem"
gcloud certificate-manager certificates create zrazu-ssl --certificate-file=fullchain.pem --private-key-file=key.pem

Добавьте его в certificate map балансировщика (Certificate Manager → Certificate maps), если ещё не добавили.

Шаг 3. Задача и расписание

Скопируйте весь блок в Cloud Shell. Регион задачи можно изменить на ближайший.

REGION=europe-west1
PROJECT=$(gcloud config get-value project)
SA=zrazu-ssl@$PROJECT.iam.gserviceaccount.com
gcloud services enable run.googleapis.com cloudscheduler.googleapis.com secretmanager.googleapis.com certificatemanager.googleapis.com
gcloud iam service-accounts create zrazu-ssl --display-name="ZRAZU SSL update"
gcloud secrets create zrazu-ssl-key --data-file=key.pem
gcloud secrets create zrazu-ssl-script --data-file=zrazu-gcp-update.sh
for s in zrazu-ssl-key zrazu-ssl-script; do gcloud secrets add-iam-policy-binding $s --member=serviceAccount:$SA --role=roles/secretmanager.secretAccessor; done
gcloud projects add-iam-policy-binding $PROJECT --member=serviceAccount:$SA --role=roles/certificatemanager.editor
gcloud run jobs create zrazu-ssl --region=$REGION --image=gcr.io/google.com/cloudsdktool/google-cloud-cli:stable --service-account=$SA --set-secrets=/zrazu-key/key.pem=zrazu-ssl-key:latest,/zrazu-script/update.sh=zrazu-ssl-script:latest --command=/bin/sh --args=/zrazu-script/update.sh --max-retries=1
gcloud run jobs add-iam-policy-binding zrazu-ssl --region=$REGION --member=serviceAccount:$SA --role=roles/run.invoker
gcloud scheduler jobs create http zrazu-ssl-daily --location=$REGION --schedule="17 4 * * *" --uri="https://run.googleapis.com/v2/projects/$PROJECT/locations/$REGION/jobs/zrazu-ssl:run" --http-method=POST --oauth-service-account-email=$SA
rm key.pem

Ключ теперь только в Secret Manager, а из Cloud Shell его убрали.

Проверка

  1. Запустите задачу вручную: gcloud run jobs execute zrazu-ssl --region=$REGION --wait.
  2. Журнал: Cloud Run → Jobs → zrazu-ssl → Logs — «updated» или «unchanged».
  3. Сайт: https://zrazu.com/tools/ssl/example.com/. Балансировщику Google нужно до нескольких минут.

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

  • PERMISSION_DENIED — сервисному аккаунту не выдана роль из шага 3; повторите соответствующую строку.
  • Ошибка про ключ при update — сертификат перевыпускали с новым ключом: gcloud secrets versions add zrazu-ssl-key --data-file=новый-key.pem.
  • Ошибка про имена (SAN) — Certificate Manager обновляет сертификат только с тем же списком доменов. Если домены изменились, создайте новый сертификат и замените им старый в certificate map.
  • Скрипт изменили — обновите секрет: gcloud secrets versions add zrazu-ssl-script --data-file=zrazu-gcp-update.sh.

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