从脚本更新 Azure CDN 自定义域证书

Jar*_*kia 4 azure azure-cdn azure-powershell azure-cli

如何在不停机的情况下触发 Azure CDN 从 Key Store 读取最新版本的自定义证书?

我的 CDN 设置工作正常,但鉴于 Let's Encrypt,证书寿命很短,需要自动化更新。这样做az keyvault certificate import是对Azure的CLI小事足以证书更新为重点库,但接下来呢?如何告诉 Azure CDN 开始使用新版本的证书?

失败的尝试

  • 等了几个小时。什么都没有发生。
  • az cdn custom-domain enable-https在已启用 HTTPS 的域上运行。结果:内部配置错误和几个小时的停机时间,首先禁用自定义域然后启用它。不过,证书已更新。

从 Azure 门户

自定义域证书版本的 Azure 门户工具提示显示“选择要使用的证书版本。默认情况下,我们将使用最新版本。 ” 创建终结点时确实如此,但如何开始使用最新版本?已经从下拉列表中选择了最新版本,但我确实选择了以前的版本并选择了最新版本。这样做启用了“保存”。

保存表单导致证书的无停机更新。不错,但考虑到自动化和脚本编写,并不是真正可行的方法。

可能有用的东西,但我还没有测试过

  • 应用 CDN 设置的 ARM 模板
  • Powershell Az.Cdn具有Start-AzCdnEndpoint/ Stop-AzCdnEndpointcmdlet。也许有帮助,但 100% 保证会产生停机时间。

我可以在下一个更新周期尝试什么吗?

Arn*_*ion 6

自 2021 年 4 月 5 日起,可以告知 Azure CDN 使用特定 KeyVault 证书的“最新”版本。我还没有发现任何有关此更改的消息,但它已通过此提交添加到文档中

为了在 Key Vault 中提供更新版本的证书时,证书自动轮换到最新版本,请将证书/机密版本设置为“最新”。如果选择了特定版本,则必须手动重新选择新版本以进行证书轮换。部署新版本的证书/机密最多需要 24 小时。

在门户中,这可以通过在“证书/秘密版本”下拉列表中选择“最新”选项来完成。使用 Azure CLI,可以通过以下方式完成:

az cdn custom-domain enable-https \
    --resource-group "$cdnResourceGroupName" \
    --profile-name "$cdnProfileName" \
    --endpoint-name "$cdnEndpointName" \
    --name "$cdnCustomDomainName" \
    --user-cert-subscription-id "$subscriptionId" \
    --user-cert-group-name "$keyVaultResourceGroupName" \
    --user-cert-vault-name "$keyVaultName" \
    --user-cert-secret-name "$secretName" \
    --user-cert-protocol-type 'sni'
Run Code Online (Sandbox Code Playgroud)

注意,这个命令并没有设置--user-cert-secret-version参数,这是你如何选择“最新”的功能。

对于想要手动执行此操作的任何人,手动执行此操作的旧答案如下。


az cdn custom-domain enable-https在已启用 HTTPS 的域上运行。结果:内部配置错误和几个小时的停机时间,首先禁用自定义域然后启用它。

自 2021 年 4 月 5 日起,这可以通过 Azure CLI 完成:

az cdn custom-domain enable-https \
    --resource-group "$cdnResourceGroupName" \
    --profile-name "$cdnProfileName" \
    --endpoint-name "$cdnEndpointName" \
    --name "$cdnCustomDomainName" \
    --user-cert-subscription-id "$subscriptionId" \
    --user-cert-group-name "$keyVaultResourceGroupName" \
    --user-cert-vault-name "$keyVaultName" \
    --user-cert-secret-name "$secretName" \
    --user-cert-secret-version "$secretVersion" \
    --user-cert-protocol-type 'sni'
Run Code Online (Sandbox Code Playgroud)

(当这个答案最初是在 2019 年 5 月编写时,Azure CLI 记录了一个--custom-domain-https-parameters参数,暗示它可以用于此目的。如果未提供该参数,CLI 将运行 CDN 管理的证书工作流(由 DigiCert 颁发的证书) 。但是,从未正确记录如何实际使用该参数。截至 2021 年 3 月,该参数再次从 CLI 中删除。最后,截至 2021 年 4 月,--user-cert-*已添加这些参数。)

等效功能是在2019年三月加入。净SDK, 。因此Nuget 包应该允许您使用用户管理的证书。

截至 2021 年 4 月,Azure PowerShell 的Enable-AzCdnCustomDomainHttpscommandlet仍然不支持用户管理的证书,仅支持 CDN 管理的证书。

或者您可以直接使用 REST API,如此处所述。做一个POST请求,https://management.azure.com/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.Cdn/profiles/$cdnProfileName/endpoints/$cdnEndpointName/customDomains/$cdnCustomDomainName/enableCustomHttps?api-version=2018-04-02application/json身体,看起来像

{
    "certificateSource": "AzureKeyVault",
    "certificateSourceParameters": {
        "@odata.type": "#Microsoft.Azure.Cdn.Models.KeyVaultCertificateSourceParameters",
        "deleteRule": "NoAction",
        "resourceGroupName": "$resourceGroupName",
        "secretName": "$secretName",
        "secretVersion": "$secretVersion",
        "subscriptionId": "$subscriptionId",
        "updateRule": "NoAction",
        "vaultName": "$keyVaultName"
    },
    "protocolType": "ServerNameIndication"
}
Run Code Online (Sandbox Code Playgroud)

$resourceGroupName$keyVaultName识别 KeyVault。$secretName$secretVersion识别证书。(如果门户没有在您的 KeyVault 中显示任何机密,请不要感到困惑;带有私钥的 KeyVault 证书隐式是具有相同名称和版本的 KeyVault 机密。)

这个 API 端点遵循标准的 REST 语义,因为它返回HTTP 202 Accepted一个长时间运行的异步操作。它将Location在响应中设置标头,您应该GET重复该 URL,直到它解析为成功或失败状态代码。

请注意,门户还使用 REST API,因此您始终可以通过执行门户 UI 中的步骤并在浏览器的开发人员工具中检查网络请求来得出这一点。不过,您需要获得自己的 oauth2 令牌(通过创建 SP)。


旁白:为了节省人们在尝试为我自己的域执行此操作时发现这一点所花费的时间,请不要被Azure Rest API 规范存储库中的文档或示例所迷惑它们暗示 API 版本2017-10-12支持customHttpsParameters,但实际上只有2018-04-02更新版本才支持。如果您使用,2017-10-12则该参数将被静默忽略,它将尝试使用 Digicert 自动证书工作流程。