适用于 Windows 的 Azure Key Vault 虚拟机扩展

Azure Key Vault 虚拟机 (VM) 扩展可自动刷新 Azure Key Vault 中存储的证书。 该扩展会监视 Key Vault 中存储的已观察到的证书列表。 检测到更改后,该扩展会检索并安装相应的证书。 本文介绍适用于 Windows 的 Key Vault VM 扩展支持的平台、配置和部署选项。

操作系统

Key Vault VM 扩展支持 Windows Server 2019 及更高版本。 自定义本地 VM 也支持 Key Vault VM 扩展。 VM 应上传并转换为专用映像,以便通过使用 Windows Server 2019 核心安装来在 Azure 中使用。

支持的证书

Key Vault VM 扩展支持以下证书内容类型:

  • PKCS #12
  • PEM

注释

Key Vault VM 扩展将所有证书下载到 Windows 证书存储或 VM 扩展设置中 certificateStoreLocation 属性指定的位置。

特点

适用于 Windows 版本 3.0 的 Key Vault VM 扩展支持:

  • 增加对下载的证书的 ACL 权限
  • 每个证书都启用证书存储配置
  • 导出私钥
  • IIS 证书重新绑定支持

先决条件

查看使用适用于 Windows 的 Key Vault VM 扩展的以下先决条件:

注释

旧的访问策略权限模型还可用于访问 VM 和虚拟机规模集。 此方法需要对机密具有“get”和“list”权限的策略。 有关详细信息,请参阅分配 Key Vault 访问策略

扩展架构

以下 JSON 显示 Key Vault VM 代理扩展的架构。 在考虑架构实现选项之前,请查看以下重要说明。

  • 扩展不需要受保护的设置。 所有设置均视为公共信息。

  • 观察到的证书 URL 应采用 https://myVaultName.vault.azure.cn/secrets/myCertName 格式。

    首选此格式是因为 /secrets 路径会返回完整证书(包括私钥),但 /certificates 路径不会。 有关证书的详细信息,请参阅 Azure Key Vault 密钥、机密和证书概述

  • 对于具有任何“用户分配的标识”的 VM,authenticationSettings 属性为“必需”属性。

    此属性指定用于对 Key Vault 进行身份验证的标识。 使用系统分配的标识定义此属性,以免出现一个 VM 扩展具有多个标识的问题。

{
   "type": "Microsoft.Compute/virtualMachines/extensions",
   "name": "KVVMExtensionForWindows",
   "apiVersion": "2022-08-01",
   "location": "<location>",
   "dependsOn": [
      "[concat('Microsoft.Compute/virtualMachines/', <vmName>)]"
   ],
   "properties": {
      "publisher": "Microsoft.Azure.KeyVault",
      "type": "KeyVaultForWindows",
      "typeHandlerVersion": "3.0",
      "autoUpgradeMinorVersion": true,
      "settings": {
         "secretsManagementSettings": {
             "pollingIntervalInS": <A string that specifies the polling interval in seconds. Example: "3600">,
             "linkOnRenewal": <Windows only. Ensures s-channel binding when the certificate renews without necessitating redeployment. Example: true>,
             "requireInitialSync": <Initial synchronization of certificates. Example: true>,
             "observedCertificates": <An array of KeyVault URIs that represent monitored certificates, including certificate store location and ACL permission to certificate private key. Example: 
             [
                {
                    "url": <A Key Vault URI to the secret portion of the certificate. Example: "https://myvault.vault.azure.cn/secrets/mycertificate1">,
                    "certificateStoreName": <The certificate store name. Example: "MY">,
                    "certificateStoreLocation": <The certificate store location, which currently works locally only. Example: "LocalMachine">,
                    "accounts": <Optional. An array of preferred accounts with read access to certificate private keys. Administrators and SYSTEM get Full Control by default. Example: ["Network Service", "Local Service"]>
                },
                {
                    "url": <Example: "https://myvault.vault.azure.cn/secrets/mycertificate2">,
                    "certificateStoreName": <Example: "MY">,
                    "certificateStoreLocation": <Example: "CurrentUser">,
                    "keyExportable": <Optional. Lets the private key be exportable. Example: "false">,
                    "accounts": <Example: ["Local Service"]>
                }
             ]>
         },
         "authenticationSettings": {
             "msiEndpoint":  <Required when the msiClientId property is used. Specifies the MSI endpoint. Example for most Azure VMs: "http://169.254.169.254/metadata/identity/oauth2/token">,
             "msiClientId":  <Required when the VM has any user assigned identities. Specifies the MSI identity. Example:  "00001111-aaaa-2222-bbbb-3333cccc4444">
         }
      }
   }
}

