SSL: автоматичне оновлення

Azure — Application Gateway, App Service, Front Door

Runbook Azure Automation раз на добу забирає свіжий сертифікат і додає нову версію в Key Vault — сервіси Azure підхоплюють її самі.

Оновлюється сам

Підходить, якщо сертифікат сайту лежить у Azure Key Vault і його бере Application Gateway v2, App Service чи Front Door (Standard/Premium). Ці сервіси самі переходять на нову версію сертифіката в Key Vault, якщо підключені «без версії» (Latest): Application Gateway — протягом 4 годин, App Service — протягом доби, Front Door — до 72 годин.

Як це працює: runbook в Azure Automation раз на добу забирає сертифікат за посиланням, порівнює з поточним у Key Vault і, якщо він новий, складає PFX із вашим ключем (ключ лежить у тому самому Key Vault як секрет) та імпортує нову версію. Ми не отримуємо доступу до вашого Azure.

Що знадобиться

  • Посилання на сертифікат із кабінету: https://api.zrazu.com/ssl-pull/zsp_ВАШ_ТОКЕН.
  • Закритий ключ без пароля — файл key.pem. Для Front Door — лише RSA: ключі ECDSA Front Door не приймає.
  • Key Vault у моделі доступу Azure role-based access control і права Owner на нього.

Крок 1. Сертифікат і ключ у Key Vault

Відкрийте Cloud Shell (кнопка >_ угорі порталу, режим Bash), завантажте key.pem (Manage files → Upload) і виконайте, підставивши назву свого Key Vault:

VAULT=НАЗВА_KEY_VAULT
curl -fsS -o fullchain.pem "https://api.zrazu.com/ssl-pull/zsp_ВАШ_ТОКЕН/fullchain.pem"
az keyvault secret set --vault-name $VAULT --name zrazu-ssl-key --file key.pem
openssl pkcs12 -export -in fullchain.pem -inkey key.pem -out zrazu.pfx -passout pass:
az keyvault certificate import --vault-name $VAULT --name zrazu-ssl --file zrazu.pfx
rm key.pem zrazu.pfx

Якщо сертифікат уже є в Key Vault під іншою назвою, останній імпорт пропустіть, а в runbook (крок 3) змініть $CertName.

Підключіть сертифікат до сервісу без версії, якщо ще не підключили: Application Gateway — Listeners → сертифікат з Key Vault; App Service — Certificates → Bring your own certificates → Import from Key Vault; Front Door — Secrets → Add certificate → версія Latest.

Крок 2. Обліковий запис Automation

  1. Automation Accounts → Create → група ресурсів і регіон ті самі, що в Key Vault → Review + Create.
  2. В обліковому записі Account Settings → Identity → System assigned: On → Save.
  3. У Key Vault Access control (IAM) → Add role assignment: роль Key Vault Certificates Officer → Managed identity → ваш обліковий запис Automation → Review + assign. Повторіть для ролі Key Vault Secrets User.

Крок 3. Runbook

  1. В обліковому записі Automation Process Automation → Runbooks → Create a runbook: назва zrazu-ssl-update, Runbook type — PowerShell, Runtime version — 7.2 → Create.
  2. Вставте текст нижче, у рядку $Vault вкажіть назву Key Vault → Save → Publish.
# ZRAZU: оновлення сертифіката в Azure Key Vault за особистим посиланням. Запускається раз на добу.
$ErrorActionPreference = "Stop"
$Pull = "https://api.zrazu.com/ssl-pull/zsp_ВАШ_ТОКЕН"
$Vault = "НАЗВА_KEY_VAULT"
$CertName = "zrazu-ssl"
$KeySecret = "zrazu-ssl-key"
$X509 = [Security.Cryptography.X509Certificates.X509Certificate2]

Connect-AzAccount -Identity | Out-Null
$full = (Invoke-WebRequest -Uri "$Pull/fullchain.pem" -UseBasicParsing).Content
if ($full -is [byte[]]) { $full = [Text.Encoding]::ASCII.GetString($full) }
$pems = @([regex]::Matches($full, "-----BEGIN CERTIFICATE-----[\s\S]+?-----END CERTIFICATE-----") | ForEach-Object { $_.Value })
if ($pems.Count -eq 0) { throw "ZRAZU: not a certificate" }
$leaf = $X509::CreateFromPem($pems[0])
$current = Get-AzKeyVaultCertificate -VaultName $Vault -Name $CertName
if ($current -and $current.Thumbprint -eq $leaf.Thumbprint) { "ZRAZU: unchanged"; return }
if ($leaf.NotAfter -le (Get-Date)) { throw "ZRAZU: certificate expired" }
$key = Get-AzKeyVaultSecret -VaultName $Vault -Name $KeySecret -AsPlainText
$withKey = $X509::CreateFromPem($pems[0], $key)
$all = New-Object Security.Cryptography.X509Certificates.X509Certificate2Collection
[void]$all.Add($withKey)
foreach ($pem in ($pems | Select-Object -Skip 1)) { [void]$all.Add($X509::CreateFromPem($pem)) }
$pfx = $all.Export([Security.Cryptography.X509Certificates.X509ContentType]::Pkcs12)
Import-AzKeyVaultCertificate -VaultName $Vault -Name $CertName -CertificateString ([Convert]::ToBase64String($pfx)) | Out-Null
"ZRAZU: updated, valid until $($leaf.NotAfter.ToString('yyyy-MM-dd'))"

Якщо ключ не підходить до сертифіката, CreateFromPem зупиниться з помилкою і нічого не буде імпортовано.

Крок 4. Розклад

У runbook Link to schedule → Link a schedule to your runbook → Add a schedule: назва zrazu-daily, Recurrence — Recurring, кожен 1 день, час — будь-який нічний → Create → OK.

Перевірка

  1. У runbook Start → OK. Відкрийте задачу (Jobs), вкладка Output: «updated» або «unchanged».
  2. У Key Vault Certificates → zrazu-ssl — нова версія з новою датою.
  3. Сайт: https://zrazu.com/tools/ssl/example.com/ — з урахуванням того, як швидко ваш сервіс підхоплює нову версію (див. вгорі).

Якщо не вийшло

  • Forbidden / does not have secrets get permission — не видано одну з двох ролей кроку 2 або Key Vault у моделі access policy: тоді в Access policies дайте identity права Certificates: Get, Import і Secrets: Get.
  • «The provided key does not match» — сертифікат перевипускали з новим ключем: az keyvault secret set --vault-name $VAULT --name zrazu-ssl-key --file новий-key.pem.
  • 404 — посилання вимкнене чи замінене: створіть нове в картці сертифіката й замініть $Pull.
  • Front Door не бере сертифікат — ключ ECDSA або сертифікат підключено з конкретною версією, а не Latest.

Ця сторінка в Markdown