属性值

JSON 架构包括以下属性。

名称 值/示例 数据类型
apiVersion 2022 年 8 月 1 日 日期
publisher Microsoft.Azure.KeyVault 字符串
type KeyVaultForWindows 字符串
typeHandlerVersion "3.0" 字符串
pollingIntervalInS "3600" 字符串
linkOnRenewal(可选) 布尔
requireInitialSync(可选) 布尔
observedCertificates [{...}, {...}] 字符串数组
observedCertificates/url “https://myvault.vault.azure.cn/secrets/mycertificate" 字符串
observedCertificates/certificateStoreName 字符串
observedCertificates/certificateStoreLocation LocalMachine 或 CurrentUser(区分大小写) 字符串
observedCertificates/keyExportable(可选) 布尔
observedCertificates/accounts(可选) [“网络服务”, “本地服务”] 字符串数组
msiEndpoint “http://169.254.169.254/metadata/identity/oauth2/token" 字符串
msiClientId 00001111-aaaa-2222-bbbb-3333cccc4444 字符串

模板部署

可使用 Azure 资源管理器 (ARM) 模板部署 Azure VM 扩展。 部署需要部署后刷新证书的一个或多个虚拟机时,模板是理想选择。 可将该扩展部署到单个 VM 或虚拟机规模集实例。 架构和配置对于这两种模板类型通用。

密钥保管库扩展的 JSON 配置嵌套在 VM 或虚拟机规模集模板中。 对于 VM 资源扩展,该配置嵌套在 "resources": [] 虚拟机对象下。 对于虚拟机规模集实例扩展,该配置嵌套在 "virtualMachineProfile":"extensionProfile":{"extensions" :[] 对象下。

以下 JSON 代码片段为 Key Vault VM 扩展的 ARM 模板部署提供了示例设置。

{
   "type": "Microsoft.Compute/virtualMachines/extensions",
   "name": "KeyVaultForWindows",
   "apiVersion": "2022-08-01",
   "location": "<location>",
   "dependsOn": [
      "[concat('Microsoft.Compute/virtualMachines/', <vmName>)]"
   ],
   "properties": {
      "publisher": "Microsoft.Azure.KeyVault",
      "type": "KeyVaultForWindows",
      "typeHandlerVersion": "3.0",
      "autoUpgradeMinorVersion": true,
      "settings": {
         "secretsManagementSettings": {
             "pollingIntervalInS": <A string that specifies the polling interval in seconds. Example: "3600">,
             "linkOnRenewal": <Windows only. Ensures s-channel binding when the certificate renews without necessitating redeployment. Example: true>,
             "observedCertificates": <An array of KeyVault URIs that represent monitored certificates, including certificate store location and ACL permission to certificate private key. Example:
             [
                {
                    "url": <A Key Vault URI to the secret portion of the certificate. Example: "https://myvault.vault.azure.cn/secrets/mycertificate1">,
                    "certificateStoreName": <The certificate store name. Example: "MY">,
                    "certificateStoreLocation": <The certificate store location, which currently works locally only. Example: "LocalMachine">,
                    "accounts": <Optional. An array of preferred accounts with read access to certificate private keys. Administrators and SYSTEM get Full Control by default. Example: ["Network Service", "Local Service"]>
                },
                {
                    "url": <Example: "https://myvault.vault.azure.cn/secrets/mycertificate2">,
                    "certificateStoreName": <Example: "MY">,
                    "certificateStoreLocation": <Example: "CurrentUser">,
                    "keyExportable": <Optional. Lets the private key be exportable. Example: "false">,
                    "accounts": <Example: ["Local Service"]>
                },
                {
                    "url": <Example: "https://myvault.vault.azure.cn/secrets/mycertificate3">,
                    "certificateStoreName": <Example: "TrustedPeople">,
                    "certificateStoreLocation": <Example: "LocalMachine">
                }
             ]>           
         },
         "authenticationSettings": {
            "msiEndpoint":  <Required when the msiClientId property is used. Specifies the MSI endpoint. Example for most Azure VMs: "http://169.254.169.254/metadata/identity/oauth2/token">,
            "msiClientId":  <Required when the VM has any user assigned identities. Specifies the MSI identity. Example: "00001111-aaaa-2222-bbbb-3333cccc4444">
         }
      }
   }
}

扩展依赖项排序

可以启用 Key Vault VM 扩展以支持扩展依赖项排序。 默认情况下,Key Vault VM 扩展在轮询开始后立即报告启动成功。 但是,可以将扩展配置为仅在其下载并安装所有证书后再报告启动成功。

如果使用其他需要在启动之前安装所有证书的扩展,则可以在 Key Vault VM 扩展中启用扩展依赖项排序。 此功能允许其他扩展声明 Key Vault VM 扩展的依赖项。

可以使用此功能阻止其他扩展在安装所有相关证书之前启动。 启用该功能后,Key Vault VM 扩展将重试下载并安装证书最多 25 次,并增加回退期,在此期间它仍处于 转换 状态。 如果重试次数已耗尽,扩展将报告错误状态。 成功安装所有证书后,Key Vault VM 扩展将报告成功的启动。

若要在 Key Vault VM 扩展中启用扩展依赖项排序功能,请设置 secretsManagementSettings 属性:

"secretsManagementSettings": {
   "requireInitialSync": true,
   ...
}

有关如何在扩展之间设置依赖项的详细信息,请参阅虚拟机规模集中的序列扩展预配

重要

扩展依赖项排序功能与 ARM 模板不兼容(该模板会创建系统分配的标识并使用该标识更新 Key Vault 访问策略)。 如果尝试在此方案中使用该功能,则会发生死锁,因为 Key Vault 访问策略只有在所有扩展都启动后才会更新。 改为在部署之前使用单个用户分配的 MSI 标识,并使用该标识对你的密钥保管库进行预 ACL 操作。

Azure PowerShell 部署

可以使用 Azure PowerShell 部署 Azure Key Vault VM 扩展。 将 Key Vault VM 扩展设置保存到 JSON 文件 (settings.json)。

以下 JSON 代码片段提供了使用 PowerShell 部署 Key Vault VM 扩展的示例设置。

{   
   "secretsManagementSettings": {
   "pollingIntervalInS": "3600",
   "linkOnRenewal": true,
   "observedCertificates":
   [
      {
          "url": "https://<examplekv>.vault.azure.cn/secrets/certificate1",
          "certificateStoreName": "MY",
          "certificateStoreLocation": "LocalMachine",
          "accounts": [
             "Network Service"
          ]
      },
      {
          "url": "https://<examplekv>.vault.azure.cn/secrets/certificate2",
          "certificateStoreName": "MY",
          "certificateStoreLocation": "LocalMachine",
          "keyExportable": true,
          "accounts": [
             "Network Service",
             "Local Service"
          ]
      }
   ]},
   "authenticationSettings": {
      "msiEndpoint":  "http://169.254.169.254/metadata/identity/oauth2/token",
      "msiClientId":  "00001111-aaaa-2222-bbbb-3333cccc4444"
   }      
}

在 VM 上部署

# Build settings
$settings = (get-content -raw ".\settings.json")
$extName =  "KeyVaultForWindows"
$extPublisher = "Microsoft.Azure.KeyVault"
$extType = "KeyVaultForWindows"
 
# Start the deployment
Set-AzVmExtension -TypeHandlerVersion "3.0" -ResourceGroupName <ResourceGroupName> -Location <Location> -VMName <VMName> -Name $extName -Publisher $extPublisher -Type $extType -SettingString $settings

在虚拟机规模集实例上部署

# Build settings
$settings = ".\settings.json"
$extName = "KeyVaultForWindows"
$extPublisher = "Microsoft.Azure.KeyVault"
$extType = "KeyVaultForWindows"
  
# Add extension to Virtual Machine Scale Sets
$vmss = Get-AzVmss -ResourceGroupName <ResourceGroupName> -VMScaleSetName <VmssName>
Add-AzVmssExtension -VirtualMachineScaleSet $vmss  -Name $extName -Publisher $extPublisher -Type $extType -TypeHandlerVersion "3.0" -Setting $settings

# Start the deployment
Update-AzVmss -ResourceGroupName <ResourceGroupName> -VMScaleSetName <VmssName> -VirtualMachineScaleSet $vmss 

Azure CLI 部署

可以使用 Azure CLI 部署 Azure Key Vault VM 扩展。 将 Key Vault VM 扩展设置保存到 JSON 文件 (settings.json)。

以下 JSON 代码片段提供了使用 Azure CLI 部署 Key Vault VM 扩展的示例设置。

   {   
        "secretsManagementSettings": {
          "pollingIntervalInS": "3600",
          "linkOnRenewal": true,
          "observedCertificates": [
            {
                "url": "https://<examplekv>.vault.azure.cn/secrets/certificate1",
                "certificateStoreName": "MY",
                "certificateStoreLocation": "LocalMachine",
                "accounts": [
                    "Network Service"
                ]
            },
            {
                "url": "https://<examplekv>.vault.azure.cn/secrets/certificate2",
                "certificateStoreName": "MY",
                "certificateStoreLocation": "LocalMachine",                
                "keyExportable": true,
                "accounts": [
                    "Network Service",
                    "Local Service"
                ]
            }
        ]
        },
          "authenticationSettings": {
          "msiEndpoint":  "http://169.254.169.254/metadata/identity/oauth2/token",
          "msiClientId":  "00001111-aaaa-2222-bbbb-3333cccc4444"
        }      
     }

在 VM 上部署

# Start the deployment
az vm extension set --name "KeyVaultForWindows" `
 --publisher Microsoft.Azure.KeyVault `
 --resource-group "<resourcegroup>" `
 --vm-name "<vmName>" `
 --settings "@settings.json"

在虚拟机规模集实例上部署

# Start the deployment
az vmss extension set --name "KeyVaultForWindows" `
 --publisher Microsoft.Azure.KeyVault `
 --resource-group "<resourcegroup>" `
 --vmss-name "<vmssName>" `
 --settings "@settings.json"

排查问题

下面是有关如何排查部署问题的一些建议。

检查常见问题解答

观察到的证书数量有限制吗?

否。 没有,Key Vault VM 扩展对观察到的证书 (observedCertificates) 数量没有限制。

未指定帐户时的默认权限是什么?

默认情况下,管理员和 SYSTEM 将获得完全控制。

如何确定证书密钥是 CAPI1 还是 CNG?

扩展依赖于 PFXImportCertStore API 的默认行为。 默认情况下,如果证书具有的“提供程序名称”属性与 CAPI1 匹配,则会使用 CAPI1 API 导入证书。 否则,将使用 CNG API 导入证书。

该扩展是否支持证书自动重新绑定?

是的,Azure Key Vault VM 扩展支持证书自动重新绑定。 当 linkOnRenewal 属性设置为 true 时,Key Vault VM 扩展在证书续订时支持 S 通道绑定。

对于 IIS,可以通过在 IIS 中启用证书续订的自动重新绑定来配置自动重新绑定。 安装了具有匹配的 SAN 的证书时,Azure Key Vault VM 扩展会生成证书生命周期通知。 IIS 使用此事件自动重新绑定证书。 有关详细信息,请参阅 IIS 中的 Certifcate Rebind

查看扩展状态

在 Azure 门户中通过使用 PowerShell 或 Azure CLI 来检查扩展部署的状态。

若要查看给定 VM 的扩展部署状态,请运行以下命令。

  • Azure PowerShell:

    Get-AzVMExtension -ResourceGroupName <myResourceGroup> -VMName <myVM> -Name <myExtensionName>
    
  • Azure CLI:

    az vm get-instance-view --resource-group <myResourceGroup> --name <myVM> --query "instanceView.extensions"
    

查看日志和配置

Key Vault VM 扩展日志仅存在于本地 VM 上。 查看日志详细信息以帮助进行故障排除。

日志文件 DESCRIPTION
C:\WindowsAzure\Logs\WaAppAgent.log' 显示进行扩展更新的时间。
C:\WindowsAzure\Logs\Plugins\Microsoft.Azure.KeyVault.KeyVaultForWindows<最新版本\ 显示证书下载的状态。 下载位置始终为 Windows 计算机的 MY 存储位置 (certlm.msc)。
C:\Packages\Plugins\Microsoft.Azure.KeyVault.KeyVaultForWindows<最新版本\RuntimeSettings\ Key Vault VM 扩展服务日志显示 akvvm_service 服务的状态。
C:\Packages\Plugins\Microsoft.Azure.KeyVault.KeyVaultForWindows<最新版本\Status\ Key Vault VM 扩展服务的配置和二进制文件。

Windows 上的证书安装

适用于 Windows 的 Key Vault VM 扩展将证书安装到 Windows 证书存储中。 当从 Key Vault 下载证书时,扩展名是:

  1. 安装所有中间证书和叶证书,而不考虑存在多少个中间证书。 根证书未安装,因为扩展无权执行根安装。 服务所有者有责任确保系统信任根证书。
    • 末级证书被安装到指定的证书存储(certificateStoreName)和位置(certificateStoreLocation
    • 中间证书颁发机构的证书安装在中继证书机构存储中。
  2. 将证书放置在指定的证书存储(certificateStoreName)和位置(certificateStoreLocation
  3. 根据 accounts 配置中指定的权限对私钥应用适当的权限
  4. linkOnRenewal设置属性(如果已启用),以确保在续订证书时 IIS 等应用程序中的证书绑定自动更新

默认证书存储

如果未指定,则默认情况下,证书安装在以下位置:

  • 商店名称:MY(个人)
  • 应用商店位置:LocalMachine

证书访问控制

默认情况下,管理员和 SYSTEM 接收对已安装证书的完全控制权限。 使用证书配置中的 accounts 数组可以自定义访问权限。

"accounts": ["Network Service", "Local Service"]

这会授予对指定帐户的读取访问权限,从而允许在这些标识下运行的应用程序使用证书。

证书续订

在 Key Vault 中更新证书时,扩展组件会自动执行以下操作:

  1. 下载新的证书版本
  2. 将其安装在配置的证书存储中
  3. 如果启用此功能,则通过 linkOnRenewal 维护现有绑定。

管理证书生命周期

对于支持证书生命周期通知的应用程序,扩展会在安装具有匹配使用者可选名称(SAN)的证书时生成事件,从而允许自动重新绑定,而不会中断服务。

获取支持

如果您在阅读本文的任何时候需要更多帮助,可以联系 Azure 支持上的 Azure 专家。 或者,也可以提出 Azure 支持事件。 请转到 Azure 支持站点提交请求。 有关使用 Azure 支持的信息,请阅读 Azure 支持常见问题